mirror of
https://github.com/centreon/centreon-plugins.git
synced 2025-04-07 20:35:27 +02:00
enh(vmware-connector): add the ability to load configuration from a json file (#5192)
Co-authored-by: sdepassio <114986849+sdepassio@users.noreply.github.com> Co-authored-by: Evan-Adam <152897682+Evan-Adam@users.noreply.github.com> REFS: CTOR-786
This commit is contained in:
parent
b9d19ede94
commit
df03cc5037
@ -39,6 +39,11 @@ contents:
|
||||
dst: "/usr/share/perl5/centreon/script/centreon_vmware.pm"
|
||||
packager: deb
|
||||
|
||||
- src: "../src/centreon/script/centreon_vmware_convert_config_file"
|
||||
dst: "/usr/bin/centreon_vmware_convert_config_file"
|
||||
file_info:
|
||||
mode: 0755
|
||||
|
||||
- src: "../src/centreon_vmware.pl"
|
||||
dst: "/usr/bin/centreon_vmware.pl"
|
||||
file_info:
|
||||
@ -76,23 +81,25 @@ scripts:
|
||||
overrides:
|
||||
rpm:
|
||||
depends:
|
||||
- perl-VMware-vSphere >= 5.1
|
||||
- perl(ZMQ::LibZMQ4)
|
||||
- perl(ZMQ::Constants)
|
||||
- perl(LWP::Protocol::https)
|
||||
- perl(Crypt::OpenSSL::AES)
|
||||
- perl(IO::Socket::INET6)
|
||||
- perl(JSON::XS)
|
||||
- perl(LWP::Protocol::https)
|
||||
- perl(ZMQ::Constants)
|
||||
- perl(ZMQ::LibZMQ4)
|
||||
- perl-Net-Curl
|
||||
- perl-VMware-vSphere >= 5.1
|
||||
deb:
|
||||
depends:
|
||||
- perl-vmware-vsphere
|
||||
- libzmq-libzmq4-perl
|
||||
- libzmq-constants-perl
|
||||
- liblwp-protocol-https-perl
|
||||
- libcrypt-openssl-aes-perl
|
||||
- libio-socket-inet6-perl
|
||||
- libjson-xs-perl
|
||||
- liblwp-protocol-https-perl
|
||||
- libnet-curl-perl
|
||||
- libtext-template-perl
|
||||
- libzmq-constants-perl
|
||||
- libzmq-libzmq4-perl
|
||||
- perl-vmware-vsphere
|
||||
|
||||
rpm:
|
||||
signature:
|
||||
|
28
connectors/vmware/packaging/config/centreon_vmware-conf.json
Normal file
28
connectors/vmware/packaging/config/centreon_vmware-conf.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"bind": "*",
|
||||
"case_insensitive": 0,
|
||||
"credstore_file": "/root/.vmware/credstore/vicredentials.xml",
|
||||
"credstore_use": 0,
|
||||
"dynamic_timeout_kill": 86400,
|
||||
"ipc_file": "/tmp/centreon_vmware/routing.ipc",
|
||||
"port": 5700,
|
||||
"refresh_keeper_session": 15,
|
||||
"timeout": 60,
|
||||
"timeout_kill": 30,
|
||||
"timeout_vsphere": 60,
|
||||
"vsan_sdk_path": "/usr/local/share/perl5/VMware",
|
||||
"vsphere_server": [
|
||||
{
|
||||
"name": "additional",
|
||||
"password": "XXXXXX",
|
||||
"url": "https://vcenter2/sdk",
|
||||
"username": "XXXXXX"
|
||||
},
|
||||
{
|
||||
"name": "default",
|
||||
"password": "XXXXXX",
|
||||
"url": "https://vcenter/sdk",
|
||||
"username": "XXXXXX"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,10 +1,28 @@
|
||||
|
||||
%centreon_vmware_config = (
|
||||
vsphere_server => {
|
||||
'default' => {'url' => 'https://vcenter/sdk',
|
||||
'username' => 'XXXXXX',
|
||||
'password' => 'XXXXXX'}
|
||||
}
|
||||
vsphere_server => {
|
||||
'default' => {
|
||||
'url' => 'https://vcenter/sdk',
|
||||
'username' => 'XXXXXX',
|
||||
'password' => 'XXXXXX'
|
||||
},
|
||||
'additional' => {
|
||||
'url' => 'https://vcenter2/sdk',
|
||||
'username' => 'XXXXXX',
|
||||
'password' => 'XXXXXX'
|
||||
}
|
||||
},
|
||||
credstore_use => 0,
|
||||
credstore_file => '/root/.vmware/credstore/vicredentials.xml',
|
||||
timeout_vsphere => 60,
|
||||
timeout => 60,
|
||||
timeout_kill => 30,
|
||||
dynamic_timeout_kill => 86400,
|
||||
refresh_keeper_session => 15,
|
||||
bind => '*',
|
||||
port => 5700,
|
||||
ipc_file => '/tmp/centreon_vmware/routing.ipc',
|
||||
case_insensitive => 0,
|
||||
vsan_sdk_path => '/usr/local/share/perl5/VMware'
|
||||
);
|
||||
|
||||
1;
|
||||
|
@ -1,4 +1,4 @@
|
||||
## Copyright 2016 Centreon
|
||||
# Copyright 2024 Centreon
|
||||
##
|
||||
## Licensed under the Apache License, Version 2.0 (the "License");
|
||||
## you may not use this file except in compliance with the License.
|
||||
|
@ -1,4 +1,4 @@
|
||||
## Copyright 2016 Centreon
|
||||
# Copyright 2024 Centreon
|
||||
##
|
||||
## Licensed under the Apache License, Version 2.0 (the "License");
|
||||
## you may not use this file except in compliance with the License.
|
||||
|
@ -1,15 +1,15 @@
|
||||
#!/usr/bin/perl
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# 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,
|
||||
@ -32,6 +32,7 @@ use JSON::XS;
|
||||
use centreon::vmware::script;
|
||||
use centreon::vmware::common;
|
||||
use centreon::vmware::connector;
|
||||
use centreon::script::centreonvault;
|
||||
|
||||
my ($centreon_vmware, $frontend);
|
||||
|
||||
@ -52,7 +53,6 @@ BEGIN {
|
||||
}
|
||||
|
||||
use base qw(centreon::vmware::script);
|
||||
use vars qw(%centreon_vmware_config);
|
||||
|
||||
my $VERSION = '3.2.6';
|
||||
my %handlers = (TERM => {}, HUP => {}, CHLD => {});
|
||||
@ -108,43 +108,90 @@ sub new {
|
||||
|
||||
bless $self, $class;
|
||||
$self->add_options(
|
||||
'config-extra=s' => \$self->{opt_extra}
|
||||
'config-extra=s' => \$self->{opt_extra},
|
||||
'check-config' => \$self->{opt_check_config},
|
||||
'vault-config=s' => \$self->{opt_vault_config}
|
||||
);
|
||||
|
||||
%{$self->{centreon_vmware_default_config}} =
|
||||
(
|
||||
credstore_use => 0,
|
||||
credstore_file => '/root/.vmware/credstore/vicredentials.xml',
|
||||
timeout_vsphere => 60,
|
||||
timeout => 60,
|
||||
timeout_kill => 30,
|
||||
dynamic_timeout_kill => 86400,
|
||||
refresh_keeper_session => 15,
|
||||
bind => '*',
|
||||
port => 5700,
|
||||
ipc_file => '/tmp/centreon_vmware/routing.ipc',
|
||||
case_insensitive => 0,
|
||||
vsphere_server => {
|
||||
#'default' => {'url' => 'https://XXXXXX/sdk',
|
||||
# 'username' => 'XXXXX',
|
||||
# 'password' => 'XXXXX'},
|
||||
#'testvc' => {'url' => 'https://XXXXXX/sdk',
|
||||
# 'username' => 'XXXXX',
|
||||
# 'password' => 'XXXXXX'}
|
||||
},
|
||||
vsan_sdk_path => '/usr/local/share/perl5/VMware'
|
||||
);
|
||||
%{$self->{centreon_vmware_default_config}} = (
|
||||
credstore_use => 0,
|
||||
credstore_file => '/root/.vmware/credstore/vicredentials.xml',
|
||||
timeout_vsphere => 60,
|
||||
timeout => 60,
|
||||
timeout_kill => 30,
|
||||
dynamic_timeout_kill => 86400,
|
||||
refresh_keeper_session => 15,
|
||||
bind => '*',
|
||||
port => 5700,
|
||||
ipc_file => '/tmp/centreon_vmware/routing.ipc',
|
||||
case_insensitive => 0,
|
||||
vsphere_server => {
|
||||
#'default' => {'url' => 'https://XXXXXX/sdk',
|
||||
# 'username' => 'XXXXX',
|
||||
# 'password' => 'XXXXX'},
|
||||
#'testvc' => {'url' => 'https://XXXXXX/sdk',
|
||||
# 'username' => 'XXXXX',
|
||||
# 'password' => 'XXXXXX'}
|
||||
},
|
||||
vsan_sdk_path => '/usr/local/share/perl5/VMware'
|
||||
);
|
||||
|
||||
$self->{return_child} = {};
|
||||
$self->{stop} = 0;
|
||||
$self->{childs_vpshere_pid} = {};
|
||||
$self->{counter_stats} = {};
|
||||
$self->{whoaim} = undef; # to know which vsphere to connect
|
||||
$self->{modules_registry} = {};
|
||||
$self->{return_child} = {};
|
||||
$self->{stop} = 0;
|
||||
$self->{children_vpshere_pid} = {};
|
||||
$self->{counter_stats} = {};
|
||||
$self->{whoaim} = undef; # to know which vsphere to connect
|
||||
$self->{modules_registry} = {};
|
||||
$self->{vault} = {};
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
# read_configuration: reads the configuration file given as parameter
|
||||
sub read_configuration {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{logger}->writeLogDebug("Reading configuration from " . $self->{opt_extra});
|
||||
my $centreon_vmware_config_from_json;
|
||||
|
||||
if ($self->{opt_extra} =~ /.*\.pm$/i) {
|
||||
our %centreon_vmware_config;
|
||||
# loads the .pm configuration (compile time)
|
||||
require($self->{opt_extra}) or $self->{logger}->writeLogFatal("There has been an error while requiring file " . $self->{opt_extra});
|
||||
# Concatenation of the default parameters with the ones from the config file
|
||||
$self->{centreon_vmware_config} = {%{$self->{centreon_vmware_default_config}}, %centreon_vmware_config};
|
||||
} elsif ($self->{opt_extra} =~ /.*\.json$/i) {
|
||||
$centreon_vmware_config_from_json = centreon::vmware::common::parse_json_file( 'json_file' => $self->{opt_extra} );
|
||||
if (defined($centreon_vmware_config_from_json->{error_message})) {
|
||||
$self->{logger}->writeLogFatal("Error while parsing " . $self->{opt_extra} . ": " . $centreon_vmware_config_from_json->{error_message});
|
||||
}
|
||||
# The structure of the JSON is different from the .pm file. The code was designed to work with the latter, so
|
||||
# the structure of $self->{centreon_vmware_config} must be adapted after parsing to avoid a massive refactoring of
|
||||
# the whole program. The wanted structure is a key-object dictionary instead of an array of objects.
|
||||
my %vsphere_server_dict = map { lc($_->{name}) => $_ } @{$centreon_vmware_config_from_json->{vsphere_server}};
|
||||
# Replace the "raw" structure from the JSON file.
|
||||
$centreon_vmware_config_from_json->{vsphere_server} = \%vsphere_server_dict;
|
||||
# Concatenation of the default parameters with the ones from the config file
|
||||
$self->{centreon_vmware_config} = {%{$self->{centreon_vmware_default_config}}, %$centreon_vmware_config_from_json};
|
||||
} else {
|
||||
$self->{logger}->writeLogFatal($self->{opt_extra} . " does not seem to be in a supported format (supported: .pm or .json).");
|
||||
}
|
||||
}
|
||||
|
||||
# report_config_check: writes a report of what has been loaded from the configuration file
|
||||
sub report_config_check {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $nb_server_entries = scalar(keys %{$self->{centreon_vmware_config}->{vsphere_server}});
|
||||
my $entry_spelling = ($nb_server_entries > 1) ? 'entries' : 'entry';
|
||||
|
||||
my $report = "Configuration file " . $self->{opt_extra} . " has been read correctly and has "
|
||||
. $nb_server_entries . " " . $entry_spelling . ".";
|
||||
|
||||
$self->{logger}->writeLogInfo($report);
|
||||
return $report;
|
||||
}
|
||||
|
||||
sub init {
|
||||
my $self = shift;
|
||||
$self->SUPER::init();
|
||||
@ -152,22 +199,31 @@ sub init {
|
||||
# redefine to avoid out when we try modules
|
||||
$SIG{__DIE__} = undef;
|
||||
|
||||
if (!defined($self->{opt_extra})) {
|
||||
if ( ! defined($self->{opt_extra}) ) {
|
||||
$self->{opt_extra} = "/etc/centreon/centreon_vmware.pm";
|
||||
}
|
||||
if (-f $self->{opt_extra}) {
|
||||
require $self->{opt_extra};
|
||||
} else {
|
||||
$self->{logger}->writeLogInfo("Can't find extra config file $self->{opt_extra}");
|
||||
|
||||
if ( ! -f $self->{opt_extra} ) {
|
||||
$self->{logger}->writeLogFatal(
|
||||
"Can't find config file '$self->{opt_extra}'. If a migration from "
|
||||
. "/etc/centreon/centreon_vmware.pm to /etc/centreon/centreon_vmware.json is required, you may "
|
||||
. "centreon_vmware_convert_config_file /etc/centreon/centreon_vmware.pm > /etc/centreon/centreon_vmware.json"
|
||||
);
|
||||
}
|
||||
|
||||
$self->{centreon_vmware_config} = {%{$self->{centreon_vmware_default_config}}, %centreon_vmware_config};
|
||||
$self->read_configuration(filename => $self->{opt_extra});
|
||||
|
||||
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};
|
||||
if (! defined($self->{opt_vault_config}) || $self->{opt_vault_config} eq '') {
|
||||
$self->{opt_vault_config} = '/var/lib/centreon/vault/vault.json';
|
||||
$self->{logger}->writeLogInfo("No vault config file given. Applying default: " . $self->{opt_vault_config});
|
||||
}
|
||||
|
||||
$self->{logger}->writeLogDebug("Vault config file " . $self->{opt_vault_config} . " exists. Creating the vault object.");
|
||||
$self->{vault} = centreon::script::centreonvault->new(
|
||||
'logger' => $self->{logger},
|
||||
'config_file' => $self->{opt_vault_config}
|
||||
);
|
||||
|
||||
##### Load modules
|
||||
$self->load_module(@load_modules);
|
||||
|
||||
@ -194,23 +250,42 @@ sub init {
|
||||
$self->{logger}->writeLogError("Credstore init failed: $@");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
$self->{logger}->writeLogDebug("Not using credstore.");
|
||||
$self->{centreon_vmware_config}->{credstore_use} = 0;
|
||||
}
|
||||
|
||||
###
|
||||
# Get password
|
||||
###
|
||||
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->{centreon_vmware_config}->{vsphere_server}->{$_}->{username} . "' : $@");
|
||||
exit(1);
|
||||
# Get passwords
|
||||
foreach my $server (keys %{$self->{centreon_vmware_config}->{vsphere_server}}) {
|
||||
|
||||
# If appropriate, get the password from the vmware credentials store
|
||||
if ($self->{centreon_vmware_config}->{credstore_use} == 1) {
|
||||
$self->{centreon_vmware_config}->{vsphere_server}->{$server}->{password} = VMware::VICredStore::get_password(
|
||||
server => $server,
|
||||
username => $self->{centreon_vmware_config}->{vsphere_server}->{$server}->{username}
|
||||
);
|
||||
if (!defined($self->{centreon_vmware_config}->{vsphere_server}->{$server}->{password})) {
|
||||
$self->{logger}->writeLogFatal("Can't get password for couple host='" . $server . "', username='" . $self->{centreon_vmware_config}->{vsphere_server}->{$server}->{username} . "' : $@");
|
||||
}
|
||||
} else {
|
||||
# we let the vault object handle the secrets
|
||||
for my $key ('username', 'password') {
|
||||
$self->{logger}->writeLogDebug("Retrieving secret: $key");
|
||||
$self->{centreon_vmware_config}->{vsphere_server}->{$server}->{$key}
|
||||
= $self->{vault}->get_secret($self->{centreon_vmware_config}->{vsphere_server}->{$server}->{$key});
|
||||
}
|
||||
$self->{centreon_vmware_config}->{vsphere_server}->{$_}->{password} = $lpassword;
|
||||
}
|
||||
}
|
||||
|
||||
my $config_check_report = $self->report_config_check();
|
||||
if (defined($self->{opt_check_config})) {
|
||||
print($config_check_report . " Exiting now.");
|
||||
exit(0);
|
||||
}
|
||||
$self->set_signal_handlers;
|
||||
}
|
||||
|
||||
|
||||
sub set_signal_handlers {
|
||||
my $self = shift;
|
||||
|
||||
@ -245,15 +320,15 @@ sub handle_TERM {
|
||||
$self->{logger}->writeLogInfo("$$ Receiving order to stop...");
|
||||
$self->{stop} = 1;
|
||||
|
||||
foreach (keys %{$self->{childs_vpshere_pid}}) {
|
||||
foreach (keys %{$self->{children_vpshere_pid}}) {
|
||||
kill('TERM', $_);
|
||||
$self->{logger}->writeLogInfo("Send -TERM signal to '" . $self->{childs_vpshere_pid}->{$_} . "' process..");
|
||||
$self->{logger}->writeLogInfo("Send -TERM signal to '" . $self->{children_vpshere_pid}->{$_} . "' process..");
|
||||
}
|
||||
}
|
||||
|
||||
sub handle_HUP {
|
||||
my $self = shift;
|
||||
$self->{logger}->writeLogInfo("$$ Receiving order to reload...");
|
||||
$self->{logger}->writeLogInfo("$$ Receiving order to reload but it has not been implemented yet...");
|
||||
# TODO
|
||||
}
|
||||
|
||||
@ -276,7 +351,7 @@ sub load_module {
|
||||
require $file;
|
||||
my $obj = $_->new(logger => $self->{logger}, case_insensitive => $self->{centreon_vmware_config}->{case_insensitive});
|
||||
$self->{modules_registry}->{ $obj->getCommandName() } = $obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub verify_child_vsphere {
|
||||
@ -286,24 +361,24 @@ sub verify_child_vsphere {
|
||||
foreach (keys %{$self->{return_child}}) {
|
||||
delete $self->{return_child}->{$_};
|
||||
|
||||
if (defined($self->{childs_vpshere_pid}->{$_})) {
|
||||
if (defined($self->{children_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!!!");
|
||||
my $name = $self->{children_vpshere_pid}->{$_};
|
||||
$self->{logger}->writeLogError("Sub-process for '" . $self->{children_vpshere_pid}->{$_} . "'???!! we relaunch it!!!");
|
||||
|
||||
if ($self->{centreon_vmware_config}->{vsphere_server}->{$self->{childs_vpshere_pid}->{$_}}->{dynamic} == 0) {
|
||||
if ($self->{centreon_vmware_config}->{vsphere_server}->{$self->{children_vpshere_pid}->{$_}}->{dynamic} == 0) {
|
||||
# Can have the same pid (so we delete before)
|
||||
delete $self->{childs_vpshere_pid}->{$_};
|
||||
delete $self->{children_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}->{$_};
|
||||
$self->{logger}->writeLogError("Sub-process for '" . $self->{children_vpshere_pid}->{$_} . "' is dead. But we don't relaunch it (dynamic sub-process)");
|
||||
delete $self->{centreon_vmware_config}->{vsphere_server}->{$self->{children_vpshere_pid}->{$_}};
|
||||
delete $self->{children_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}->{$_};
|
||||
$self->{logger}->writeLogInfo("Sub-process for '" . $self->{children_vpshere_pid}->{$_} . "' dead ???!!");
|
||||
$self->{centreon_vmware_config}->{vsphere_server}->{$self->{children_vpshere_pid}->{$_}}->{running} = 0;
|
||||
delete $self->{children_vpshere_pid}->{$_};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -317,7 +392,7 @@ sub verify_child_vsphere {
|
||||
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->{centreon_vmware_config}->{vsphere_server}->{$_}->{pid});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
@ -329,11 +404,11 @@ 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();
|
||||
$self->check_children();
|
||||
|
||||
my $time = time();
|
||||
# We wait 10 seconds
|
||||
while ($self->{centreon_vmware_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);
|
||||
}
|
||||
@ -368,7 +443,7 @@ sub request_dynamic {
|
||||
};
|
||||
$self->{logger}->writeLogError(
|
||||
sprintf(
|
||||
"Dynamic creation: identity = %s [address: %s] [username: %s] [password: %s]",
|
||||
"Dynamic creation: identity = %s [address: %s] [username: %s] [password: %s]",
|
||||
$container, $options{result}->{vsphere_address}, $options{result}->{vsphere_username}, $options{result}->{vsphere_password}
|
||||
)
|
||||
);
|
||||
@ -436,7 +511,7 @@ sub request {
|
||||
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;
|
||||
@ -465,7 +540,7 @@ sub repserver {
|
||||
my $identity = 'client-' . pack('H*', $1);
|
||||
|
||||
centreon::vmware::common::response(
|
||||
token => 'RESPSERVER', endpoint => $frontend,
|
||||
token => 'RESPSERVER', endpoint => $frontend,
|
||||
identity => $identity, force_response => $options{data}
|
||||
);
|
||||
}
|
||||
@ -498,17 +573,18 @@ sub router_event {
|
||||
}
|
||||
|
||||
centreon::vmware::common::free_response();
|
||||
my $more = zmq_getsockopt($frontend, ZMQ_RCVMORE);
|
||||
my $more = zmq_getsockopt($frontend, ZMQ_RCVMORE);
|
||||
last unless $more;
|
||||
}
|
||||
}
|
||||
|
||||
sub check_childs {
|
||||
sub check_children {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $count = $self->verify_child_vsphere();
|
||||
$self->{logger}->writeLogDebug("$count child(ren) found. Stop ? : " . $self->{stop});
|
||||
if ($self->{stop} == 1) {
|
||||
# No childs
|
||||
# No children
|
||||
if ($count == 0) {
|
||||
$self->{logger}->writeLogInfo("Quit main process");
|
||||
zmq_close($frontend);
|
||||
@ -516,7 +592,7 @@ sub check_childs {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub create_vsphere_child {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
@ -527,7 +603,7 @@ sub create_vsphere_child {
|
||||
|
||||
my $child_vpshere_pid = fork();
|
||||
if (!defined($child_vpshere_pid)) {
|
||||
$self->{logger}->writeLogError("Cannot fork for '" . $options{vsphere_name} . "': $!");
|
||||
$self->{logger}->writeLogError("Cannot fork for '" . $options{vsphere_name} . "': $!");
|
||||
return -1;
|
||||
}
|
||||
if ($child_vpshere_pid == 0) {
|
||||
@ -541,10 +617,11 @@ sub create_vsphere_child {
|
||||
$connector->run();
|
||||
exit(0);
|
||||
}
|
||||
$self->{childs_vpshere_pid}->{$child_vpshere_pid} = $self->{whoaim};
|
||||
$self->{children_vpshere_pid}->{$child_vpshere_pid} = $self->{whoaim};
|
||||
|
||||
$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;
|
||||
$self->{centreon_vmware_config}->{vsphere_server}->{$self->{whoaim}}->{pid} = $child_vpshere_pid;
|
||||
}
|
||||
|
||||
sub bind_ipc {
|
||||
@ -577,21 +654,21 @@ sub run {
|
||||
my $context = zmq_init();
|
||||
$frontend = zmq_socket($context, ZMQ_ROUTER);
|
||||
if (!defined($frontend)) {
|
||||
$centreon_vmware->{logger}->writeLogError("Can't setup server: $!");
|
||||
exit(1);
|
||||
$centreon_vmware->{logger}->writeLogFatal("Can't setup server: $!");
|
||||
}
|
||||
|
||||
zmq_setsockopt($frontend, ZMQ_LINGER, 0); # we discard
|
||||
zmq_setsockopt($frontend, ZMQ_LINGER, 0); # we discard
|
||||
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}}) {
|
||||
$centreon_vmware->{counter_stats}->{$_} = 0;
|
||||
$centreon_vmware->{logger}->writeLogDebug("Creating vSphere child for $_");
|
||||
$centreon_vmware->create_vsphere_child(vsphere_name => $_, dynamic => 0);
|
||||
}
|
||||
|
||||
$centreon_vmware->{logger}->writeLogInfo("[Server accepting clients]");
|
||||
|
||||
|
||||
# Initialize poll set
|
||||
$centreon_vmware->{poll} = [
|
||||
{
|
||||
@ -600,10 +677,10 @@ sub run {
|
||||
callback => \&router_event
|
||||
}
|
||||
];
|
||||
|
||||
$centreon_vmware->{logger}->writeLogDebug("Global loop starting...");
|
||||
# Switch messages between sockets
|
||||
while (1) {
|
||||
$centreon_vmware->check_childs();
|
||||
$centreon_vmware->check_children();
|
||||
zmq_poll($centreon_vmware->{poll}, 5000);
|
||||
}
|
||||
}
|
||||
@ -611,3 +688,4 @@ sub run {
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/perl
|
||||
# Copyright 2024 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 strict;
|
||||
use warnings FATAL => 'all';
|
||||
use JSON::XS;
|
||||
use Data::Dumper;
|
||||
|
||||
die "Usage: centreon_vmware_convert_config_file /etc/centreon/centreon_vmware.pm > /etc/centreon/centreon_vmware.json" if (scalar(@ARGV) < 1);
|
||||
my $config_file = $ARGV[0];
|
||||
|
||||
die "Config file $config_file does not exist.\n" if (! -f $config_file);
|
||||
|
||||
our %centreon_vmware_config;
|
||||
require($config_file) or die "Error while loading file $config_file";
|
||||
|
||||
my $new_config_structure = {
|
||||
vsphere_server => []
|
||||
};
|
||||
|
||||
|
||||
for my $config_entry_key (keys %centreon_vmware_config){
|
||||
if ($config_entry_key eq 'vsphere_server') {
|
||||
for my $server_config_entry_key (keys %{$centreon_vmware_config{vsphere_server}}) {
|
||||
my $config_entry_content = $centreon_vmware_config{vsphere_server}->{$server_config_entry_key};
|
||||
$config_entry_content->{name} = $server_config_entry_key;
|
||||
push @{$new_config_structure->{vsphere_server}}, $config_entry_content;
|
||||
}
|
||||
} else {
|
||||
$new_config_structure->{$config_entry_key} = $centreon_vmware_config{$config_entry_key};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
my $new_json_config = encode_json($new_config_structure) or die "Unable to convert this object to JSON:\n" . Dumper($new_config_structure);
|
||||
print($new_json_config);
|
||||
|
||||
exit(0);
|
382
connectors/vmware/src/centreon/script/centreonvault.pm
Normal file
382
connectors/vmware/src/centreon/script/centreonvault.pm
Normal file
@ -0,0 +1,382 @@
|
||||
#
|
||||
# Copyright 2024 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::centreonvault;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use JSON::XS;
|
||||
use MIME::Base64;
|
||||
use Crypt::OpenSSL::AES;
|
||||
use Net::Curl::Easy qw(:constants);
|
||||
use centreon::vmware::common;
|
||||
|
||||
my $VAULT_PATH_REGEX = qr/^secret::hashicorp_vault::([^:]+)::(.+)$/;
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = bless \%options, $class;
|
||||
# mandatory options:
|
||||
# - logger: logger object
|
||||
# - config_file: path of a JSON vault config file
|
||||
|
||||
$self->{enabled} = 1;
|
||||
$self->{crypted_credentials} = 1;
|
||||
|
||||
if ( !$self->init() ) {
|
||||
$self->{enabled} = 0;
|
||||
$self->{logger}->writeLogError("An error occurred in init() method. Centreonvault cannot be used.");
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub init {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->check_options() or return undef;
|
||||
|
||||
# check if the following information is available
|
||||
$self->{logger}->writeLogDebug("Reading Vault configuration from file " . $self->{config_file} . ".");
|
||||
$self->{vault_config} = centreon::vmware::common::parse_json_file( 'json_file' => $self->{config_file} );
|
||||
if (defined($self->{vault_config}->{error_message})) {
|
||||
$self->{logger}->writeLogError("Error while parsing " . $self->{config_file} . ": "
|
||||
. $self->{vault_config}->{error_message});
|
||||
return undef;
|
||||
}
|
||||
|
||||
$self->check_configuration() or return undef;
|
||||
|
||||
$self->{logger}->writeLogDebug("Vault configuration read. Name: " . $self->{vault_config}->{name}
|
||||
. ". Url: " . $self->{vault_config}->{url} . ".");
|
||||
|
||||
# Create the Curl object, it will be used several times
|
||||
$self->{curl_easy} = Net::Curl::Easy->new();
|
||||
$self->{curl_easy}->setopt( CURLOPT_USERAGENT, "Centreon VMware daemon's centreonvault.pm");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
if ( !defined($self->{logger}) ) {
|
||||
die "FATAL: No logger given to the constructor. Centreonvault cannot be used.";
|
||||
}
|
||||
if ( !defined($self->{config_file})) {
|
||||
$self->{logger}->writeLogError("No config file given to the constructor. Centreonvault cannot be used.");
|
||||
return undef;
|
||||
}
|
||||
if ( ! -f $self->{config_file} ) {
|
||||
$self->{logger}->writeLogError("The given configuration file " . $self->{config_file}
|
||||
. " does not exist. Centreonvault cannot be used.");
|
||||
return undef;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub check_configuration {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
if ( !defined($self->{vault_config}->{url}) || $self->{vault_config}->{url} eq '') {
|
||||
$self->{logger}->writeLogInfo("Vault url is missing from configuration.");
|
||||
$self->{vault_config}->{url} = '127.0.0.1';
|
||||
}
|
||||
if ( !defined($self->{vault_config}->{port}) || $self->{vault_config}->{port} eq '') {
|
||||
$self->{logger}->writeLogInfo("Vault port is missing from configuration.");
|
||||
$self->{vault_config}->{port} = '443';
|
||||
}
|
||||
|
||||
# Normally, the role_id and secret_id data are encrypted using AES wit the following information:
|
||||
# firstKey = APP_SECRET (environment variable)
|
||||
# secondKey = 'salt' (hashing) key given by vault.json configuration file
|
||||
# both are base64 encoded
|
||||
if ( !defined($self->{vault_config}->{salt}) || $self->{vault_config}->{salt} eq '') {
|
||||
$self->{logger}->writeLogError("Vault environment does not seem complete: 'salt' attribute missing from "
|
||||
. $self->{config_file}
|
||||
. ". 'role_id' and 'secret_id' won't be decrypted, so they'll be used as they're stored in the vault config file.");
|
||||
$self->{crypted_credentials} = 0;
|
||||
$self->{hash_key} = '';
|
||||
} else {
|
||||
$self->{hash_key} = $self->{vault_config}->{salt}; # key for sha3-512 hmac
|
||||
}
|
||||
|
||||
if ( !defined($ENV{'APP_SECRET'}) || $ENV{'APP_SECRET'} eq '' ) {
|
||||
$self->{logger}->writeLogError("Vault environment does not seem complete. 'APP_SECRET' environment variable missing."
|
||||
. " 'role_id' and 'secret_id' won't be decrypted, so they'll be used as they're stored in the vault config file.");
|
||||
$self->{crypted_credentials} = 0;
|
||||
$self->{encryption_key} = '';
|
||||
} else {
|
||||
$self->{encryption_key} = $ENV{'APP_SECRET'}; # key for aes-256-cbc
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub extract_and_decrypt {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $input = decode_base64($options{data});
|
||||
$self->{logger}->writeLogDebug("data to extract and decrypt: '" . $options{data} . "'");
|
||||
|
||||
# with AES-256, the IV length must 16 bytes
|
||||
my $iv_length = 16;
|
||||
# extract the IV, the hashed data, the encrypted data
|
||||
my $iv = substr($input, 0, $iv_length); # initialization vector
|
||||
my $hashed_data = substr($input, $iv_length, 64); # hmac of the original data, for integrity control
|
||||
my $encrypted_data = substr($input, $iv_length + 64); # data to decrypt
|
||||
|
||||
# create the AES object
|
||||
$self->{logger}->writeLogDebug(
|
||||
"Creating the AES decryption object for initialization vector (IV) of length "
|
||||
. length($iv) . "B, key of length " . length($self->{encryption_key}) . "B."
|
||||
);
|
||||
my $cipher;
|
||||
eval {
|
||||
$cipher = Crypt::OpenSSL::AES->new(
|
||||
decode_base64( $self->{encryption_key} ),
|
||||
{
|
||||
'cipher' => 'AES-256-CBC',
|
||||
'iv' => $iv,
|
||||
'padding' => 1
|
||||
}
|
||||
);
|
||||
};
|
||||
if ($@) {
|
||||
$self->{logger}->writeLogError("There was an error while creating the AES object: " . $@);
|
||||
return undef;
|
||||
}
|
||||
|
||||
# decrypt
|
||||
$self->{logger}->writeLogDebug("Decrypting the data of length " . length($encrypted_data) . "B.");
|
||||
my $decrypted_data;
|
||||
eval {$decrypted_data = $cipher->decrypt($encrypted_data);};
|
||||
if ($@) {
|
||||
$self->{logger}->writeLogError("There was an error while decrypting one of the AES-encrypted data: " . $@);
|
||||
return undef;
|
||||
}
|
||||
|
||||
return $decrypted_data;
|
||||
}
|
||||
|
||||
sub authenticate {
|
||||
my ($self) = @_;
|
||||
|
||||
# initial value: assuming the role and secret id might not be encrypted
|
||||
my $role_id = $self->{vault_config}->{role_id};
|
||||
my $secret_id = $self->{vault_config}->{secret_id};
|
||||
|
||||
|
||||
if ($self->{crypted_credentials}) {
|
||||
# Then decrypt using https://github.com/perl-openssl/perl-Crypt-OpenSSL-AES
|
||||
# keep the decrypted data in local variables so that they stay in memory for as little time as possible
|
||||
$self->{logger}->writeLogDebug("Decrypting the credentials needed to authenticate to the vault.");
|
||||
$role_id = $self->extract_and_decrypt( ('data' => $role_id ));
|
||||
$secret_id = $self->extract_and_decrypt( ('data' => $secret_id ));
|
||||
$self->{logger}->writeLogDebug("role_id and secret_id have been decrypted.");
|
||||
} else {
|
||||
$self->{logger}->writeLogDebug("role_id and secret_id are not crypted");
|
||||
}
|
||||
|
||||
|
||||
# Authenticate to get the token
|
||||
my $url = "https://" . $self->{vault_config}->{url} . ":" . $self->{vault_config}->{port} . "/v1/auth/approle/login";
|
||||
$self->{logger}->writeLogDebug("Authenticating to the vault server at URL: $url");
|
||||
$self->{curl_easy}->setopt( CURLOPT_URL, $url );
|
||||
|
||||
my $post_data = "role_id=$role_id&secret_id=$secret_id";
|
||||
my $auth_result_json;
|
||||
# to get more details (in STDERR)
|
||||
#$self->{curl_easy}->setopt(CURLOPT_VERBOSE, 1);
|
||||
$self->{curl_easy}->setopt(CURLOPT_POST, 1);
|
||||
$self->{curl_easy}->setopt(CURLOPT_POSTFIELDS, $post_data);
|
||||
$self->{curl_easy}->setopt(CURLOPT_POSTFIELDSIZE, length($post_data));
|
||||
$self->{curl_easy}->setopt(CURLOPT_WRITEDATA(), \$auth_result_json);
|
||||
|
||||
eval {
|
||||
$self->{curl_easy}->perform();
|
||||
};
|
||||
if ($@) {
|
||||
$self->{logger}->writeLogError("Error while authenticating to the vault: " . $@);
|
||||
return undef;
|
||||
}
|
||||
|
||||
$self->{logger}->writeLogInfo("Authentication to the vault passed." );
|
||||
|
||||
my $auth_result_obj = centreon::vmware::common::transform_json_to_object($auth_result_json);
|
||||
if (defined($auth_result_obj->{error_message})) {
|
||||
$self->{logger}->writeLogError("Error while decoding JSON '$auth_result_json'. Message: "
|
||||
. $auth_result_obj->{error_message});
|
||||
return undef;
|
||||
}
|
||||
|
||||
# store the token (.auth.client_token) and its expiration date (current date + .lease_duration)
|
||||
my $expiration_epoch = -1;
|
||||
my $lease_duration = $auth_result_obj->{auth}->{lease_duration};
|
||||
if ( defined($lease_duration)
|
||||
&& $lease_duration =~ /\d+/
|
||||
&& $lease_duration > 0 ) {
|
||||
$expiration_epoch = time() + $lease_duration;
|
||||
}
|
||||
$self->{auth} = {
|
||||
'token' => $auth_result_obj->{auth}->{client_token},
|
||||
'expiration_epoch' => $expiration_epoch
|
||||
};
|
||||
|
||||
$self->{logger}->writeLogInfo("Authenticating worked. Token valid until "
|
||||
. localtime($self->{auth}->{expiration_epoch}));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub is_token_still_valid {
|
||||
my ($self) = @_;
|
||||
if (
|
||||
!defined($self->{auth})
|
||||
|| !defined($self->{auth}->{token})
|
||||
|| $self->{auth}->{token} eq ''
|
||||
|| $self->{auth}->{expiration_epoch} <= time()
|
||||
) {
|
||||
$self->{logger}->writeLogInfo("The token has expired or is invalid.");
|
||||
return undef;
|
||||
}
|
||||
$self->{logger}->writeLogDebug("The token is still valid.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub get_secret {
|
||||
my ($self, $secret) = @_;
|
||||
|
||||
# if vault not enabled, return the secret unchanged
|
||||
return $secret if ( ! $self->{enabled});
|
||||
|
||||
my ($secret_path, $secret_name) = $secret =~ $VAULT_PATH_REGEX;
|
||||
if (!defined($secret_path) || !defined($secret_name)) {
|
||||
$self->{logger}->writeLogInfo("A string given to get_secret does not look like a secret. Using it as a plain text credential?");
|
||||
return $secret;
|
||||
}
|
||||
$self->{logger}->writeLogDebug("Secret path: $secret_path - Secret name: $secret_name");
|
||||
|
||||
if (!defined($self->{auth}) || !$self->is_token_still_valid() ) {
|
||||
$self->authenticate() or return $secret;
|
||||
}
|
||||
|
||||
# prepare the GET statement
|
||||
my $get_result_json;
|
||||
my $url = "https://" . $self->{vault_config}->{url} . ":" . $self->{vault_config}->{port} . "/v1/" . $secret_path;
|
||||
$self->{logger}->writeLogDebug("Requesting URL: $url");
|
||||
|
||||
#$self->{curl_easy}->setopt( CURLOPT_VERBOSE, 1 );
|
||||
$self->{curl_easy}->setopt( CURLOPT_URL, $url );
|
||||
$self->{curl_easy}->setopt( CURLOPT_POST, 0 );
|
||||
$self->{curl_easy}->setopt( CURLOPT_WRITEDATA(), \$get_result_json );
|
||||
$self->{curl_easy}->setopt( CURLOPT_HTTPHEADER(), ["X-Vault-Token: " . $self->{auth}->{token}]);
|
||||
|
||||
eval {
|
||||
$self->{curl_easy}->perform();
|
||||
};
|
||||
if ($@) {
|
||||
$self->{logger}->writeLogError("Error while getting a secret from the vault: " . $@);
|
||||
return $secret;
|
||||
}
|
||||
|
||||
$self->{logger}->writeLogDebug("Request passed.");
|
||||
# request_id
|
||||
|
||||
# the result is a json string, convert it into an object
|
||||
my $get_result_obj = centreon::vmware::common::transform_json_to_object($get_result_json);
|
||||
if (defined($get_result_obj->{error_message})) {
|
||||
$self->{logger}->writeLogError("Error while decoding JSON '$get_result_json'. Message: "
|
||||
. $get_result_obj->{error_message});
|
||||
return $secret;
|
||||
}
|
||||
$self->{logger}->writeLogDebug("Request id is " . $get_result_obj->{request_id});
|
||||
|
||||
# .data.data will contain the stored macros
|
||||
if ( !defined($get_result_obj->{data})
|
||||
|| !defined($get_result_obj->{data}->{data})
|
||||
|| !defined($get_result_obj->{data}->{data}->{$secret_name}) ) {
|
||||
$self->{logger}->writeLogError("Could not get secret '$secret_name' from path '$secret_path' from the vault. Enable debug for more details.");
|
||||
$self->{logger}->writeLogDebug("Response: " . $get_result_json);
|
||||
return $secret;
|
||||
}
|
||||
$self->{logger}->writeLogInfo("Secret '$secret_name' from path '$secret_path' retrieved from the vault.");
|
||||
return $get_result_obj->{data}->{data}->{$secret_name};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Centreon Vault password manager
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Allows to retrieve secrets (usually username and password) from a Hashicorp vault compatible api given a config file as constructor.
|
||||
|
||||
use centreon::vmware::logger;
|
||||
use centreon::script::centreonvault;
|
||||
my $vault = centreon::script::centreonvault->new(
|
||||
(
|
||||
'logger' => centreon::vmware::logger->new(),
|
||||
'config_file' => '/var/lib/centreon/vault/vault.json'
|
||||
)
|
||||
);
|
||||
my $password = $vault->get_secret('secret::hashicorp_vault::mypath/to/mysecrets::password');
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 new(\%options)
|
||||
|
||||
Constructor of the vault object.
|
||||
|
||||
%options must provide:
|
||||
|
||||
- logger: an object of the centreon::vmware::logger class.
|
||||
|
||||
- config_file: full path and file name of the Centreon Vault JSON config file.
|
||||
|
||||
The default config_file path should be '/var/lib/centreon/vault/vault.json'.
|
||||
The expected file format for Centreon Vault is:
|
||||
|
||||
{
|
||||
"name": "hashicorp_vault",
|
||||
"url": "vault-server.mydomain.com",
|
||||
"salt": "<base64 encoded(<32 bytes long key used to hash the crypted data)>",
|
||||
"port": 443,
|
||||
"root_path": "vmware_daemon",
|
||||
"role_id": "<base64 encoded(<iv><hmac_hash><encrypted_role_id>)",
|
||||
"secret_id": "<base64 encoded(<iv><hmac_hash><encrypted_secret_id>)"
|
||||
}
|
||||
|
||||
=head2 get_secret($secret)
|
||||
|
||||
Returns the secret stored in the Centreon Vault at the given path.
|
||||
If the format of the secret does not match the regular expression
|
||||
C</^secret::hashicorp_vault::([^:]+)::(.+)$/>
|
||||
or in case of any failure in the process, the method will return the secret unchanged.
|
||||
|
||||
=cut
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2019 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2019 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
@ -162,19 +162,22 @@ sub run {
|
||||
push @$customValuesEsx, { key => $customFields->{ $_->{key} }, value => $_->{value} };
|
||||
}
|
||||
}
|
||||
$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;
|
||||
|
||||
$esx{type} = 'esx';
|
||||
$esx{name} = $esx->name;
|
||||
$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;
|
||||
$esx{custom_attributes} = $customValuesEsx;
|
||||
$esx{tags} = [];
|
||||
if (defined($tags)) {
|
||||
$esx{tags} = $tags->{esx}->{ $esx->{mo_ref}->{value} } if (defined($tags->{esx}->{ $esx->{mo_ref}->{value} }));
|
||||
$esx{tags} = [];
|
||||
$esx{os} = defined($esx->{'config.product.productLineId'}) ? $esx->{'config.product.productLineId'} . ' ' : ''
|
||||
. defined($esx->{'config.product.version'}) ? $esx->{'config.product.version'} : '';
|
||||
|
||||
if (defined($tags) and defined($tags->{esx}->{ $esx->{mo_ref}->{value} })) {
|
||||
$esx{tags} = $tags->{esx}->{ $esx->{mo_ref}->{value} };
|
||||
}
|
||||
|
||||
foreach my $nic (@{$esx->{'config.virtualNicManagerInfo.netConfig'}}) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
@ -25,7 +25,7 @@ use VMware::VIRuntime;
|
||||
use VMware::VILib;
|
||||
use ZMQ::LibZMQ4;
|
||||
use ZMQ::Constants qw(:all);
|
||||
use JSON::XS;;
|
||||
use JSON::XS;
|
||||
|
||||
my $manager_display = {};
|
||||
my $manager_response = {};
|
||||
@ -794,4 +794,38 @@ sub vsan_get_performances {
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub transform_json_to_object {
|
||||
my ($json_data) = @_;
|
||||
|
||||
my $json_as_object;
|
||||
eval {
|
||||
$json_as_object = decode_json($json_data);
|
||||
};
|
||||
if ($@) {
|
||||
return ('error_message' => "Could not decode JSON from '$json_data'. Reason: " . $@);
|
||||
};
|
||||
return($json_as_object);
|
||||
}
|
||||
|
||||
sub parse_json_file {
|
||||
my (%options) = @_;
|
||||
|
||||
my $fh;
|
||||
my $json_data = '';
|
||||
|
||||
if ( !defined($options{json_file}) ) {
|
||||
return ('error_message' => "parse_json_file: json_file option is mandatory");
|
||||
}
|
||||
|
||||
my $json_file = $options{json_file};
|
||||
|
||||
open($fh, '<', $json_file) or return ('error_message' => "parse_json_file: Cannot open " . $json_file);
|
||||
for my $line (<$fh>) {
|
||||
chomp $line;
|
||||
$json_data .= $line;
|
||||
}
|
||||
close($fh);
|
||||
return transform_json_to_object($json_data);
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
@ -237,7 +237,7 @@ sub run {
|
||||
my ($connector) = shift;
|
||||
my $timeout_process = 0;
|
||||
|
||||
$connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' init begin");
|
||||
$connector->{logger}->writeLogInfo("'" . $connector->{whoaim} . "' ZMQ init begin");
|
||||
my $context = zmq_init();
|
||||
|
||||
$backend = zmq_socket($context, ZMQ_DEALER);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2019 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2019 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2019 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2019 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2019 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
@ -50,9 +50,18 @@ use warnings;
|
||||
use Sys::Syslog qw(:standard :macros);
|
||||
use IO::Handle;
|
||||
|
||||
my %severities = (1 => LOG_INFO,
|
||||
2 => LOG_ERR,
|
||||
4 => LOG_DEBUG);
|
||||
my %syslog_severities = (
|
||||
1 => LOG_CRIT,
|
||||
2 => LOG_ERR,
|
||||
4 => LOG_INFO,
|
||||
5 => LOG_DEBUG
|
||||
);
|
||||
my %human_severities = (
|
||||
1 => 'fatal',
|
||||
2 => 'error',
|
||||
4 => 'info',
|
||||
5 => 'debug'
|
||||
);
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
@ -62,8 +71,8 @@ sub new {
|
||||
file => 0,
|
||||
filehandler => undef,
|
||||
# 0 = nothing, 1 = critical, 3 = info, 7 = debug
|
||||
severity => 3,
|
||||
old_severity => 3,
|
||||
severity => 4,
|
||||
old_severity => 4,
|
||||
# 0 = stdout, 1 = file, 2 = syslog
|
||||
log_mode => 0,
|
||||
# Output pid of current process
|
||||
@ -104,7 +113,7 @@ sub is_file_mode {
|
||||
sub is_debug {
|
||||
my $self = shift;
|
||||
|
||||
if (($self->{severity} & 4) == 0) {
|
||||
if ($self->{severity} < 5) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -138,21 +147,22 @@ sub set_default_severity {
|
||||
# Getter/Setter Log severity
|
||||
sub severity {
|
||||
my $self = shift;
|
||||
|
||||
if (@_) {
|
||||
my $save_severity = $self->{severity};
|
||||
if ($_[0] =~ /^[012347]$/) {
|
||||
if ($_[0] =~ /^[01245]$/) {
|
||||
$self->{severity} = $_[0];
|
||||
} elsif ($_[0] eq "none") {
|
||||
$self->{severity} = 0;
|
||||
} elsif ($_[0] eq "error") {
|
||||
$self->{severity} = 1;
|
||||
$self->{severity} = 2;
|
||||
} elsif ($_[0] eq "info") {
|
||||
$self->{severity} = 3;
|
||||
$self->{severity} = 4;
|
||||
} elsif ($_[0] eq "debug") {
|
||||
$self->{severity} = 7;
|
||||
$self->{severity} = 5;
|
||||
} else {
|
||||
$self->writeLogError("Wrong severity value set.");
|
||||
return -1;
|
||||
$self->writeLogError("Wrong severity value given: " . $_[0] . ". Keeping default value: " . $self->{severity});
|
||||
return $self->{severity};
|
||||
}
|
||||
$self->{old_severity} = $save_severity;
|
||||
}
|
||||
@ -176,14 +186,18 @@ sub get_date {
|
||||
|
||||
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;
|
||||
}
|
||||
# do nothing if the configured severity does not imply logging this message
|
||||
return if ($self->{severity} < $severity);
|
||||
|
||||
my $withdate = (defined $options{withdate}) ? $options{withdate} : 1;
|
||||
$msg = ($self->{withpid} == 1) ? "[$$] $msg " : $msg;
|
||||
|
||||
my $newmsg = ($withdate)
|
||||
? "[" . $self->get_date . "] " : '';
|
||||
$newmsg .= "[" . $human_severities{$severity} . "] " . $msg;
|
||||
# Bit mask: if AND gives 0 it means the log level does not require this message to be logged
|
||||
|
||||
if ($self->{log_mode} == 0) {
|
||||
print "$newmsg\n";
|
||||
} elsif ($self->{log_mode} == 1) {
|
||||
@ -191,20 +205,24 @@ sub writeLog($$$%) {
|
||||
print { $self->{filehandler} } "$newmsg\n";
|
||||
}
|
||||
} elsif ($self->{log_mode} == 2) {
|
||||
syslog($severities{$severity}, $msg);
|
||||
syslog($syslog_severities{$severity}, $msg);
|
||||
}
|
||||
}
|
||||
|
||||
sub writeLogDebug {
|
||||
shift->writeLog(4, @_);
|
||||
shift->writeLog(5, @_);
|
||||
}
|
||||
|
||||
sub writeLogInfo {
|
||||
shift->writeLog(2, @_);
|
||||
shift->writeLog(4, @_);
|
||||
}
|
||||
|
||||
sub writeLogError {
|
||||
shift->writeLog(2, @_);
|
||||
}
|
||||
sub writeLogFatal {
|
||||
shift->writeLog(1, @_);
|
||||
die("FATAL: " . $_[0] . "\n");
|
||||
}
|
||||
|
||||
sub DESTROY {
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
@ -46,9 +46,9 @@ sub new {
|
||||
$self->{name} = $name;
|
||||
$self->{logger} = centreon::vmware::logger->new();
|
||||
$self->{options} = {
|
||||
"logfile=s" => \$self->{log_file},
|
||||
"logfile=s" => \$self->{log_file},
|
||||
"severity=s" => \$self->{severity},
|
||||
"help|?" => \$self->{help}
|
||||
"help|?" => \$self->{help}
|
||||
};
|
||||
return $self;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
# Copyright 2015 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
@ -42,6 +42,10 @@ centreon_vmware.pl [options]
|
||||
|
||||
Specify the path to the centreon_vmware configuration file (default: /etc/centreon/centreon_vmware.pm).
|
||||
|
||||
=item B<--vault-config>
|
||||
|
||||
Full path to the file defining access to the Centreon vault (/etc/centreon-engine/centreonvault.json by default).
|
||||
|
||||
=item B<--help>
|
||||
|
||||
Print a brief help message and exits.
|
||||
@ -51,6 +55,6 @@ Print a brief help message and exits.
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<centreon_vmware.pl> will connect to ESX and/or VirtualCenter.
|
||||
Use the plugin 'apps::vmware::connector::plugin' from: https://github.com/centreon/centreon-plugins
|
||||
To be used with the plugin 'apps::vmware::connector::plugin' from: https://github.com/centreon/centreon-plugins
|
||||
|
||||
=cut
|
||||
|
43
connectors/vmware/tests/centreon/vmware/centreonvault.t
Normal file
43
connectors/vmware/tests/centreon/vmware/centreonvault.t
Normal file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test2::V0;
|
||||
use Test2::Plugin::NoWarnings echo => 1;
|
||||
|
||||
use FindBin;
|
||||
use lib qw($FindBin::RealBin/../../../src);
|
||||
|
||||
use centreon::script::centreonvault;
|
||||
use centreon::vmware::logger;
|
||||
my $vault;
|
||||
my $global_logger = centreon::vmware::logger->new();
|
||||
my @test_data = (
|
||||
{'logger' => undef, 'config_file' => undef, 'test' => '$error_message =~ /FATAL: No logger given to the constructor/'},
|
||||
{'logger' => $global_logger, 'config_file' => undef, 'test' => '$vault->{enabled} == 0'},
|
||||
{'logger' => $global_logger, 'config_file' => 'does_not_exist.json', 'test' => '$vault->{enabled} == 0'}
|
||||
);
|
||||
|
||||
for my $i (0..$#test_data) {
|
||||
my $logger = $test_data[$i]->{logger};
|
||||
my $config_file = $test_data[$i]->{config_file};
|
||||
my $test = $test_data[$i]->{test};
|
||||
|
||||
use Data::Dumper;
|
||||
#print("Test $i with logger " . Dumper($logger) ."\n");
|
||||
eval {
|
||||
$vault = centreon::script::centreonvault->new(
|
||||
(
|
||||
'logger' => $logger,
|
||||
'config_file' => $config_file
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
my $error_message = defined($@) ? $@ : '';
|
||||
print("Test $i with vault " . Dumper($vault) ."\n");
|
||||
|
||||
ok (eval($test), "TEST CASE $i FAILED: '$test' with error message: '" . $error_message . "'" );
|
||||
}
|
||||
|
||||
done_testing();
|
||||
|
Loading…
x
Reference in New Issue
Block a user