add tags to discovery

This commit is contained in:
garnier-quentin 2022-07-28 15:56:46 +02:00
parent bb6fca03e9
commit 31f4bc3d2b
12 changed files with 1443 additions and 60 deletions

View File

@ -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;

View File

@ -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} = \&centreon::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<http>.
=cut

View File

@ -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;

View File

@ -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<http>.
=cut

View File

@ -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;

View File

@ -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<http>.
=cut

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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)) {

View File

@ -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";

View File

@ -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");