diff --git a/src/apps/redis/sentinel/custom/cli.pm b/src/apps/redis/sentinel/custom/cli.pm index 1b5a59b40..17b279224 100644 --- a/src/apps/redis/sentinel/custom/cli.pm +++ b/src/apps/redis/sentinel/custom/cli.pm @@ -49,6 +49,8 @@ sub new { 'password:s' => { name => 'password' }, 'tls' => { name => 'tls' }, 'cacert:s' => { name => 'cacert' }, + 'cert:s' => { name => 'cert' }, + 'key:s' => { name => 'key' }, 'insecure' => { name => 'insecure' }, 'timeout:s' => { name => 'timeout' } }); @@ -73,15 +75,18 @@ sub set_defaults {} sub check_options { my ($self, %options) = @_; - $self->{ssh_hostname} = defined($self->{option_results}->{ssh_hostname}) && $self->{option_results}->{ssh_hostname} ne '' ? $self->{option_results}->{ssh_hostname} : ''; - $self->{server} = defined($self->{option_results}->{server}) && $self->{option_results}->{server} ne '' ? $self->{option_results}->{server} : ''; - $self->{port} = defined($self->{option_results}->{port}) && $self->{option_results}->{port} ne '' ? $self->{option_results}->{port} : 26379; - $self->{username} = defined($self->{option_results}->{username}) && $self->{option_results}->{username} ne '' ? $self->{option_results}->{username} : ''; - $self->{password} = defined($self->{option_results}->{password}) && $self->{option_results}->{password} ne '' ? $self->{option_results}->{password} : ''; + $self->{ssh_hostname} = $self->{option_results}->{ssh_hostname} // ''; + $self->{server} = $self->{option_results}->{server} // ''; + $self->{port} = $self->{option_results}->{port} || 26379; + $self->{username} = $self->{option_results}->{username} // ''; + $self->{password} = $self->{option_results}->{password} // ''; $self->{timeout} = defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /(\d+)/ ? $1 : 10; - $self->{tls} = defined($self->{option_results}->{tls}) ? 1 : 0; $self->{insecure} = defined($self->{option_results}->{insecure}) ? 1 : 0; - $self->{cacert} = defined($self->{option_results}->{cacert}) && $self->{option_results}->{cacert} ne '' ? $self->{option_results}->{cacert} : ''; + $self->{cacert} = $self->{option_results}->{cacert} // ''; + $self->{cert} = $self->{option_results}->{cert} // ''; + $self->{key} = $self->{option_results}->{key} // ''; + # --tls is implied by --key and --cert + $self->{tls} = ($self->{cert} ne '' || $self->{key} ne '' || defined($self->{option_results}->{tls})) ? 1 : 0; if ($self->{server} eq '') { $self->{output}->add_option_msg(short_msg => 'Need to specify --server option.'); @@ -159,6 +164,8 @@ sub get_extra_options { my $options = ''; $options .= ' --tls' if ($self->{tls} == 1); $options .= " --cacert '" . $self->{cacert} . "'" if ($self->{cacert} ne ''); + $options .= " --cert '" . $self->{cert} . "'" if ($self->{cert} ne ''); + $options .= " --key '" . $self->{key} . "'" if ($self->{key} ne ''); $options .= ' --insecure' if ($self->{insecure} == 1); $options .= " --user '" . $self->{username} . "'" if ($self->{username} ne ''); $options .= " -a '" . $self->{password} . "'" if ($self->{password} ne ''); @@ -221,11 +228,20 @@ Sentinel port (default: 26379). =item B<--tls> Establish a secure TLS connection (redis-cli >= 6.x mandatory). +--tls is automatically enabled when --cert or --key are used. =item B<--cacert> CA Certificate file to verify with (redis-cli >= 6.x mandatory). +=item B<--cert> + +Client certificate to authenticate with (redis-cli >= 6.x mandatory). + +=item B<--key> + +Private key file to authenticate with (redis-cli >= 6.x mandatory). + =item B<--insecure> Allow insecure TLS connection by skipping cert validation (since redis-cli 6.2.0). diff --git a/src/database/redis/custom/cli.pm b/src/database/redis/custom/cli.pm index f6c3a7450..5d6712516 100644 --- a/src/database/redis/custom/cli.pm +++ b/src/database/redis/custom/cli.pm @@ -52,6 +52,8 @@ sub new { 'service:s' => { name => 'service' }, 'tls' => { name => 'tls' }, 'cacert:s' => { name => 'cacert' }, + 'cert:s' => { name => 'cert' }, + 'key:s' => { name => 'key' }, 'insecure' => { name => 'insecure' }, 'timeout:s' => { name => 'timeout' } }); @@ -76,31 +78,34 @@ sub set_defaults {} sub check_options { my ($self, %options) = @_; - $self->{ssh_hostname} = defined($self->{option_results}->{ssh_hostname}) && $self->{option_results}->{ssh_hostname} ne '' ? $self->{option_results}->{ssh_hostname} : ''; - $self->{server} = defined($self->{option_results}->{server}) && $self->{option_results}->{server} ne '' ? $self->{option_results}->{server} : ''; - $self->{port} = defined($self->{option_results}->{port}) && $self->{option_results}->{port} ne '' ? $self->{option_results}->{port} : 6379; - $self->{sentinel_port} = defined($self->{option_results}->{sentinel_port}) && $self->{option_results}->{sentinel_port} =~ /(\d+)/ ? $1 : 26379; - $self->{username} = defined($self->{option_results}->{password}) && $self->{option_results}->{username} ne '' ? $self->{option_results}->{username} : ''; - $self->{password} = defined($self->{option_results}->{password}) && $self->{option_results}->{password} ne '' ? $self->{option_results}->{password} : ''; + $self->{ssh_hostname} = $self->{option_results}->{ssh_hostname} // ''; + $self->{server} = $self->{option_results}->{server} // ''; + $self->{port} = $self->{option_results}->{port} || 6379; + $self->{sentinel_port} = $self->{option_results}->{sentinel_port} && $self->{option_results}->{sentinel_port} =~ /(\d+)/ ? $1 : 26379; + $self->{username} = $self->{option_results}->{username} // ''; + $self->{password} = $self->{option_results}->{password} // ''; $self->{timeout} = defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /(\d+)/ ? $1 : 10; - $self->{tls} = defined($self->{option_results}->{tls}) ? 1 : 0; $self->{insecure} = defined($self->{option_results}->{insecure}) ? 1 : 0; - $self->{cacert} = defined($self->{option_results}->{cacert}) && $self->{option_results}->{cacert} ne '' ? $self->{option_results}->{cacert} : ''; + $self->{cacert} = $self->{option_results}->{cacert} // ''; + $self->{cert} = $self->{option_results}->{cert} // ''; + $self->{key} = $self->{option_results}->{key} // ''; + # --tls is implied by --key and --cert + $self->{tls} = ($self->{cert} ne '' || $self->{key} ne '' || defined($self->{option_results}->{tls})) ? 1 : 0; $self->{sentinel} = []; if (defined($self->{option_results}->{sentinel})) { foreach my $addr (@{$self->{option_results}->{sentinel}}) { next if ($addr eq ''); - push @{$self->{sentinel}}, $addr . ($self->{sentinel_port} ne '' ? ':' . $self->{sentinel_port} : '') + push @{$self->{sentinel}}, $addr . ':' . $self->{sentinel_port}; } } - $self->{service} = defined($self->{option_results}->{service}) && $self->{option_results}->{service} ne '' ? $self->{option_results}->{service} : ''; + $self->{service} = $self->{option_results}->{service} // ''; - if ($self->{server} eq '' && scalar(@{$self->{sentinel}}) <= 0) { + if ($self->{server} eq '' && not @{$self->{sentinel}}) { $self->{output}->add_option_msg(short_msg => 'Need to specify --server or --sentinel option.'); $self->{output}->option_exit(); } - if (scalar(@{$self->{sentinel}}) > 0 && $self->{service} eq '') { + if (@{$self->{sentinel}} && $self->{service} eq '') { $self->{output}->add_option_msg(short_msg => 'Need to specify --service option.'); $self->{output}->option_exit(); } @@ -172,6 +177,8 @@ sub get_extra_options { my $options = ''; $options .= ' --tls' if ($self->{tls} == 1); $options .= " --cacert '" . $self->{cacert} . "'" if ($self->{cacert} ne ''); + $options .= " --cert '" . $self->{cert} . "'" if ($self->{cert} ne ''); + $options .= " --key '" . $self->{key} . "'" if ($self->{key} ne ''); $options .= ' --insecure' if ($self->{insecure} == 1); $options .= " --user '" . $self->{username} . "'" if ($self->{username} ne ''); $options .= " -a '" . $self->{password} . "'" if ($self->{password} ne ''); @@ -185,6 +192,7 @@ sub sentinels_get_master { foreach my $addr (@{$self->{sentinel}}) { my ($sentinel_host, $sentinel_port) = split(/:/, $addr); my $command_options = "-h '" . $sentinel_host . "' -p " . (defined($sentinel_port) ? $sentinel_port : 26379); + $command_options .= $self->get_extra_options(); $command_options .= ' --no-raw'; $command_options .= ' sentinel get-master-addr-by-name ' . $self->{service}; my ($stdout, $exit_code) = $self->execute_command( @@ -209,7 +217,7 @@ sub get_info { my ($self, %options) = @_; my $command_options; - if (scalar(@{$self->{sentinel}}) > 0) { + if (@{$self->{sentinel}}) { my ($host, $port) = $self->sentinels_get_master(); $command_options = "-h '" . $host . "' -p " . $port; } else { @@ -264,11 +272,20 @@ Redis port (default: 6379). =item B<--tls> Establish a secure TLS connection (redis-cli >= 6.x mandatory). +--tls is automatically enabled when --cert or --key are used. =item B<--cacert> CA Certificate file to verify with (redis-cli >= 6.x mandatory). +=item B<--cert> + +Client certificate to authenticate with (redis-cli >= 6.x mandatory). + +=item B<--key> + +Private key file to authenticate with (redis-cli >= 6.x mandatory). + =item B<--insecure> Allow insecure TLS connection by skipping cert validation (since redis-cli 6.2.0). diff --git a/src/database/redis/custom/perlmod.pm b/src/database/redis/custom/perlmod.pm index 00da87dc0..8ef567940 100644 --- a/src/database/redis/custom/perlmod.pm +++ b/src/database/redis/custom/perlmod.pm @@ -48,7 +48,11 @@ sub new { 'password:s' => { name => 'password' }, 'sentinel:s@' => { name => 'sentinel' }, 'sentinel-port:s' => { name => 'sentinel_port' }, - 'service:s' => { name => 'service' } + 'service:s' => { name => 'service' }, + 'tls' => { name => 'tls' }, + 'cacert:s' => { name => 'cacert' }, + 'cert:s' => { name => 'cert' }, + 'key:s' => { name => 'key' } }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REDIS OPTIONS', once => 1); @@ -69,11 +73,14 @@ sub set_defaults {} sub check_options { my ($self, %options) = @_; - $self->{server} = defined($self->{option_results}->{server}) && $self->{option_results}->{server} ne '' ? $self->{option_results}->{server} : ''; + $self->{server} = $self->{option_results}->{server} // ''; $self->{port} = defined($self->{option_results}->{port}) && $self->{option_results}->{port} =~ /(\d+)/ ? $1 : 6379; $self->{sentinel_port} = defined($self->{option_results}->{sentinel_port}) && $self->{option_results}->{sentinel_port} =~ /(\d+)/ ? $1 : 26379; - $self->{username} = defined($self->{option_results}->{username}) && $self->{option_results}->{username} ne '' ? $self->{option_results}->{username} : ''; - $self->{password} = defined($self->{option_results}->{password}) && $self->{option_results}->{password} ne '' ? $self->{option_results}->{password} : ''; + $self->{username} = $self->{option_results}->{username} // ''; + $self->{password} = $self->{option_results}->{password} // ''; + $self->{cacert} = $self->{option_results}->{cacert} // ''; + $self->{cert} = $self->{option_results}->{cert} // ''; + $self->{key} = $self->{option_results}->{key} // ''; $self->{sentinel} = []; if (defined($self->{option_results}->{sentinel})) { foreach my $addr (@{$self->{option_results}->{sentinel}}) { @@ -92,9 +99,12 @@ sub check_options { $self->{output}->add_option_msg(short_msg => 'Need to specify --service option.'); $self->{output}->option_exit(); } - if ($self->{username} ne '') { - $self->{output}->add_option_msg(short_msg => 'Unsupported --username option.'); - $self->{output}->option_exit(); + + foreach (qw/username cert key/) { + if ($self->{$_} ne '') { + $self->{output}->add_option_msg(short_msg => "Unsupported --$_ option."); + $self->{output}->option_exit(); + } } return 0; @@ -144,11 +154,11 @@ __END__ =head1 NAME -REDIS perlmod +REDIS Perl mode =head1 SYNOPSIS -Redis perlmod +Redis Perl mode =head1 REDIS OPTIONS diff --git a/tests/centreon/plugins/apps_redis_sentinel_parameters.t b/tests/centreon/plugins/apps_redis_sentinel_parameters.t new file mode 100644 index 000000000..b1a4512a3 --- /dev/null +++ b/tests/centreon/plugins/apps_redis_sentinel_parameters.t @@ -0,0 +1,59 @@ +use strict; +use warnings; + +package MockOptions; +sub new { bless { extra_arguments => [ ], option_results => {}, default => {}, custom => {} }, shift } +sub add_options { } +sub add_help { } + +package MockOutput; +sub new { bless {}, shift } +sub add_option_msg { } +sub output_add { } +sub option_exit { } + +package main; + +# Unit tests to check that the plugin constructs a valid redis-cli command with the corresponding parameters + +use Test2::V0; +use FindBin; +use lib "$FindBin::RealBin/../../../src"; +use apps::redis::sentinel::mode::listclusters; +use apps::redis::sentinel::custom::cli; + +my $capture; +my $options = MockOptions->new(); +my $output = MockOutput->new(); + +my $plugin_misc = mock 'centreon::plugins::misc'; + +$plugin_misc->override('execute' => sub { + my (%options) = @_; + $capture = "$options{command} $options{command_options}"; +}); + +my $plugin = apps::redis::sentinel::mode::listclusters->new( + options => $options, + output => $output, +); +$plugin->init(%$options); + +my $cust = apps::redis::sentinel::custom::cli->new( + options => $options, + output => $output, +); +$options->{custom} = $cust; + +foreach my $test ({ title => 'Test --key parameter', param => { key => 'private.key'}, expect => q(--key 'private.key') }, + { title => 'Test --cert parameter', param => { cert => 'dummy.crt'}, expect => q(--cert 'dummy.crt') }, + { title => 'Test --cacert parameter', param => { cacert => 'ca.crt'}, expect => q(--cacert 'ca.crt') },) { + $cust->set_options(option_results => $test->{param} ); + $cust->check_options(); + + $plugin->manage_selection(%$options); + + ok($capture =~ /$test->{expect}/, "$test->{title}"); +} + +done_testing; diff --git a/tests/centreon/plugins/database_redis_parameters.t b/tests/centreon/plugins/database_redis_parameters.t new file mode 100644 index 000000000..a26ff8942 --- /dev/null +++ b/tests/centreon/plugins/database_redis_parameters.t @@ -0,0 +1,61 @@ +use strict; +use warnings; + +package MockOptions; +sub new { bless { extra_arguments => [ ], option_results => {}, default => {}, custom => {} }, shift } +sub add_options { } +sub add_help { } + +package MockOutput; +sub new { bless {}, shift } +sub add_option_msg { } +sub output_add { } +sub use_new_perfdata { } +sub option_exit { } + +package main; + +# Unit tests to check that the plugin constructs a valid redis-cli command with the corresponding parameters + +use Test2::V0; +use FindBin; +use lib "$FindBin::RealBin/../../../src"; +use database::redis::mode::commands; +use database::redis::custom::cli; + +my $capture; +my $options = MockOptions->new(); +my $output = MockOutput->new(); + +my $plugin_misc = mock 'centreon::plugins::misc'; + +$plugin_misc->override('execute' => sub { + my (%options) = @_; + $capture = "$options{command} $options{command_options}"; +}); + +my $plugin = database::redis::mode::commands->new( + options => $options, + output => $output, + mode => 'commands', +); +$plugin->init(%$options); + +my $cust = database::redis::custom::cli->new( + options => $options, + output => $output, +); +$options->{custom} = $cust; + +foreach my $test ({ title => 'Test --key parameter', param => { key => 'private.key'}, expect => q(--key 'private.key') }, + { title => 'Test --cert parameter', param => { cert => 'dummy.crt'}, expect => q(--cert 'dummy.crt') }, + { title => 'Test --cacert parameter', param => { cacert => 'ca.crt'}, expect => q(--cacert 'ca.crt') },) { + $cust->set_options(option_results => $test->{param} ); + $cust->check_options(); + + $plugin->manage_selection(%$options); + + ok($capture =~ /$test->{expect}/, "$test->{title}"); +} + +done_testing; diff --git a/tests/resources/spellcheck/stopwords.txt b/tests/resources/spellcheck/stopwords.txt index 7282b39e4..c0b1cfbc8 100644 --- a/tests/resources/spellcheck/stopwords.txt +++ b/tests/resources/spellcheck/stopwords.txt @@ -254,6 +254,7 @@ ReplicaJobSession RestAPI RFC1628 RRDCached +redis-cli rsrp rsrq rssi @@ -294,6 +295,7 @@ Teldat temperatureambient timeframe TiMOS +TLS TMM tmnxSasAlarmInputDescription topic-messages-inflighted