Skip to content

Commit

Permalink
agents: implement combined matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
sni committed Feb 26, 2025
1 parent 83a1e8e commit 1703079
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 3 deletions.
10 changes: 8 additions & 2 deletions docs/documentation/plugins/agents/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,22 @@ tags = tag2
# multiple tags (AND)
# matches only if all given tags exist
tags = tag1 & tag2
tags = tag1 && tag2
...................................

#### Excludes

...................................
# exclude something
# exclude pattern start with a '!'
# this matches all hosts except localhost
host = ANY
host = !localhost
...................................

...................................
# this matches all hosts which have tag1 but must not have tag2
tags = tag1 & !tag2
tags = tag1 && !tag2
...................................

### Configuration
Expand Down
50 changes: 50 additions & 0 deletions plugins/plugins-available/agents/lib/Thruk/Utils/Agents.pm
Original file line number Diff line number Diff line change
Expand Up @@ -604,11 +604,61 @@ sub check_wildcard_match {
return(undef);
}
$str = Thruk::Base::list($str);

# check excludes first
for my $p (@{$pattern}) {
next unless $p =~ m/^\!/mx;
$p = "$p";
$p =~ s=^\!==mx;
for my $s (@{$str}) {
return if _check_pattern($s, $p);
}
}

for my $p (@{$pattern}) {
next if $p =~ m/^\!/mx;
return $p if $p eq 'ANY';
return $p if $p eq 'ANY';
return $p if $p eq '*';
return $p if $p eq '.*';

my @sub_pattern = split/\s*\&\&\s*/mx, $p;
if(scalar @sub_pattern > 1) {
# all must match
my $total = 1;
for my $sp (@sub_pattern) {
my $res;
# negated filter, none must match
if($sp =~ m/^\!/mx) {
$res = 1;
$sp =~ s/^\!//mx;
for my $s (@{$str}) {
if(_check_pattern($s, $sp)) {
$res = 0;
last;
}
}
}

# normal filter, any must match
else {
$res = 0;
for my $s (@{$str}) {
if(_check_pattern($s, $sp)) {
$res = 1;
last;
}
}
}
if(!$res) {
$total = 0;
last;
}
}
return $p if $total;
next;
}

for my $s (@{$str}) {
return $p if _check_pattern($s, $p);
}
Expand Down
96 changes: 95 additions & 1 deletion plugins/plugins-available/agents/t/utils_agents.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use Thruk::Config 'noautoload';
BEGIN {
plan skip_all => 'test skipped' if defined $ENV{'NO_DISABLED_PLUGINS_TEST'};

plan tests => 14;
plan tests => 24;
}

BEGIN {
Expand Down Expand Up @@ -147,3 +147,97 @@ EOT
}

###########################################################
# excludes
{
my $conf = <<EOT;
<Component Thruk::Agents>
<snclient>
<extra_host_opts>
host = ANY
host = !localhost
service = ANY
section = ANY
tags = ANY
first_notification_delay = 30
</extra_host_opts>
</snclient>
</Component>
EOT

my $xtr = Thruk::Config::parse_config_from_text($conf);
$c->config->{'Thruk::Agents'} = $xtr->{'Thruk::Agents'};

my $opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "localhost", "", []);
ok(scalar @{$opts} == 0, "excludes match");

$opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "local", "", []);
ok($opts->[0]->{'first_notification_delay'} == 30, "excludes match II");
}

###########################################################
# combined matches
{
my $conf = <<EOT;
<Component Thruk::Agents>
<snclient>
<extra_host_opts>
host = ANY
service = ANY
section = ANY
tags = tag1 && tag2
first_notification_delay = 30
</extra_host_opts>
</snclient>
</Component>
EOT

my $xtr = Thruk::Config::parse_config_from_text($conf);
$c->config->{'Thruk::Agents'} = $xtr->{'Thruk::Agents'};

my $opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "localhost", "", []);
ok(scalar @{$opts} == 0, "combined match");

$opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "localhost", "", ["tag1"]);
ok(scalar @{$opts} == 0, "combined match II");

$opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "localhost", "", ["tag2"]);
ok(scalar @{$opts} == 0, "combined match III");

$opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "localhost", "", ["tag1", "tag2", "tag3"]);
ok($opts->[0]->{'first_notification_delay'} == 30, "combined match IV");
}

###########################################################
# combined exclude matches
{
my $conf = <<EOT;
<Component Thruk::Agents>
<snclient>
<extra_host_opts>
host = ANY
service = ANY
section = ANY
tags = tag1 && !tag2
first_notification_delay = 30
</extra_host_opts>
</snclient>
</Component>
EOT

my $xtr = Thruk::Config::parse_config_from_text($conf);
$c->config->{'Thruk::Agents'} = $xtr->{'Thruk::Agents'};

my $opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "localhost", "", []);
ok(scalar @{$opts} == 0, "combined exclude match");

$opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "localhost", "", ["tag1"]);
ok($opts->[0]->{'first_notification_delay'} == 30, "combined exclude match II");

$opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "localhost", "", ["tag2"]);
ok(scalar @{$opts} == 0, "combined exclude match III");

$opts = Thruk::Agents::SNClient::_get_extra_opts_hst($c, "localhost", "", ["tag1", "tag2", "tag3"]);
ok(scalar @{$opts} == 0, "combined exclude match IV");
}

###########################################################

0 comments on commit 1703079

Please sign in to comment.