Skip to content

Commit

Permalink
Implement additive inheritance. Fix a bug in multiple inheritance imp…
Browse files Browse the repository at this point in the history
…lementation.

* lib/Nagios/Object.pm (_set): Register additive attributes in
the {_additive} hash.
(_make_method) <get>: Implement additive inheritance.
* t/additive_inheritance.cfg: New test config.
* t/additive_inheritance.t: New testcase.

* lib/Nagios/Template.pm (AUTOLOAD): Don't croak on undefined,
but valid attributes.  Return undef as expected.

* t/multipletemplates.cfg: Add a sample of multiple additive
inheritance.
* t/multipletemplates.t: Check for the proper return of undefined
attribute and for working multiple additive inheritance.
  • Loading branch information
graygnuorg committed Sep 17, 2020
1 parent e067fa9 commit bf5de4d
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 5 deletions.
25 changes: 20 additions & 5 deletions lib/Nagios/Object.pm
Expand Up @@ -855,10 +855,13 @@ sub _set ($ $ $) {
$self->_validate( $key, $value, @{ $vf->{$key} } );
}

# Nagios allows the usage of a '+' sign. This breaks member lists.
# Ignore the '+' sign completely for now.
# Nagios allows the usage of a '+' sign, meaning additive inheritance.
# Strip it off lest it breaks member lists, and store the attribute in
# _additive hash for eventual use in the "get" accessor (created in the
# _make_method below).
if ( ref $vf->{$key}[0] eq 'ARRAY' && $value =~/^\+(.+)$/ ) {
$value = $1;
$self->{_additive}{$key} = 1;
}

if ( ref $vf->{$key}[0] eq 'ARRAY' && $value =~ /,/ ) {
Expand Down Expand Up @@ -1064,20 +1067,32 @@ GENESIS: {
my $self = shift;
my $value = $self->{$method};

if ( defined $value || $method eq 'use' ) {
if ( $method eq 'use' ) {
return $value
}
if ( defined $value && !$self->{_additive}{$method} ) {
return $value;
}
else {
my $template = $self->template;
if ( $template && $template->can($method) ) {
return $template->$method;
return _append($template->$method, $value);
}
}
return undef;
return $value;
}; # end of anonymous "get" subroutine
}
}

sub _append {
my ($a, $b) = @_;
return $b unless defined $a;
return $a unless defined $b;
$a = [ $a ] unless ref($a) eq 'ARRAY';
$b = [ $b ] unless ref($b) eq 'ARRAY';
[ @$a, @$b ]
}

sub DESTROY { }

sub AUTOLOAD {
Expand Down
3 changes: 3 additions & 0 deletions lib/Nagios/Template.pm
Expand Up @@ -28,13 +28,16 @@ sub AUTOLOAD {
my $self = shift;
$AUTOLOAD =~ s/(?:(.*)::)?(.+)//;
my ($p, $m) = ($1, $2);
my $has_attr;
foreach my $obj ($self->objects) {
if ($obj->can($m)) {
$has_attr = 1;
if (defined(my $v = $obj->${\$m}(@_))) {
return $v;
}
}
}
return if $has_attr;
croak "Can't locate object method \"$m\" via package \"$p\"";
}

Expand Down
17 changes: 17 additions & 0 deletions t/additive_inheritance.cfg
@@ -0,0 +1,17 @@
# An example of additive inheritance from
# https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/3/en/objectinheritance.html#add_string
#
define host {
name generichosttemplate
hostgroups all-servers
register 0
}

define host {
host_name linuxserver1
hostgroups +linux-servers,web-servers
use generichosttemplate
}

# The effective value of hostgroups in linuxserver1 is
# all-servers,linux-servers,web-servers
21 changes: 21 additions & 0 deletions t/additive_inheritance.t
@@ -0,0 +1,21 @@
#!/usr/bin/perl -w

use strict;
use Test::More qw(no_plan);
use Test::NoWarnings;
use lib qw( ../lib ./lib );
use Data::Dumper;

$Data::Dumper::Terse = 1;
$Data::Dumper::Indent = 0;

eval { chdir('t') };

use Nagios::Config;

my $config = Nagios::Object::Config->new();
$config->parse('additive_inheritance.cfg');

my $host = $config->find_object('linuxserver1','Nagios::Host');
is(Dumper([$host->hostgroups]),q{[['all-servers','linux-servers','web-servers']]});

27 changes: 27 additions & 0 deletions t/multipletemplates.cfg
Expand Up @@ -23,3 +23,30 @@ define host {
host_name devweb1
}

#
# A combination of multiple template and additive inheritance.
#
define host {
name generichosttemplate
hostgroups all-servers
register 0
}

define host {
name template1
hostgroups +linux-servers,web-servers
use generichosttemplate
}

define host {
name template2
hostgroups another
}

define host {
host_name linuxserver2
use template1,template2
hostgroups +one
}


5 changes: 5 additions & 0 deletions t/multipletemplates.t
Expand Up @@ -23,3 +23,8 @@ is($host->active_checks_enabled, 1, 'attribute defined in first parent template'
is(Dumper([$host->notification_options]), q{[['d','u','r']]},
'attribute defined in second parent template');

$host = $config->find_object('linuxserver2','Nagios::Host');
is(Dumper([$host->hostgroups]), q{[['all-servers','linux-servers','web-servers','one']]},
'multiple additive inheritance');

is($host->alias, undef, 'undefined attribute');

0 comments on commit bf5de4d

Please sign in to comment.