#!/usr/bin/perl -w # # mergecfg v0.11 -- # Merge Nagios object definitions into templates # # Copyright (C) 2003,2004 by Kenytt Avery, Willing Minds LLC # (kavery@willingminds.com) # # Willing Minds LLC # System and Network Infrastructure Experts # 4095 E. La Palma Ave, Ste J # Anaheim, CA 92807-1704 # # +1 949 623 9854 # # http://www.willingminds.com/ # # Nagios is a registered trademark of Ethan Galstad. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # Merges object definitions with duplicate attributes such as # # define host { # host_name web1 # alias Web1 External Web Server # address 192.168.1.1 # max_check_attempts 10 # notification_interval 120 # notification_options d,u,r # notification_period 24x7 # notifications_enabled 1 # event_handler_enabled 1 # flap_detection_enabled 1 # process_perf_data 1 # retain_status_information 1 # retain_nonstatus_information 1 # } # # define host { # host_name web2 # alias Web2 External Web Server # address 192.168.1.2 # max_check_attempts 10 # notification_interval 120 # notification_options d,u,r # notification_period 24x7 # notifications_enabled 1 # event_handler_enabled 1 # flap_detection_enabled 1 # process_perf_data 1 # retain_status_information 1 # retain_nonstatus_information 1 # } # # into templates and abbreviated object definitions such as # # define host { # name template.host.1 # register 0 # # max_check_attempts 10 # notification_interval 120 # notification_options d,u,r # notification_period 24x7 # notifications_enabled 1 # event_handler_enabled 1 # flap_detection_enabled 1 # process_perf_data 1 # retain_status_information 1 # retain_nonstatus_information 1 # } # # define host { # use template.host.1 # # host_name web1 # alias Web1 External Web Server # address 192.168.1.1 # } # # define host { # use template.host.1 # # host_name web2 # alias Web2 External Web Server # address 192.168.1.2 # } # # The program currently merges services.cfg, hosts.cfg, and contacts.cfg. # # Add list-valued attributes to LISTVALS to merge other object definitions. # use strict; use File::Basename; use constant LISTVALS => qw( contact_name host_name alias address email pager ); sub listval { return grep { $_ eq $_[0] } LISTVALS; } sub similar_objects { my $o1 = shift; my $o2 = shift; my $match = 1; for my $var (keys %{$o1}) { next if listval $var; if (not exists $o2->{$var} or $o1->{$var} ne $o2->{$var}) { $match = 0; last; } } return $match; } if (@ARGV == 0 or @ARGV > 1) { print STDERR < Object definitions currently supported are hosts, services, and contacts. EOF exit 0; } my $objects; my $buffer; while (<>) { s/#.*//; s/;.*//; s/^\s+//; s/\s+$//; next unless length; $buffer .= "$_\n"; } my $type; while ($buffer =~ /define\s+(\w+)\s*{(.*?)}/gs) { $type = $1; my $definition = $2; my $object; while ($definition =~ /\s*(\w+)\s+(.*)/g) { my $var = $1; my $value = $2; if (listval $var) { push(@{$object->{$var}}, $value); } else { $object->{$var} = $value; } } push(@{$objects}, $object); } my $n = 1; while (my $a = shift @{$objects}) { next if exists $a->{MERGED}; for my $b (@{$objects}) { next if exists $b->{MERGED}; if (similar_objects($a, $b)) { for my $var (LISTVALS) { push(@{$a->{$var}}, @{$b->{$var}}) if exists $a->{$var}; } $b->{MERGED} = 1; } } my $templatize = 0; for my $var (keys %{$a}) { if (ref $a->{$var} eq 'ARRAY') { $templatize = (@{$a->{$var}} > 1); last; } } if ($templatize) { my $template = (exists $a->{name})? $a->{name} : "template.$type." . $n++; print "define $type {\n"; print "\tname\t$template\n"; print "\tregister\t0\n\n"; for my $var (sort keys %{$a}) { unless (listval $var) { print "\t$var\t$a->{$var}\n" unless $var eq 'name' or $var eq 'register'; delete $a->{$var}; } } print "}\n\n"; my $obj; LOOP: for (;;) { keys %{$a} or last LOOP; for my $var (keys %{$a}) { my $value = shift @{$a->{$var}} or last LOOP; $obj->{$var} = $value; } print "define $type {\n"; print "\tuse\t$template\n\n"; for my $var (sort keys %{$obj}) { print "\t$var\t$obj->{$var}\n"; } print "}\n\n"; } } else { print "define $type {\n"; for my $var (sort keys %{$a}) { if (ref $a->{$var} eq 'ARRAY') { print "\t$var\t", join(', ', @{$a->{$var}}), "\n"; } else { print "\t$var\t$a->{$var}\n"; } } print "}\n\n"; } }