# MonArch - Groundwork Monitor Architect
# MonarchLoad.pm
#
############################################################################
# Release 4.0
# December 2011
############################################################################
#
# Original author: Scott Parris
#
# Copyright 2007-2011 GroundWork Open Source, Inc. (GroundWork)
# All rights reserved. This program is free software; you can redistribute
# it and/or modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
use strict;
use MonarchStorProc;
package Load;
my $debug = 0;
my $gw4 = 0;
my @messages = ();
my $xml_begin = "\n\n";
my $xml_end = "";
sub update_status(@) {
my $type = $_[0];
my $message = $_[1];
my $dt = StorProc->datetime();
my $message_str = "$dt~~$type~~$message";
if ($debug) { print "\n$message_str\n" }
push @messages, $message_str;
}
#
############################################################################
# stage load
#
# FIX THIS: should we also pass in the purge_escalation flag, here or elsewhere?
sub stage_load(@) {
my $nagios_home = $_[1];
my $action_type = $_[2]; # only used for Nagios 3.x import: update|purge_all|purge_all_and_import_3x|purge_nice
my $precached_file = $_[3];
my $index = 0;
my $use_regex = 0;
my $result;
update_status( 'start', "Import process begins" );
my %objects = ();
update_status( 'info', "Reading: $nagios_home/nagios.cfg" );
my @files = ();
my @dirs = ();
my @resource_files = ();
if ( !open( FILE, '<', "$nagios_home/nagios.cfg" ) ) {
update_status( 'error', "error: cannot open $nagios_home/nagios.cfg to read ($!)" );
}
else {
while ( my $line = ) {
if ( $line =~ /^\s*cfg_file\s*=\s*(.*\.cfg)\s*$/ ) { push @files, $1 }
if ( $line =~ /^\s*cfg_dir\s*=\s*(\S+)\s*$/ ) { push @dirs, $1 }
if ( $line =~ /^\s*resource_file\s*=\s*(\S+)\s*$/ ) {
push @resource_files, $1;
}
if ( $line =~ /^\s*use_regexp_matching\s*=\s*1\s*$/ ) { $use_regex = 1 }
}
close(FILE);
}
foreach my $dir (@dirs) {
if ( !opendir( DIR, $dir ) ) {
update_status( 'error', "error: cannot open $dir to read ($!)" );
}
else {
while ( my $file = readdir(DIR) ) {
if ( $file =~ /^(\S+\.cfg)$/ ) {
my $cfg = $1;
push @files, "$dir/$cfg";
}
}
closedir(DIR);
}
}
update_status( 'info', "Reading: $nagios_home/cgi.cfg" );
if ( !open( FILE, '<', "$nagios_home/cgi.cfg" ) ) {
update_status( 'error', "error: cannot open $nagios_home/cgi.cfg to read ($!)" );
}
else {
while ( my $line = ) {
if ( $line =~ /^\s*cfg_file\s*=\s*(.+\.cfg)$/ ) {
push @files, $1;
}
}
close(FILE);
}
if ($use_regex) {
my @vals = ( 'use_regex', 'config', '1', '', '' );
$result = StorProc->insert_obj( 'stage_other', \@vals );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
}
my $doing_nagios_3_import = 0;
if ( $action_type eq 'purge_all_and_import_3x' ) {
$doing_nagios_3_import = 1;
if ( !$precached_file ) {
my %precached_file = StorProc->fetch_one( 'setup', 'name', 'precached_object_file' );
$precached_file = $precached_file{'value'};
}
unshift( @files, $precached_file );
}
foreach my $file (@files) {
my $host_file = 0;
my $service_file = 0;
my $added = 0;
my $rejected = 0;
next if ( $file =~ /nagios.cfg|resource.cfg|perfparse.cfg|cgi.cfg/i );
my @properties = ();
if ( !open( CFG, '<', $file ) ) {
update_status( 'error', "error: cannot open $file to read ($!)" );
}
else {
while ( my $line = ) {
next if ( $line =~ /#\s*GROUNDWORK#|^#\s*GW|^\s*;/ );
$line =~ s/\t+/ /g;
$line =~ s/^\s+|\s+$//g;
# If at end of a definition -- all lines up to this one in the definition are in @properties.
# For easy editing, we balance { the extra brace just below.
if ( $line !~ /^}/ ) {
push @properties, $line;
}
else {
## each time through, do one definition
my @comment = ();
my %element = ();
$element{'data'} = $xml_begin;
foreach my $prop (@properties) {
## each line is part of a single definition, the current one
if ( $prop =~ /^define\s+(\S+)\s*\{/i ) {
$element{'type'} = $1;
}
## For easy editing, we balance } the extra brace just above.
elsif ( $prop =~ /register\s+0/i ) {
$element{'type'} .= '_template';
}
elsif ( $prop =~ /register\s+1/i ) {
next;
}
elsif ( $prop =~ /^\#/ ) {
push @comment, "$prop\n";
}
elsif ( $prop =~ /\s*(.*?)\s+(\d\d:\d\d-\d\d:\d\d.*)/ ) {
my ( $name, $value ) = ( $1, $2 );
$name =~ s/\s+/ /g;
$value =~ s/\s+$//;
$value =~ s/\s*([;#])\s*/$1/;
$value =~ s/^([^;#]+)\s+([^;#]*)([;#])/$1$2$3/g;
$element{$name} = $value;
}
elsif ( $prop =~ /\s*exclude\s+(.*)/ ) {
$element{'exclude'} = $1;
}
elsif ( $prop =~ /(\S+)\s+(\S+.*?)(?\n";
$element{'data'} .= " \n";
}
$element{'parent'} ||= $element{'name'};
$element{'data'} .= $xml_end;
(my $comment = pop @comment) =~ s/\s+$//;
unless ( $objects{"$element{'name'},$element{'type'},$element{'parent'}"} ) {
$element{'name'} ||= 1;
my @values = ( $element{'name'}, $element{'type'}, $element{'parent'}, $element{'data'}, $comment );
$result = StorProc->insert_obj( 'stage_other', \@values );
if ( $result =~ /error/i ) {
update_status( 'error', "Error: $file ($result)" );
$rejected++;
}
else {
## FIX THIS: what is this for?
## push object only if
## 1) we are not doing 3.x import OR
## 2) we are doing a precached file OR
## 3) we are doing a template object
if ( !$doing_nagios_3_import || $file eq $precached_file || $element{'type'} =~ /_template$/ ) {
$objects{"$element{'name'},$element{'type'},$element{'parent'}"} = 1;
## FIX THIS: is this in the wrong place?
$added++;
}
}
}
@properties = ();
}
}
close(CFG);
update_status( 'info',
"File $file: $added object"
. ( $added == 1 ? '' : 's' )
. " staged; $rejected object"
. ( $rejected == 1 ? '' : 's' )
. ' rejected.' );
}
}
foreach my $resource_file (@resource_files) {
update_status( 'info', "Reading: $resource_file" );
if ( !open( FILE, '<', $resource_file ) ) {
update_status( 'error', "error: cannot open $resource_file to read ($!)" );
}
else {
while ( my $line = ) {
if ( $line =~ /\$USER(\d+)\$=(\S+)\s*$/ ) {
if ( $1 >= 1 && $1 <= 32 ) {
my %w = ( 'name' => "user$1" );
my %u = ( 'value' => $2 );
StorProc->update_obj_where( 'setup', \%u, \%w );
}
}
}
close(FILE);
}
}
update_status( 'end', 'Stage load completed.' );
return @messages;
}
############################################################################
######
###### Break
######
############################################################################
# commands
sub process_commands() {
my $read = 0;
my $updated = 0;
my $imported = 0;
my $result;
update_status( 'start', "Processing." );
my %command_name = StorProc->get_table_objects('commands');
update_status( 'info', 'Loading commands ...' );
my %where = ( 'type' => 'command' );
my %objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
my $cmdtype = 'check';
if ( $data{'command_line'} =~ /\$CONTACTEMAIL\$|\$NOTIFICATIONTYPE\$|\$CONTACTPAGER\$/ ) {
$cmdtype = 'notify';
}
elsif ( $data{'command_line'} =~ /\$PERFDATA\$|perfdata|performance/i ) {
$cmdtype = 'other';
}
my $data = $xml_begin;
$data .= " \n";
$data .= " \n";
$data .= $xml_end;
if ( $command_name{ $objects{$key}[0] } ) {
my %values = ();
$values{'type'} = $cmdtype;
$values{'data'} = $data;
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'commands', 'name', $objects{$key}[0], \%values );
$updated++;
}
else {
my @values = ( \undef, $objects{$key}[0], $cmdtype, $data, $objects{$key}[4] );
$result = StorProc->insert_obj_id( 'commands', \@values, 'command_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$command_name{ $objects{$key}[0] } = $result;
$imported++;
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Commands: $read read, $updated updated, imported $imported." );
return @messages;
}
############################################################################
######
###### Break
######
############################################################################
# process_timeperiods
# FIX THIS: It makes no sense to truncate the various time tables unless we know
# we are purging instead of merging. And if we are merging, we cannot truncate
# the time_periods table, and we must only selectively delete just those rows
# from the time_period_property and time_period_exclude tables that correspond
# to the specific time periods we are updating in the time_periods table.
# FIX THIS: if we do truncate these tables, what will be the effect on other
# tables that reference these time periods, that have already been populated
# during the loading process? are such cross-references even constructed
# during a load operation? or are all tables that might refer to time periods
# deliberately handled after the time period tables are constructed?
sub process_timeperiods() {
my $read = 0;
my $updated = 0;
my $imported = 0;
my $errors = 0;
my %tp_exclude = ();
my $result;
StorProc->truncate_table('time_periods', 'time_period_property', 'time_period_exclude');
# Note that we won't get get anything back if we just truncated the time_periods table.
my %timeperiod_id = StorProc->get_table_objects('time_periods');
update_status( 'info', 'Loading timeperiods ...' );
my %where = ( 'type' => 'timeperiod' );
my %objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
$read++;
my $tp_name = $objects{$key}[0];
# Clean up the comment field. FIX THIS: It should really be done uniformly for all objects.
$objects{$key}[4] =~ s/^# //;
$objects{$key}[4] =~ s/^\s+|\s+$//g;
if ( $timeperiod_id{$tp_name} ) {
my %values = ();
$values{'alias'} = $objects{$key}[2];
$values{'comment'} = $objects{$key}[4] if $objects{$key}[4];
$result = StorProc->update_obj( 'time_periods', 'name', $tp_name, \%values );
if ( $result =~ /error/i ) {
update_status( 'error', $result . " (time period \"$tp_name\")" );
++$errors;
}
else {
$updated++;
}
}
else {
my @values = ( \undef, $tp_name, $objects{$key}[2], $objects{$key}[4] );
$result = StorProc->insert_obj_id( 'time_periods', \@values, 'timeperiod_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result . " (time period \"$tp_name\")" );
delete $timeperiod_id{$tp_name};
++$errors;
}
else {
$timeperiod_id{$tp_name} = $result;
$imported++;
}
}
if ( $timeperiod_id{$tp_name} ) {
## FIX MINOR: If we don't truncate the various time tables above, we must delete
## right here all the rows in both time_period_property and time_period_exclude
## that have a timeperiod_id of $timeperiod_id{$tp_name}, before we go adding
## new rows in time_period_property for this timeperiod.
my %data_values = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data_values{'error'} ) if defined $data_values{'error'};
$tp_exclude{$tp_name} = $data_values{'exclude'};
# Note: In the future, we might also want to add code here to
# also process "use" and "require" directives for time periods.
delete $data_values{'exclude'};
delete $data_values{'use'};
delete $data_values{'require'};
foreach my $dayrule ( keys %data_values ) {
my @values = ();
$values[0] = $timeperiod_id{$tp_name};
$values[1] = $dayrule;
$values[2] = 'exception';
$values[2] = 'weekday' if $dayrule =~ /^\S+day$/;
if ( $data_values{$dayrule} =~ /(.*?)[;#](.*)/ ) {
$values[3] = $1;
$values[4] = $2;
}
else {
$values[3] = $data_values{$dayrule};
$values[4] = '';
}
$result = StorProc->insert_obj( 'time_period_property', \@values );
if ( $result =~ /error/i ) {
update_status( 'error', $result . " (time period \"$tp_name\")" );
++$errors;
}
}
}
}
# Process all exclude insertions now, here at the end. We cannot do this in the earlier loop,
# because back then we may not yet know all the timeperiod_id values we will want to reference here.
foreach my $tp_name ( keys %tp_exclude ) {
my @elist = split( /,/, $tp_exclude{$tp_name} );
foreach my $excluded_tp_name (@elist) {
if ( $timeperiod_id{$excluded_tp_name} ) {
my @values = ( $timeperiod_id{$tp_name}, $timeperiod_id{$excluded_tp_name} );
$result = StorProc->insert_obj( 'time_period_exclude', \@values );
if ( $result =~ /error/i ) {
update_status( 'error', $result . " (time period \"$tp_name\")" );
++$errors;
}
}
else {
update_status( 'error', "Error: time period \"$tp_name\" exclusion of time period \"$excluded_tp_name\" has not been saved." );
++$errors;
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info',
"Time periods: $read read, $updated updated, $imported imported"
. ( $errors == 0 ? '' : ", $errors error" . ( $errors == 1 ? '' : 's' ) )
. '.' );
return @messages;
}
############################################################################
######
###### Break
######
############################################################################
# process_contacts
sub process_contacts() {
my $read = 0;
my $updated = 0;
my $imported = 0;
my %command_name = StorProc->get_table_objects('commands');
my %timeperiod_name = StorProc->get_table_objects('time_periods');
my %contact_name = StorProc->get_table_objects('contacts');
my %contactgroup_name = StorProc->get_table_objects('contactgroups');
my %contact_templates = StorProc->get_contact_templates();
my $result;
update_status( 'info', 'Loading contact templates ...' );
my %where = ( 'type' => 'contact_template' );
my %objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
my %contact_use = ();
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
my $data_xml = $xml_begin;
if ( $data{'use'} ) { $contact_use{ $objects{$key}[0] } = $data{'use'} }
$contact_templates{ $objects{$key}[0] }{'host_notification_options'} = $data{'host_notification_options'};
$data_xml .= " \n";
$data_xml .= " \n";
$contact_templates{ $objects{$key}[0] }{'service_notification_options'} = $data{'service_notification_options'};
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= $xml_end;
$contact_templates{ $objects{$key}[0] }{'host_notification_period'} = $timeperiod_name{ $data{'host_notification_period'} };
$contact_templates{ $objects{$key}[0] }{'service_notification_period'} = $timeperiod_name{ $data{'service_notification_period'} };
if ( $contact_templates{ $objects{$key}[0] }{'id'} ) {
my %values = ();
$values{'data'} = $data_xml;
$values{'host_notification_period'} = $timeperiod_name{ $data{'host_notification_period'} };
$values{'service_notification_period'} = $timeperiod_name{ $data{'service_notification_period'} };
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'contact_templates', 'name', $objects{$key}[0], \%values );
$updated++;
}
else {
my @values = (
\undef, $objects{$key}[0],
$contact_templates{ $objects{$key}[0] }{'host_notification_period'},
$contact_templates{ $objects{$key}[0] }{'service_notification_period'},
$data_xml, $objects{$key}[4]
);
$result = StorProc->insert_obj_id( 'contact_templates', \@values, 'contacttemplate_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$contact_templates{ $objects{$key}[0] }{'id'} = $result;
$imported++;
}
}
StorProc->delete_all( 'contact_command', 'contacttemplate_id', $contact_templates{ $objects{$key}[0] }{'id'} );
@{ $contact_templates{ $objects{$key}[0] }{'host_notification_commands'} } = ();
@{ $contact_templates{ $objects{$key}[0] }{'service_notification_commands'} } = ();
my @h = split( /,/, $data{'host_notification_commands'} );
foreach my $h (@h) {
$h =~ s/^\s+|\s+$//g;
if ( $command_name{$h} ) {
my @vals = ( $contact_templates{ $objects{$key}[0] }{'id'}, 'host', $command_name{$h} );
$result = StorProc->insert_obj( 'contact_command', \@vals );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
push @{ $contact_templates{ $objects{$key}[0] }{'host_notification_commands'} }, $command_name{$h};
}
}
my @s = split( /,/, $data{'service_notification_commands'} );
foreach my $s (@s) {
$s =~ s/^\s+|\s+$//g;
if ( $command_name{$s} ) {
my @vals = ( $contact_templates{ $objects{$key}[0] }{'id'}, 'service', $command_name{$s} );
$result = StorProc->insert_obj( 'contact_command', \@vals );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
push @{ $contact_templates{ $objects{$key}[0] }{'service_notification_commands'} }, $command_name{$s};
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
foreach my $temp ( keys %contact_use ) {
my %values = ();
foreach my $prop ( keys %{ $contact_templates{ $contact_use{$temp} } } ) {
unless ( $contact_templates{$temp}{$prop} || $prop =~ /command/ ) {
$values{$prop} = $contact_templates{ $contact_use{$temp} }{$prop};
}
}
if ( $values{'host_notification_options'} || $values{'service_notification_options'} ) {
$values{'data'} = $xml_begin;
if ( $values{'host_notification_options'} ) {
$values{'data'} .= " \n";
$values{'data'} .= " \n";
}
if ( $values{'service_notification_options'} ) {
$values{'data'} .= " \n";
$values{'data'} .= " \n";
}
$values{'data'} .= $xml_end;
delete $values{'host_notification_options'};
delete $values{'service_notification_options'};
}
StorProc->update_obj( 'contact_templates', 'name', $temp, \%values );
unless ( @{ $contact_templates{$temp}{'host_notification_commands'} } ) {
foreach my $cid ( @{ $contact_templates{ $contact_use{$temp} }{'host_notification_commands'} } ) {
my @vals = ( $contact_templates{$temp}{'id'}, 'host', $cid );
$result = StorProc->insert_obj( 'contact_command', \@vals );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
unless ( @{ $contact_templates{$temp}{'service_notification_commands'} } ) {
foreach my $cid ( @{ $contact_templates{ $contact_use{$temp} }{'service_notification_commands'} } ) {
my @vals = ( $contact_templates{$temp}{'id'}, 'service', $cid );
$result = StorProc->insert_obj( 'contact_command', \@vals );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
}
update_status( 'info', "Contact templates: $read read, $updated updated, $imported imported." );
# contacts
$read = $updated = $imported = 0;
update_status( 'info', 'Loading contacts ...' );
%where = ( 'type' => 'contact' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
my %contact_contactgroups = ();
my $index = 1;
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
my @h = split( /,/, $data{'host_notification_commands'} );
my %h_commands = ();
foreach my $h (@h) {
$h =~ s/^\s+|\s+$//g;
$h_commands{$h} = $command_name{$h};
}
my @s = split( /,/, $data{'service_notification_commands'} );
my %s_commands = ();
foreach my $s (@s) {
$s =~ s/^\s+|\s+$//g;
$s_commands{$s} = $command_name{$s};
}
unless ( $data{'use'} ) {
$read++;
update_status( 'note', "Contact $objects{$key}[0] does not use a template." );
my $bestmatch = 0;
my %w = ();
foreach my $temp ( keys %contact_templates ) {
my $gotmatch = 0;
foreach my $tc ( @{ $contact_templates{$temp}{'host_notification_commands'} } ) {
foreach my $key ( keys %h_commands ) {
if ( $h_commands{$key} eq $tc ) { $gotmatch++ }
}
}
foreach my $tc ( @{ $contact_templates{$temp}{'service_notification_commands'} } ) {
foreach my $key ( keys %s_commands ) {
if ( $s_commands{$key} eq $tc ) { $gotmatch++ }
}
}
if ( $timeperiod_name{ $data{'host_notification_period'} } eq $contact_templates{$temp}{'host_notification_period'} ) {
$gotmatch++;
}
if ( $timeperiod_name{ $data{'service_notification_period'} } eq $contact_templates{$temp}{'service_notification_period'} ) {
$gotmatch++;
}
my %t = ();
my @sort = split( /,/, $data{'host_notification_options'} );
@sort = sort @sort;
my $sorted = undef;
foreach (@sort) { $sorted .= "$_," }
chop $sorted;
$data{'host_notification_options'} = $sorted;
@sort = split( /,/, $data{'service_notification_options'} );
@sort = sort @sort;
$sorted = undef;
foreach (@sort) { $sorted .= "$_," }
chop $sorted;
$data{'service_notification_options'} = $sorted;
@sort = split( /,/, $contact_templates{ $data{'use'} }{'host_notification_options'} );
@sort = sort @sort;
$sorted = undef;
foreach (@sort) { $sorted .= "$_," }
chop $sorted;
$t{'host_notification_period'} = $sorted;
@sort = split( /,/, $contact_templates{ $data{'use'} }{'service_notification_options'} );
@sort = sort @sort;
$sorted = undef;
foreach (@sort) { $sorted .= "$_," }
chop $sorted;
$t{'service_notification_period'} = $sorted;
if ( $data{'host_notification_options'} eq $t{'host_notification_options'} ) {
$gotmatch++;
}
if ( $data{'service_notification_options'} eq $t{'service_notification_options'} ) {
$gotmatch++;
}
if ( $gotmatch > $bestmatch ) {
$bestmatch = $gotmatch;
$data{'use'} = $temp;
}
}
if ( $data{'use'} ) {
update_status( 'action', "Assigned: Contact template $data{'use'} assigned to contact $objects{$key}[0]" );
}
}
unless ( $data{'use'} ) {
my $name = "generic-contact-$index";
my $data_xml = $xml_begin;
$contact_templates{$name}{'host_notification_options'} = $data{'host_notification_options'};
$data_xml .= " \n";
$data_xml .= " \n";
$contact_templates{$name}{'service_notification_options'} = $data{'service_notification_options'};
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= $xml_end;
$contact_templates{$name}{'host_notification_period'} = $timeperiod_name{ $data{'host_notification_period'} };
$contact_templates{$name}{'service_notification_period'} = $timeperiod_name{ $data{'service_notification_period'} };
my $comment = undef;
my @values = (
\undef, $name,
$timeperiod_name{ $data{'host_notification_period'} },
$timeperiod_name{ $data{'service_notification_period'} },
$data_xml, $comment
);
$result = StorProc->insert_obj_id( 'contact_templates', \@values, 'contacttemplate_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$contact_templates{$name}{'id'} = $result;
}
foreach my $key ( keys %h_commands ) {
if ( $command_name{$key} ) {
my @vals = ( $contact_templates{$name}{'id'}, 'host', $command_name{$key} );
$result = StorProc->insert_obj( 'contact_command', \@vals );
if ( $debug && $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
foreach my $key ( keys %s_commands ) {
if ( $command_name{$key} ) {
my @vals = ( $contact_templates{$name}{'id'}, 'service', $command_name{$key} );
$result = StorProc->insert_obj( 'contact_command', \@vals );
if ( $debug && $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
update_status( 'action', "Added: Contact template $name, assigned to contact $objects{$key}[0]" );
$data{'use'} = $name;
$index++;
}
if ( $contact_name{ $objects{$key}[0] } ) {
my %values = ();
$values{'alias'} = $objects{$key}[2];
$values{'email'} = $data{'email'};
$values{'pager'} = $data{'pager'};
$values{'contacttemplate_id'} = $contact_templates{ $data{'use'} }{'id'};
$values{'status'} = '1';
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'contacts', 'name', $objects{$key}[0], \%values );
$updated++;
}
else {
my @values = (
\undef, $objects{$key}[0], $objects{$key}[2], $data{'email'}, $data{'pager'}, $contact_templates{ $data{'use'} }{'id'},
'1', $objects{$key}[4]
);
$result = StorProc->insert_obj_id( 'contacts', \@values, 'contact_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$contact_name{ $objects{$key}[0] } = $result;
$imported++;
}
}
if ( $data{'contactgroups'} ) {
$contact_contactgroups{ $contact_name{ $objects{$key}[0] } } = $data{'contactgroups'};
}
# process overrides
StorProc->delete_all( 'contact_overrides', 'contact_id', $contact_name{ $objects{$key}[0] } );
StorProc->delete_all( 'contact_command_overrides', 'contact_id', $contact_name{ $objects{$key}[0] } );
my $match = 0;
my $i = 0;
foreach my $tc ( @{ $contact_templates{ $data{'use'} }{'host_notification_commands'} } ) {
$i++;
foreach my $key ( keys %h_commands ) {
unless ( $h_commands{$key} eq $tc ) { $match++ }
}
}
unless ( $i == $match ) {
foreach my $k ( keys %h_commands ) {
if ( $h_commands{$k} ) {
my @values = ( $contact_name{ $objects{$key}[0] }, 'host', $h_commands{$k} );
$result = StorProc->insert_obj( 'contact_command_overrides', \@values );
if ( $debug && $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
}
$match = 0;
$i = 0;
foreach my $tc ( @{ $contact_templates{ $data{'use'} }{'service_notification_commands'} } ) {
$i++;
foreach my $key ( keys %s_commands ) {
if ( $s_commands{$key} eq $tc ) { $match++ }
}
}
unless ( $i == $match ) {
foreach my $k ( keys %s_commands ) {
if ( $s_commands{$k} ) {
my @values = ( $contact_name{ $objects{$key}[0] }, 'service', $s_commands{$k} );
$result = StorProc->insert_obj( 'contact_command_overrides', \@values );
if ( $debug && $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
}
my %t = ();
my %overrides = ();
my @sort = split( /,/, $data{'host_notification_options'} );
@sort = sort @sort;
my $sorted = undef;
foreach (@sort) { $sorted .= "$_," }
chop $sorted;
$data{'host_notification_options'} = $sorted;
@sort = split( /,/, $data{'service_notification_options'} );
@sort = sort @sort;
$sorted = undef;
foreach (@sort) { $sorted .= "$_," }
chop $sorted;
$data{'service_notification_options'} = $sorted;
@sort =
split( /,/, $contact_templates{ $data{'use'} }{'host_notification_options'} );
@sort = sort @sort;
$sorted = undef;
foreach (@sort) { $sorted .= "$_," }
chop $sorted;
$t{'host_notification_period'} = $sorted;
@sort = split( /,/, $contact_templates{ $data{'use'} }{'service_notification_options'} );
@sort = sort @sort;
$sorted = undef;
foreach (@sort) { $sorted .= "$_," }
chop $sorted;
$t{'service_notification_period'} = $sorted;
unless ( $timeperiod_name{ $data{'host_notification_period'} } eq $contact_templates{ $data{'use'} }{'host_notification_period'} ) {
$overrides{'host_notification_period'} = $timeperiod_name{ $data{'host_notification_period'} };
}
unless ( $timeperiod_name{ $data{'service_notification_period'} } eq $contact_templates{ $data{'use'} }{'service_notification_period'} )
{
$overrides{'service_notification_period'} = $timeperiod_name{ $data{'service_notification_period'} };
}
unless ( $data{'host_notification_options'} eq $t{'host_notification_options'} ) {
$overrides{'host_notification_options'} = $data{'host_notification_options'};
}
unless ( $data{'service_notification_options'} eq $t{'service_notification_options'} ) {
$overrides{'service_notification_options'} = $data{'service_notification_options'};
}
my $data = undef;
foreach my $d ( keys %overrides ) {
if ( $d =~ /options/ ) {
$data .= " \n";
$data .= " \n";
}
}
if ($data) { $data = $xml_begin . $data . $xml_end }
if ( $data{'host_notification_options'}
|| $data{'service_notification_options'}
|| $overrides{'host_notification_period'}
|| $overrides{'service_notification_period'} )
{
my @values =
( $contact_name{ $objects{$key}[0] }, $overrides{'host_notification_period'}, $overrides{'service_notification_period'}, $data );
$result = StorProc->insert_obj( 'contact_overrides', \@values );
if ( $debug && $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Contacts: $read read, $updated updated, imported $imported." );
# contactgroups
$read = $updated = $imported = 0;
update_status( 'info', 'Loading contactgroups ...' );
%where = ( 'type' => 'contactgroup' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
$read++;
if ( $contactgroup_name{ $objects{$key}[0] } ) {
my %values = ();
$values{'alias'} = $objects{$key}[2];
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'contactgroups', 'name', $objects{$key}[0], \%values );
$updated++;
}
else {
my @values = ( \undef, $objects{$key}[0], $objects{$key}[2], $objects{$key}[4] );
$result = StorProc->insert_obj_id( 'contactgroups', \@values, 'contactgroup_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$contactgroup_name{ $objects{$key}[0] } = $result;
$imported++;
}
}
StorProc->delete_all( 'contactgroup_contact', 'contactgroup_id', $contactgroup_name{ $objects{$key}[0] } );
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
my %members = ();
my @mems = split( /,/, $data{'members'} );
foreach (@mems) { $members{$_} = 1 }
foreach my $mem ( keys %members ) {
$mem =~ s/^\s+|\s+$//g;
if ( $contact_name{$mem} ) {
my @vals = ( $contactgroup_name{ $objects{$key}[0] }, $contact_name{$mem} );
$result = StorProc->insert_obj( 'contactgroup_contact', \@vals );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
}
else {
update_status( 'info', "\"$mem\" is not a valid contact and so will be ignored." );
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
foreach my $cid ( keys %contact_contactgroups ) {
my @cgs = split( /,/, $contact_contactgroups{$cid} );
foreach my $cname (@cgs) {
my @vals = ( $contactgroup_name{$cname}, $cid );
$result = StorProc->insert_obj( 'contactgroup_contact', \@vals );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
}
}
update_status( 'info', "Contact groups: $read read, $updated updated, imported $imported." );
return @messages;
}
############################################################################
######
###### Break
######
############################################################################
# hosts
sub process_hosts() {
my $read = 0;
my $updated = 0;
my $imported = 0;
my $new = 0;
my %command_name = StorProc->get_table_objects('commands');
my %timeperiod_name = StorProc->get_table_objects('time_periods');
my %contact_name = StorProc->get_table_objects('contacts');
my %contactgroup_name = StorProc->get_table_objects('contactgroups');
my %service_name = StorProc->get_table_objects('service_names');
my %host_templates = StorProc->get_host_templates();
my %hostextinfo_templates = StorProc->get_hostextinfo_templates();
my %host_name = StorProc->get_table_objects('hosts');
my %hostgroup_name = StorProc->get_table_objects('hostgroups');
my $result;
# host templates
update_status( 'info', 'Loading host templates ...' );
my %host_template_name = ();
my %where = ( 'type' => 'host_template' );
my %template_parents = ();
my %template_hostgroups = ();
my %redundant_templates = ();
my %consolidate_templates = ();
my %objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
my $props = 0;
foreach ( keys %data ) { $props++ }
my $data_xml = undef;
if ( $data{'hostgroups'} ) {
$props -= 1;
$template_hostgroups{ $objects{$key}[0] } = $data{'hostgroups'};
update_status( 'note', "Hostgroup directive on host template $objects{$key}[0]." );
update_status( 'action',
"Hostgroup directive moved: Hostgroups $data{'hostgroups'} moved from host template $objects{$key}[0] to hosts." );
delete $data{'hostgroups'};
}
if ( $data{'parents'} ) {
$props -= 1;
$template_parents{ $objects{$key}[0] }{'parents'} = $data{'parents'};
update_status( 'note', "Parent directive on host template $objects{$key}[0]." );
update_status( 'action', "Parent directive moved: Parents $data{'parents'} moved from host template $objects{$key}[0] to hosts." );
delete $data{'parents'};
}
if ( $data{'use'} && $props == 1 ) {
$redundant_templates{ $objects{$key}[0] } = $data{'use'};
update_status( 'note',
"Redundant: Host template $objects{$key}[0] is redundant as it references $data{'use'} but has no properties itself." );
update_status( 'action',
"Staged for removal: Host template $objects{$key}[0]. Hosts using $objects{$key}[0] will be referenced to $data{'use'}." );
}
else {
if ( $data{'use'} ) {
$consolidate_templates{ $objects{$key}[0] } = $data{'use'};
update_status( 'note', "Host template $objects{$key}[0] is a host template that references a host template." );
update_status( 'warning',
"Reference removed: Host template $objects{$key}[0] will no longer reference $data{'use'}. Please check Hosts->Host Templates->$objects{$key}[0] values."
);
delete $data{'use'};
}
$host_templates{ $objects{$key}[0] }{'check_period'} = $timeperiod_name{ $data{'check_period'} };
$host_templates{ $objects{$key}[0] }{'notification_period'} = $timeperiod_name{ $data{'notification_period'} };
$host_templates{ $objects{$key}[0] }{'check_command'} = $command_name{ $data{'check_command'} };
$host_templates{ $objects{$key}[0] }{'event_handler'} = $command_name{ $data{'event_handler'} };
delete $data{'notification_period'};
delete $data{'check_command'};
delete $data{'check_period'};
delete $data{'event_handler'};
my $template_contactgroups = $data{'contact_groups'};
delete $data{'contact_groups'};
my $data_xml = $xml_begin;
foreach my $prop ( keys %data ) {
$data_xml .= " \n";
$data_xml .= " \n";
$host_templates{ $objects{$key}[0] }{$prop} = $data{$prop};
}
$data_xml .= $xml_end;
if ( $host_templates{ $objects{$key}[0] }{'id'} ) {
my %values = ();
$values{'check_period'} = $host_templates{ $objects{$key}[0] }{'check_period'};
$values{'notification_period'} = $host_templates{ $objects{$key}[0] }{'notification_period'};
$values{'check_command'} = $host_templates{ $objects{$key}[0] }{'check_command'};
$values{'event_handler'} = $host_templates{ $objects{$key}[0] }{'event_handler'};
$values{'data'} = $data_xml;
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'host_templates', 'name', $objects{$key}[0], \%values );
$updated++;
}
else {
my @values = (
\undef, $objects{$key}[0],
$host_templates{ $objects{$key}[0] }{'check_period'}, $host_templates{ $objects{$key}[0] }{'notification_period'},
$host_templates{ $objects{$key}[0] }{'check_command'}, $host_templates{ $objects{$key}[0] }{'event_handler'},
$data_xml, $objects{$key}[4]
);
$result = StorProc->insert_obj_id( 'host_templates', \@values, 'hosttemplate_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$host_templates{ $objects{$key}[0] }{'id'} = $result;
$imported++;
}
}
## my %w = ('type' => 'host_templates','object' => $host_templates{$objects{$key}[0]}{'id'});
## StorProc->delete_one_where('contactgroup_assign',\%w);
my %w = ( 'hosttemplate_id' => $host_templates{ $objects{$key}[0] }{'id'} );
StorProc->delete_one_where( 'contactgroup_host_template', \%w );
my @members = split( /,/, $template_contactgroups );
@{ $host_templates{ $objects{$key}[0] }{'contactgroups'} } = ();
foreach my $mem (@members) {
$mem =~ s/^\s+|\s+$//g;
unless ( $contactgroup_name{$mem} ) {
update_status( 'error', "Contact group $mem does not exist for host template $objects{$key}[0]." );
}
else {
## my @vals = ($contactgroup_name{$mem},'host_templates',$host_templates{$objects{$key}[0]}{'id'});
## StorProc->insert_obj('contactgroup_assign',\@vals);
my @vals = ( $contactgroup_name{$mem}, $host_templates{ $objects{$key}[0] }{'id'} );
$result = StorProc->insert_obj( 'contactgroup_host_template', \@vals );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
push @{ $host_templates{ $objects{$key}[0] }{'contactgroups'} }, $contactgroup_name{$mem};
}
}
}
}
## Collapse host template chains, because Monarch currently only supports one level.
## FIX LATER: deal with additive inheritance here (where the local non-custom string variable contains a leading "+")
## FIX LATER: deal with multiple-level inheritance chains here (i.e., sequence the $temp values according to their level
## in the hierarchy, instead of randomly), watching out for possible circular template references in the incoming files
foreach my $temp ( keys %consolidate_templates ) {
my %values = ();
foreach my $prop ( keys %{ $host_templates{ $consolidate_templates{$temp} } } ) {
if ( $prop eq 'contactgroups' ) {
unless ( @{ $host_templates{$temp}{'contactgroups'} } ) {
foreach my $cgid ( @{ $host_templates{ $consolidate_templates{$temp} }{$prop} } ) {
## my @vals = ($cgid,'host_templates',$host_templates{$temp}{'id'});
## StorProc->insert_obj('contactgroup_assign',\@vals);
my @vals = ( $cgid, $host_templates{$temp}{'id'} );
$result = StorProc->insert_obj( 'contactgroup_host_template', \@vals );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
push @{ $host_templates{$temp}{'contactgroups'} }, $cgid;
}
}
}
else {
unless ( defined $host_templates{$temp}{$prop} ) {
$host_templates{$temp}{$prop} = $host_templates{ $consolidate_templates{$temp} }{$prop};
if ( $prop =~ /^check_period$|^notification_period$|^check_command$|^event_handler$/ ) {
$values{$prop} = $host_templates{ $consolidate_templates{$temp} }{$prop};
}
}
}
}
$values{'data'} = $xml_begin;
foreach my $prop ( keys %{ $host_templates{$temp} } ) {
unless ( $prop =~ /^check_period$|^notification_period$|^id$|^contactgroups$|^check_command$|^event_handler$/ ) {
$values{'data'} .= " \n";
$values{'data'} .= " \n";
}
}
$values{'data'} .= $xml_end;
StorProc->update_obj( 'host_templates', 'name', $temp, \%values );
}
update_status( 'info', "Host templates: $read read, $updated updated, $imported imported." );
StorProc->delete_one_where( 'stage_other', \%where );
# hostextinfo templates
$read = $updated = $imported = $new = 0;
update_status( 'info', 'Loading hostextinfo templates ...' );
%where = ( 'type' => 'hostextinfo_template' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
my $index = 1;
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
foreach my $prop ( keys %data ) {
$hostextinfo_templates{ $objects{$key}[0] }{$prop} = $data{$prop};
}
if ( $hostextinfo_templates{ $objects{$key}[0] }{'id'} ) {
my %values = ();
$values{'data'} = $objects{$key}[3];
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'extended_host_info_templates', 'name', $objects{$key}[0], \%values );
$updated++;
}
else {
my @values = ( \undef, $objects{$key}[0], $objects{$key}[3], '', $objects{$key}[4] );
$result = StorProc->insert_obj_id( 'extended_host_info_templates', \@values, 'hostextinfo_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$hostextinfo_templates{ $objects{$key}[0] }{'id'} = $result;
$imported++;
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Host extended info templates: $read read, $updated updated, $imported imported." );
# hosts
$read = $updated = $imported = $new = 0;
update_status( 'info', 'Loading hosts ...' );
my %host_parents = ();
my %host_hostgroup = ();
%where = ( 'type' => 'host' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
$index = 1;
foreach my $key ( keys %objects ) {
$read++;
my $status = 1;
my %host_overrides = ();
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
delete $data{'command_line'};
my %contactgroups = ();
my @parents = ();
if ( $redundant_templates{ $data{'use'} } ) {
$data{'use'} = $redundant_templates{ $data{'use'} };
}
if ( $data{'parents'} ) {
@parents = split( /,/, $data{'parents'} );
delete $data{'parents'};
}
if ( $data{'check_period'} ) {
if ( $timeperiod_name{ $data{'check_period'} } ) {
$host_overrides{'check_period'} = $timeperiod_name{ $data{'check_period'} };
}
else {
my $tname = $data{'check_period'};
update_status( 'error',
"Time period $data{'check_period'} is specified for host \"$objects{$key}[0]\" but no such time period exists." );
my @values = ( \undef, $data{'check_period'}, '', $xml_begin . $xml_end, '' );
$result = StorProc->insert_obj_id( 'time_periods', \@values, 'timeperiod_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$timeperiod_name{ $data{'check_period'} } = $result;
}
$host_overrides{'check_period'} = $timeperiod_name{ $data{'check_period'} };
update_status( 'warning',
"Added time period $tname but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
delete $data{'check_period'};
}
if ( $data{'notification_period'} ) {
if ( $timeperiod_name{ $data{'notification_period'} } ) {
$host_overrides{'notification_period'} = $timeperiod_name{ $data{'notification_period'} };
}
else {
my $tname = $data{'notification_period'};
update_status( 'error',
"Time period $data{'notification_period'} is specified for host \"$objects{$key}[0]\" but no such time period exists." );
my @values = ( \undef, $data{'notification_period'}, '', $xml_begin . $xml_end, '' );
$result = StorProc->insert_obj_id( 'time_periods', \@values, 'timeperiod_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$timeperiod_name{ $data{'notification_period'} } = $result;
}
$host_overrides{'notification_period'} = $timeperiod_name{ $data{'notification_period'} };
update_status( 'warning',
"Added time period $tname but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
delete $data{'notification_period'};
}
if ( $data{'check_command'} ) {
if ( $command_name{ $data{'check_command'} } ) {
$host_overrides{'check_command'} = $command_name{ $data{'check_command'} };
}
else {
my $tname = $data{'check_command'};
update_status( 'error',
"Check command $data{'check_command'} is specified for host \"$objects{$key}[0]\" but no such command definition exists." );
my @values = ( \undef, $data{'check_command'}, 'check', $xml_begin . $xml_end, '' );
$result = StorProc->insert_obj_id( 'commands', \@values, 'command_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$host_overrides{'check_command'} = $result;
}
$command_name{ $data{'check_command'} } = $host_overrides{'check_command'};
update_status( 'warning',
"Added check command $tname but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
delete $data{'check_command'};
}
if ( $data{'event_handler'} ) {
if ( $command_name{ $data{'event_handler'} } ) {
$host_overrides{'event_handler'} = $command_name{ $data{'event_handler'} };
}
else {
my $tname = $data{'event_handler'};
update_status( 'error',
"Event handler $data{'event_handler'} is specified for host \"$objects{$key}[0]\" but no such command definition exists." );
my @values = ( \undef, $data{'event_handler'}, 'check', $xml_begin . $xml_end, '' );
$result = StorProc->insert_obj_id( 'commands', \@values, 'command_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$host_overrides{'event_handler'} = $result;
}
$command_name{ $data{'event_handler'} } = $host_overrides{'event_handler'};
update_status( 'warning',
"Added event handler $tname but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
delete $data{'event_handler'};
}
if ( $data{'contact_groups'} ) {
my @cgs = split( /,/, $data{'contact_groups'} );
foreach my $cg (@cgs) {
$cg =~ s/^\s+|\s+$//g;
if ( $contactgroup_name{$cg} ) {
$contactgroups{$cg} = $contactgroup_name{$cg};
}
}
delete $data{'contact_groups'};
}
foreach my $k ( keys %data ) {
$host_overrides{$k} = $data{$k};
}
unless ( $data{'use'} ) {
update_status( 'note', "Host $objects{$key}[0] does not use a template" );
my $bestmatch = 0;
foreach my $temp ( keys %host_templates ) {
my $gotmatch = 0;
if ( $host_overrides{'check_period'} eq $host_templates{$temp}{'check_period'} ) {
$gotmatch++;
}
if ( $host_overrides{'notification_period'} eq $host_templates{$temp}{'notification_period'} ) {
$gotmatch++;
}
if ( $host_overrides{'check_command'} eq $host_templates{$temp}{'check_command'} ) {
$gotmatch++;
}
if ( $host_overrides{'event_handler'} eq $host_templates{$temp}{'event_handler'} ) {
$gotmatch++;
}
foreach my $d ( keys %data ) {
if ( $d =~ /file_name|address|alias|parents/ ) { next }
if ( defined( $host_templates{$temp}{$d} ) && $data{$d} eq $host_templates{$temp}{$d} ) { $gotmatch++ }
}
foreach my $cgid ( @{ $host_templates{$temp}{'contactgroups'} } ) {
foreach my $cg ( keys %contactgroups ) {
if ( $contactgroups{$cg} eq $cgid ) { $gotmatch++ }
}
}
if ( $gotmatch > $bestmatch ) {
$bestmatch = $gotmatch;
$data{'use'} = $temp;
}
}
update_status( 'action', "Assigned host template $data{'use'} to host $objects{$key}[0]." );
}
else {
unless ( $host_templates{ $data{'use'} }{'id'} ) {
update_status( 'error', "host $objects{$key}[0] specifies template $data{'use'} but no such template exists." );
my $data = $xml_begin . $xml_end;
my $comment = undef;
my @values = ( \undef, $data{'use'}, '', '', '', '', $data, $comment );
$result = StorProc->insert_obj_id( 'host_templates', \@values, 'hosttemplate_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$host_templates{ $data{'use'} }{'id'} = $result;
}
update_status( 'warning',
"Added host template $data{'use'}, but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
}
unless ( $data{'address'} ) { $data{'address'} = $objects{$key}[0] }
if ( $host_name{ $objects{$key}[0] } ) {
my %values = ();
$values{'alias'} = $data{'alias'};
$values{'address'} = $data{'address'};
$values{'hosttemplate_id'} = $host_templates{ $data{'use'} }{'id'};
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'hosts', 'name', $objects{$key}[0], \%values );
$updated++;
}
else {
## FIX MAJOR NOW: unxmlify the notes
my @values = (
\undef, $objects{$key}[0], $data{'alias'}, $data{'address'}, 'n/a', $host_templates{ $data{'use'} }{'id'},
'', '', '', '', $status, $objects{$key}[4], $data{'notes'}
);
$result = StorProc->insert_obj_id( 'hosts', \@values, 'host_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$host_name{ $objects{$key}[0] } = $result;
$imported++;
}
}
if (@parents) {
foreach my $p (@parents) {
$host_parents{ $objects{$key}[0] } .= "$p,";
}
chop $host_parents{ $host_name{ $objects{$key}[0] } };
}
elsif ( $template_parents{ $data{'use'} }{'parents'} ) {
push @{ $template_parents{ $data{'use'} }{'hosts'} }, $host_name{ $objects{$key}[0] };
}
if ( $data{'hostgroups'} ) {
$host_hostgroup{ $host_name{ $objects{$key}[0] } } = $data{'hostgroups'};
}
elsif ( $template_hostgroups{ $data{'use'} } ) {
$host_hostgroup{ $host_name{ $objects{$key}[0] } } = $template_hostgroups{ $data{'use'} };
}
StorProc->delete_all( 'host_overrides', 'host_id', $host_name{ $objects{$key}[0] } );
my $got_covs = 0;
foreach my $k ( keys %host_overrides ) {
if ( $host_templates{ $data{'use'} }{$k} eq $host_overrides{$k} ) {
delete $host_overrides{$k};
}
elsif ($k =~ /^_/) {
$got_covs = 1;
}
}
## FIX MINOR: There are probably lots of other possible override fields that we ought to test for here,
## To force an update. Should we do so in a blanket way?
if ( $host_overrides{'check_period'}
|| $host_overrides{'notification_period'}
|| $host_overrides{'check_command'}
|| $host_overrides{'event_handler'}
|| $host_overrides{'max_check_attempts'}
|| $host_overrides{'notification_options'}
|| $host_overrides{'notification_interval'}
|| $got_covs)
{
my $data_xml = $xml_begin;
foreach my $o ( keys %host_overrides ) {
unless ( $o =~ /alias|address|file_name|check_period|notification_period|check_command|event_handler|^use$/ ) {
$data_xml .= " \n";
$data_xml .= " \n";
}
}
$data_xml .= $xml_end;
my @values = (
$host_name{ $objects{$key}[0] },
$host_overrides{'check_period'},
$host_overrides{'notification_period'},
$host_overrides{'check_command'},
$host_overrides{'event_handler'}, $data_xml
);
$result = StorProc->insert_obj( 'host_overrides', \@values );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
}
if (%contactgroups) {
foreach my $cg ( keys %contactgroups ) {
if ($cg) {
## my @vals = ($contactgroups{$cg},'hosts',$host_name{$objects{$key}[0]});
## StorProc->insert_obj('contactgroup_assign',\@vals);
my @vals = ( $contactgroups{$cg}, $host_name{ $objects{$key}[0] } );
$result = StorProc->insert_obj( 'contactgroup_host', \@vals );
if ( $result =~ /Error/ && $result !~ /duplicate/i ) {
update_status( 'error', "$result (contact group $cg, host $objects{$key}[0])" );
}
}
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Hosts: $read read, $updated updated, $imported imported." );
# host parent
update_status( 'info', "Setting host parent relationships ..." );
StorProc->truncate_table('host_parent');
foreach my $host ( keys %host_parents ) {
my @parents = split( /,/, $host_parents{$host} );
foreach my $parent (@parents) {
$parent =~ s/^\s+|\s+$//g;
my @vals = ( $host_name{$host}, $host_name{$parent} );
$result = StorProc->insert_obj( 'host_parent', \@vals );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
}
}
# template parents
if (%template_parents) {
update_status( 'info', "Setting parents from templates to hosts ..." );
foreach my $temp ( keys %template_parents ) {
my @parents = split( /,/, $template_parents{$temp}{'parents'} );
delete $template_parents{$temp}{'parents'};
foreach my $parent (@parents) {
$parent =~ s/^\s+|\s+$//g;
foreach my $host ( @{ $template_parents{$temp}{'hosts'} } ) {
my $hid = $template_parents{$temp}{$host};
my @vals = ( $host, $host_name{$parent} );
$result = StorProc->insert_obj( 'host_parent', \@vals );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
}
}
}
}
# redundant templates
if (%redundant_templates) {
update_status( 'info', "Removing redundant templates ..." );
foreach my $temp ( keys %redundant_templates ) {
StorProc->delete_all( 'host_templates', 'name', $temp );
}
}
StorProc->delete_one_where( 'stage_other', \%where );
# host dependency
update_status( 'info', 'Loading host dependencies ...' );
StorProc->truncate_table('host_dependencies');
%where = ( 'type' => 'hostdependency' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
my @hosts = split( /,/, $data{'dependent_host_name'} );
my @parents = split( /,/, $data{'host_name'} );
my %master_host = ();
foreach my $host (@hosts) {
$host =~ s/^\s+|\s+$//g;
foreach my $parent (@parents) {
$parent =~ s/^\s+|\s+$//g;
$master_host{ $host_name{$host} } = $host_name{$parent};
}
}
my $data_xml = $xml_begin;
foreach my $d ( keys %data ) {
if ( $d =~ /host_name/ ) { next }
# The Nagios docs say notification_failure_criteria and execution_failure_criteria but
# the Nagios code emits notification_failure_options and execution_failure_options when
# it writes a precached object file, for either a host or service dependency. So we
# need to handle either case, to process robustly.
my $name = $d;
$name = 'notification_failure_criteria' if $name eq 'notification_failure_options';
$name = 'execution_failure_criteria' if $name eq 'execution_failure_options';
$data_xml .= " \n";
$data_xml .= " \n";
}
$data_xml .= $xml_end;
foreach my $host ( keys %master_host ) {
my @values = ( $host, $master_host{$host}, $data_xml, $objects{$key}[4] );
$result = StorProc->insert_obj( 'host_dependencies', \@values );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
}
}
StorProc->delete_one_where( 'stage_other', \%where );
# hostextinfo
update_status( 'info', 'Loading host extended info ...' );
%where = ( 'type' => 'hostextinfo' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
$index = StorProc->count('extended_host_info_templates');
foreach my $key ( keys %objects ) {
my @hosts = ();
my $hoststr = undef;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
if ( $objects{$key}[2] eq 'hostextinfo' ) {
@hosts = split( /,/, $data{'host_name'} );
}
else {
push @hosts, $objects{$key}[0];
}
if ( $data{'notes_url'} ) {
if ( $hosts[0] && $hosts[0] ne '?' ) {
$data{'notes_url'} =~ s/$hosts[0]/\$HOSTNAME\$/g;
}
$data{'notes_url'} =~ s/\s/+/g;
}
unless ( $data{'use'} ) {
my $props = 0;
foreach ( keys %data ) { $props++ }
if ( $data{'host_name'} ) { $props -= 1 }
if ( $data{'notes_url'} ) { $props -= 1 }
if ( $data{'2d_coords'} ) { $props -= 1 }
if ( $data{'3d_coords'} ) { $props -= 1 }
my %gotmatch = ();
foreach my $temp ( keys %hostextinfo_templates ) {
foreach my $d ( keys %data ) {
if ( $d =~ /d_coords|host_name/ ) { next }
if ( $data{$d} eq $hostextinfo_templates{$temp}{$d} ) {
$gotmatch{$temp} += 1;
}
}
}
my $match = undef;
my $best = 0;
foreach my $key ( keys %gotmatch ) {
if ( $gotmatch{$key} > $best ) {
$match = $key;
$best = $gotmatch{$key};
}
}
if ( $gotmatch{$match} >= $props ) { $data{'use'} = $match }
unless ( $data{'use'} ) {
my $data_xml = $xml_begin;
foreach my $d ( keys %data ) {
if ( $d =~ /host_name/ ) { next }
$data_xml .= " \n";
$data_xml .= " \n";
}
$data_xml .= $xml_end;
my $name = undef;
if ( $data{'icon_image_alt'} ) {
$name = lc("$data{'icon_image_alt'}-$index");
$name =~ s/_|\s/-/g;
}
elsif ( $data{'icon_image'} ) {
$name = lc("$data{'icon_image'}-$index");
$name =~ s/_|\s|\./-/g;
}
elsif ( $data{'vrml_image'} ) {
$name = lc("$data{'vrml_image'}-$index");
$name =~ s/_|\s|\./-/g;
}
elsif ( $data{'statusmap_image'} ) {
$name = lc("$data{'statusmap_image'}-$index");
$name =~ s/_|\s|\./-/g;
}
else {
$name = "generic-hostextinfo-$index";
}
my $comment = undef;
my @values = ( \undef, $name, $data_xml, '', $comment );
$result = StorProc->insert_obj_id( 'extended_host_info_templates', \@values, 'hostextinfo_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$hostextinfo_templates{ $data{'use'} }{'id'} = $result;
}
$index++;
}
}
if ( $data{'2d_coords'} eq $hostextinfo_templates{ $data{'use'} }{'2d_coords'} ) {
delete $data{'2dcoords'};
}
if ( $data{'3d_coords'} eq $hostextinfo_templates{ $data{'use'} }{'3d_coords'} ) {
delete $data{'3dcoords'};
}
foreach my $host (@hosts) {
my %w = ( 'name' => $host );
my %u = ( 'hostextinfo_id' => $hostextinfo_templates{ $data{'use'} }{'id'} );
StorProc->update_obj_where( 'hosts', \%u, \%w );
StorProc->delete_all( 'extended_info_coords', 'host_id', $host_name{$host} );
if ( $data{'2d_coords'} || $data{'3d_coords'} ) {
my $data_xml = $xml_begin;
foreach my $d ( keys %data ) {
if ( $d =~ /coords/ ) {
$data_xml .= " \n";
$data_xml .= " \n";
}
}
$data_xml .= $xml_end;
my @vals = ( $host_name{$host}, $data_xml );
$result = StorProc->insert_obj( 'extended_info_coords', \@vals );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
# hostgroup templates
update_status( 'info', "Removing hostgroup templates ..." );
my %hostgroup_template = ();
%where = ( 'type' => 'hostgroup_templates' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
$hostgroup_template{ $objects{$key}[0] } = $data{'contact_groups'};
}
StorProc->delete_one_where( 'stage_other', \%where );
# hostgroups
$read = $updated = $imported = $new = 0;
update_status( 'info', 'Loading hostgroups ...' );
StorProc->truncate_table('hostgroup_host');
%where = ( 'type' => 'hostgroup-host' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
my @contactgroups = split( /,/, $data{'contact_groups'} );
if ( $data{'use'} ) {
my @cguse = split( /,/, $hostgroup_template{ $data{'use'} } );
push( @contactgroups, @cguse );
}
if ( $hostgroup_name{ $objects{$key}[0] } ) {
$updated++;
my %values = ();
$values{'alias'} = $objects{$key}[2];
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'hostgroups', 'name', $objects{$key}[0], \%values );
}
else {
$imported++;
## FIX MAJOR NOW: unxmlify the notes
## FIX MAJOR NOW: should have profile id here, too, instead of ''
## FIX MAJOR NOW: should have escalation ids here, too, instead of ''s
my @vals = ( \undef, $objects{$key}[0], $objects{$key}[2], '', '', '', '1', $objects{$key}[4], $data{'notes'} );
if ($gw4) {
@vals = ( \undef, $objects{$key}[0], $objects{$key}[2], '', '', '1', $objects{$key}[4] );
}
$result = StorProc->insert_obj_id( 'hostgroups', \@vals, 'hostgroup_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$hostgroup_name{ $objects{$key}[0] } = $result;
}
}
## my %w = ('type' => 'hostgroups','object' => $hostgroup_name{$objects{$key}[0]});
## StorProc->delete_one_where('contactgroup_assign',\%w);
my %w = ( 'hostgroup_id' => $hostgroup_name{ $objects{$key}[0] } );
StorProc->delete_one_where( 'contactgroup_hostgroup', \%w );
foreach my $cg (@contactgroups) {
$cg =~ s/^\s+|\s+$//g;
## my @vals = ($contactgroup_name{$cg},'hostgroups',$hostgroup_name{$objects{$key}[0]});
## StorProc->insert_obj('contactgroup_assign',\@vals);
my @vals = ( $contactgroup_name{$cg}, $hostgroup_name{ $objects{$key}[0] } );
$result = StorProc->insert_obj( 'contactgroup_hostgroup', \@vals );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
}
if ( $data{'members'} eq '*' ) {
foreach my $mem ( keys %host_name ) {
my @vals = ( $hostgroup_name{ $objects{$key}[0] }, $host_name{$mem} );
$result = StorProc->insert_obj( 'hostgroup_host', \@vals );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
}
}
else {
my %members = ();
$data{'members'} =~ s/^\s+|\s+$//g;
my @mems = split( /,/, $data{'members'} );
foreach (@mems) { $members{$_} = 1 }
foreach my $mem ( keys %members ) {
if ( $host_name{$mem} ) {
my @vals = ( $hostgroup_name{ $objects{$key}[0] }, $host_name{$mem} );
$result = StorProc->insert_obj( 'hostgroup_host', \@vals );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
}
else {
update_status( 'info', "\"$mem\" is not a valid host, and so will be ignored." );
}
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Hostgroups: $read read, $updated updated, $imported imported." );
# hostgroups on hosts
foreach my $host ( keys %host_hostgroup ) {
my @hostgroups = split( /,/, $host_hostgroup{$host} );
foreach my $hg (@hostgroups) {
$hg =~ s/^\s+|\s+$//g;
if ( $hostgroup_name{$hg} ) {
my @vals = ( $hostgroup_name{$hg}, $host );
$result = StorProc->insert_obj( 'hostgroup_host', \@vals );
if ( $result =~ /Error/ ) { update_status( 'error', $result ) }
}
else {
update_status( 'info', "\"$hg\" is not a valid hostgroup, and so will be ignored." );
}
}
}
return @messages;
}
############################################################################
######
###### Break
######
############################################################################
# services
sub process_services() {
my $read = 0;
my $updated = 0;
my $imported = 0;
my %command_name = StorProc->get_table_objects('commands');
my %timeperiod_name = StorProc->get_table_objects('time_periods');
my %contact_name = StorProc->get_table_objects('contacts');
my %contactgroup_name = StorProc->get_table_objects('contactgroups');
my %service_name = StorProc->get_table_objects('service_names');
my %host_templates = StorProc->get_host_templates();
my %hostextinfo_templates = StorProc->get_hostextinfo_templates(); # FIX LATER: not referenced anywhere
my %host_name = StorProc->get_table_objects('hosts');
my %hostgroup_name = StorProc->get_table_objects('hostgroups');
my %service_templates = StorProc->get_service_templates();
my %serviceextinfo_templates = StorProc->get_serviceextinfo_templates();
my %servicegroup_name = StorProc->get_table_objects('servicegroups');
my %service_dependency_templates = StorProc->get_service_dependency_templates('service_dependency_templates');
my $result;
# Set special * service
unless ( $service_name{'*'} ) {
my @values = ( \undef, '*', 'special use', '', '', '', '', '', "$xml_begin$xml_end" );
if ($gw4) { pop @values }
$result = StorProc->insert_obj_id( 'service_names', \@values, 'servicename_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$service_name{'*'} = $result;
}
}
# service templates
update_status( 'info', 'Loading service templates ...' );
my %where = ( 'type' => 'service_template' );
my %objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
my %service_template_host = ();
my %parents = ();
foreach my $key ( keys %objects ) {
$read++;
unless ( $objects{$key}[2] eq 'no-parent' ) {
$parents{ $objects{$key}[0] } = $objects{$key}[2];
}
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
$service_templates{ $objects{$key}[0] }{'check_period'} = $timeperiod_name{ $data{'check_period'} };
$service_templates{ $objects{$key}[0] }{'notification_period'} = $timeperiod_name{ $data{'notification_period'} };
$service_templates{ $objects{$key}[0] }{'check_command'} = $command_name{ $data{'check_command'} };
unless ($gw4) {
$service_templates{ $objects{$key}[0] }{'command_line'} = $data{'command_line'};
}
$service_templates{ $objects{$key}[0] }{'event_handler'} = $command_name{ $data{'event_handler'} };
delete $data{'check_period'};
delete $data{'notification_period'};
delete $data{'check_command'};
delete $data{'event_handler'};
unless ($gw4) { delete $data{'command_line'} }
if ( $data{'host_name'} ) {
$service_template_host{ $objects{$key}[0] }{'hosts'} = $data{'host_name'};
}
if ( $data{'hostgroup_name'} ) {
$service_template_host{ $objects{$key}[0] }{'hostgroups'} = $data{'hostgroup_name'};
}
delete $data{'host_name'};
delete $data{'hostgroup_name'};
my $data_xml = $xml_begin;
foreach my $d ( keys %data ) {
if ( $d =~ /contact_groups/ ) { next }
$data_xml .= " \n";
$data_xml .= " \n";
}
$data_xml .= $xml_end;
if ( $service_templates{ $objects{$key}[0] }{'id'} ) {
$updated++;
my %values = ();
$values{'parent_id'} = $service_templates{ $objects{$key}[0] }{'parent_id'};
$values{'check_period'} = $service_templates{ $objects{$key}[0] }{'check_period'};
$values{'notification_period'} = $service_templates{ $objects{$key}[0] }{'notification_period'};
$values{'check_command'} = $service_templates{ $objects{$key}[0] }{'check_command'};
unless ($gw4) {
$values{'command_line'} = $service_templates{ $objects{$key}[0] }{'command_line'};
}
$values{'event_handler'} = $service_templates{ $objects{$key}[0] }{'event_handler'};
$values{'data'} = $data_xml;
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'service_templates', 'name', $objects{$key}[0], \%values );
}
else {
$imported++;
my @values = (
\undef, $objects{$key}[0],
'', $service_templates{ $objects{$key}[0] }{'check_period'},
$service_templates{ $objects{$key}[0] }{'notification_period'}, $service_templates{ $objects{$key}[0] }{'check_command'},
$service_templates{ $objects{$key}[0] }{'command_line'}, $service_templates{ $objects{$key}[0] }{'event_handler'},
$data_xml, $objects{$key}[4]
);
if ($gw4) {
@values = (
\undef, $objects{$key}[0],
'', $service_templates{ $objects{$key}[0] }{'check_period'},
$service_templates{ $objects{$key}[0] }{'notification_period'}, $service_templates{ $objects{$key}[0] }{'check_command'},
$service_templates{ $objects{$key}[0] }{'event_handler'}, $data_xml,
$objects{$key}[4]
);
}
$result = StorProc->insert_obj_id( 'service_templates', \@values, 'servicetemplate_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$service_templates{ $objects{$key}[0] }{'id'} = $result;
}
}
## my %w = ('type' => 'service_templates','object' => $service_templates{$objects{$key}[0]}{'id'});
## StorProc->delete_one_where('contactgroup_assign',\%w);
my %w = ( 'servicetemplate_id' => $service_templates{ $objects{$key}[0] }{'id'} );
StorProc->delete_one_where( 'contactgroup_service_template', \%w );
my @members = split( /,/, $data{'contact_groups'} );
foreach my $mem (@members) {
$mem =~ s/^\s+|\s+$//g;
unless ( $contactgroup_name{$mem} ) {
update_status( 'error', "Contact group $mem does not exist for service template $objects{$key}[0]" );
}
else {
## my @vals = ($contactgroup_name{$mem},'service_templates',$service_templates{$objects{$key}[0]}{'id'});
## StorProc->insert_obj('contactgroup_assign',\@vals);
my @vals = ( $contactgroup_name{$mem}, $service_templates{ $objects{$key}[0] }{'id'} );
$result = StorProc->insert_obj( 'contactgroup_service_template', \@vals );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Service templates: $read read, $updated updated, $imported imported." );
foreach my $temp ( keys %parents ) {
my %values = ( 'parent_id' => $service_templates{ $parents{$temp} }{'id'} );
StorProc->update_obj( 'service_templates', 'name', $temp, \%values );
}
%service_templates = StorProc->get_service_templates();
# service names
$read = $updated = $imported = 0;
update_status( 'info', "Creating service names ..." );
my $index = 1;
%where = ( 'type' => 'service' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
my %sn_use = ();
my %sn_cmd = ();
my %sn_cmdline = ();
my %sn_dep = ();
foreach my $key ( sort keys %objects ) {
$objects{$key}[0] =~ s/^\s+|\s+$//g;
unless ( $service_name{ $objects{$key}[0] } ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
$sn_cmd{ $objects{$key}[0] } = $command_name{ $data{'check_command'} };
$sn_cmdline{ $objects{$key}[0] } = $data{'command_line'};
my $props = 0;
delete $data{'host_name'};
delete $data{'hostgroup_name'};
delete $data{'file_name'};
my @cgs = split( /,/, $data{'contact_groups'} );
my %contactgroups = ();
foreach my $cg (@cgs) {
$cg =~ s/^\s+|\s+$//g;
$contactgroups{$cg} = $contactgroup_name{$cg};
}
if ( $data{'check_period'} ) {
if ( $timeperiod_name{ $data{'check_period'} } ) {
$data{'check_period'} = $timeperiod_name{ $data{'check_period'} };
}
else {
my $tname = $data{'check_period'};
update_status( 'error',
"Time period $data{'check_period'} is specified for service \"$objects{$key}[0]\" but no such time period exists." );
my @values = ( \undef, $data{'check_period'}, '', $xml_begin . $xml_end, '' );
$result = StorProc->insert_obj_id( 'time_periods', \@values, 'timeperiod_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$timeperiod_name{ $data{'check_period'} } = $result;
}
$data{'check_period'} = $timeperiod_name{ $data{'check_period'} };
update_status( 'warning',
"Added time period $tname but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
}
if ( $data{'notification_period'} ) {
if ( $timeperiod_name{ $data{'notification_period'} } ) {
$data{'notification_period'} = $timeperiod_name{ $data{'notification_period'} };
}
else {
my $tname = $data{'notification_period'};
update_status( 'error',
"Time period $data{'notification_period'} is specified for service \"$objects{$key}[0]\" but no such time period exists."
);
my @values = ( \undef, $data{'check_period'}, '', $xml_begin . $xml_end, '' );
$result = StorProc->insert_obj_id( 'time_periods', \@values, 'timeperiod_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$timeperiod_name{ $data{'notification_period'} } = $result;
}
$data{'notification_period'} = $timeperiod_name{ $data{'notification_period'} };
update_status( 'warning',
"Added time period $tname but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
}
if ( $data{'check_command'} ) {
if ( $command_name{ $data{'check_command'} } ) {
$data{'check_command'} = $command_name{ $data{'check_command'} };
}
else {
my $tname = $data{'check_command'};
update_status( 'error',
"Check command $data{'check_command'} is specified for service \"$objects{$key}[0]\" but no such command definition exists."
);
my @values = ( \undef, $data{'check_period'}, '', $xml_begin . $xml_end, '' );
$result = StorProc->insert_obj_id( 'commands', \@values, 'command_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$command_name{ $data{'check_command'} } = $result;
}
$data{'check_command'} = $command_name{ $data{'check_command'} };
update_status( 'warning',
"Added check command $tname but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
}
unless ( $data{'use'} ) {
my $bestmatch = 0;
unless (%service_templates) {
update_status( 'note', "No service templates exist and at least one is required." );
my $data = $xml_begin . $xml_end;
my @values = ( \undef, 'default-service', '', '', '', '', '', '', $data, '' );
$result = StorProc->insert_obj_id( 'service_templates', \@values, 'servicetemplate_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$service_templates{'default-service'}{'id'} = $result;
}
$data{'use'} = 'default-service';
update_status( 'warning',
"Added service template 'default-service' but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
else {
foreach my $temp ( keys %service_templates ) {
my %template = %{ $service_templates{$temp} };
my %super_temp = ();
@{ $super_temp{'contactgroups'} } = ();
my $got_parent = 0;
my %already_seen = ();
until ($got_parent) {
foreach my $t ( keys %template ) {
unless ( exists $super_temp{$t} ) {
$super_temp{$t} = $template{$t};
}
}
$already_seen{ $template{'id'} } = 1;
$got_parent = 1;
if ( $template{'parent_id'} && !$already_seen{ $template{'parent_id'} } ) {
foreach my $key ( keys %service_templates ) {
if ( $template{'parent_id'} eq $service_templates{$key}{'id'} ) {
%template = %{ $service_templates{$key} };
$got_parent = 0;
last;
}
}
}
}
foreach my $t ( keys %super_temp ) {
my $gotmatch = 0;
foreach my $d ( keys %data ) {
if ( $d =~ /period/ ) {
if ( $timeperiod_name{ $data{$d} } eq $super_temp{$d} ) {
$gotmatch++;
}
}
elsif ( $d =~ /command|handler/ ) {
if ( $command_name{ $data{$d} } eq $super_temp{$d} ) {
$gotmatch++;
}
}
else {
if ( $data{$d} eq $super_temp{$d} ) {
$gotmatch++;
}
}
}
foreach my $cg ( keys %contactgroups ) {
foreach my $cid ( @{ $super_temp{'contactgroups'} } ) {
if ( $cid eq $contactgroups{$cg} ) {
$gotmatch++;
}
}
}
if ( $gotmatch > $bestmatch ) {
$bestmatch = $gotmatch;
$data{'use'} = $temp;
}
}
}
}
}
unless ( $service_templates{ $data{'use'} }{'id'} ) {
update_status( 'error', "Service $objects{$key}[0] specifies template $data{'use'} but no such template exists." );
my $data = $xml_begin . $xml_end;
my @values = ( \undef, $data{'use'}, '', '', '', '', '', '', $data, '' );
$result = StorProc->insert_obj_id( 'service_templates', \@values, 'servicetemplate_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$service_templates{ $data{'use'} }{'id'} = $result;
}
update_status( 'warning',
"Added service template $data{'use'} but properties have not been set. WARNING: You must set the properties before attempting preflight or commit!"
);
}
$imported++;
my $samesame = 0;
foreach my $sname ( keys %service_name ) {
if ( $sname =~ /^$objects{$key}[0]$/i ) {
$service_name{ $objects{$key}[0] } = $service_name{$sname};
}
}
unless ( $service_name{ $objects{$key}[0] } ) {
$sn_use{ $objects{$key}[0] } = $data{'use'};
my @values = (
\undef, $objects{$key}[0], $objects{$key}[0],
$service_templates{ $data{'use'} }{'id'},
$sn_cmd{ $objects{$key}[0] },
$sn_cmdline{ $objects{$key}[0] },
'', '', "$xml_begin$xml_end"
);
if ($gw4) { pop @values }
$result = StorProc->insert_obj_id( 'service_names', \@values, 'servicename_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$service_name{ $objects{$key}[0] } = $result;
}
if ( $debug && $service_name{ $objects{$key}[0] } =~ /error/i ) {
update_status( 'error', "$service_name{$objects{$key}[0]}" );
}
}
}
}
update_status( 'info', "New service definitions: $imported imported." );
# services
$read = $updated = $imported = 0;
update_status( 'info', 'Loading services ...' );
my %use_regex = StorProc->fetch_one( 'stage_other', 'name', 'use_regex' );
my %host_services = ();
my %hosts_services = StorProc->get_hostid_servicenameid_serviceid();
my %service_groups = ();
my %services = StorProc->get_staged_services();
foreach my $key ( sort keys %services ) {
$read++;
my %hosts = ();
if ( $services{$key}{'hostgroup_name'} ) {
my @hostgroups = split( /,/, $services{$key}{'hostgroup_name'} );
foreach my $hg (@hostgroups) {
$hg =~ s/^\s+|\s+$//g;
my %w = ( 'hostgroup_id' => $hostgroup_name{$hg} );
my @hosts = StorProc->fetch_list_where( 'hostgroup_host', 'host_id', \%w );
foreach (@hosts) { $hosts{$_} = 1 }
}
}
if ( $service_template_host{ $services{$key}{'use'} }{'hosts'} ) {
my @hostnames = split( /,/, $service_template_host{ $services{$key}{'use'} }{'hosts'} );
foreach my $hn (@hostnames) {
$hn =~ s/^\s+|\s+$//g;
foreach my $host ( keys %host_name ) {
if ( $host =~ /^$hn$/i ) { $hosts{ $host_name{$host} } = 1 }
}
}
}
if ( $service_template_host{ $services{$key}{'use'} }{'hostgroups'} ) {
my @hostgroups = split( /,/, $service_template_host{ $services{$key}{'use'} }{'hostgroups'} );
foreach my $hg (@hostgroups) {
$hg =~ s/^\s+|\s+$//g;
my %w = ( 'hostgroup_id' => $hostgroup_name{$hg} );
my @hosts = fetch_list_where( 'hostgroup_host', 'host_id', \%w );
foreach (@hosts) { $hosts{$_} = 1 }
}
}
if ( $services{$key}{'host_name'} eq '*' ) {
foreach my $h ( keys %host_name ) {
$hosts{ $host_name{$h} } = $host_name{$h};
}
}
else {
my @hostnames = split( /,/, $services{$key}{'host_name'} );
foreach my $hn (@hostnames) {
$hn =~ s/^\s+|\s+$//g;
foreach my $host ( keys %host_name ) {
if ( $host =~ /^$hn$/i ) { $hosts{ $host_name{$host} } = 1 }
}
}
}
my %values = ();
$values{'servicename_id'} = $service_name{ $services{$key}{'name'} };
$values{'servicetemplate_id'} = $service_templates{ $services{$key}{'use'} }{'id'};
$values{'check_command'} = $command_name{ $services{$key}{'check_command'} };
$values{'command_line'} = $services{$key}{'command_line'};
$values{'comment'} = $services{$key}{'comment'};
$values{'notes'} = $services{$key}{'notes'};
my $got_parent = 0;
my %template = %{ $service_templates{ $services{$key}{'use'} } };
my %super_temp = ();
@{ $super_temp{'contactgroups'} } = ();
%super_temp = %template;
my %already_seen = ();
until ($got_parent) {
foreach my $t ( keys %template ) {
unless ( exists $super_temp{$t} ) {
$super_temp{$t} = $template{$t};
}
}
$already_seen{ $template{'id'} } = 1;
$got_parent = 1;
if ( $template{'parent_id'} && !$already_seen{ $template{'parent_id'} } ) {
foreach my $key ( keys %service_templates ) {
if ( $template{'parent_id'} eq $service_templates{$key}{'id'} ) {
%template = %{ $service_templates{$key} };
$got_parent = 0;
last;
}
}
}
}
my %overrides = ();
if ( $timeperiod_name{ $services{$key}{'check_period'} }
&& $timeperiod_name{ $services{$key}{'check_period'} } ne $super_temp{'check_period'} )
{
$overrides{'check_period'} = $timeperiod_name{ $services{$key}{'check_period'} };
}
if ( $timeperiod_name{ $services{$key}{'notification_period'} }
&& $timeperiod_name{ $services{$key}{'notification_period'} } ne $super_temp{'notification_period'} )
{
$overrides{'notification_period'} = $timeperiod_name{ $services{$key}{'notification_period'} };
}
if ( $command_name{ $services{$key}{'event_handler'} }
&& $command_name{ $services{$key}{'event_handler'} } ne $super_temp{'event_handler'} )
{
$overrides{'event_handler'} = $command_name{ $services{$key}{'event_handler'} };
}
if ( $services{$key}{'use'} ) {
unless ( $service_templates{ $services{$key}{'use'} }{'id'} ) {
update_status( 'error',
"Service template $services{$key}{'use'} for service $services{$key}{'name'} does not exist. Template $sn_use{$services{$key}{'name'}} assigned."
);
$services{$key}{'use'} = $sn_use{ $services{$key}{'name'} };
}
}
else {
$services{$key}{'use'} = $sn_use{ $services{$key}{'name'} };
}
delete $services{$key}{'hostgroup_name'};
delete $services{$key}{'host_name'};
delete $services{$key}{'use'};
delete $services{$key}{'check_period'};
delete $services{$key}{'notification_period'};
delete $services{$key}{'event_handler'};
delete $services{$key}{'use'};
delete $services{$key}{'host_name'};
delete $services{$key}{'check_command'};
delete $services{$key}{'command_line'};
delete $services{$key}{'comment'};
my $data_xml = undef;
foreach my $d ( keys %{ $services{$key} } ) {
unless ( $d =~ /contact_groups|file_name|servicegroups|^name$/ || $services{$key}{$d} eq $super_temp{$d} ) {
$data_xml .= " \n";
$data_xml .= " \n";
}
}
if ($data_xml) { $data_xml = $xml_begin . $data_xml . $xml_end }
my @cg_overrides = ();
if ( $services{$key}{'contact_groups'} ) {
my %tcgs = ();
foreach my $mem ( @{ $super_temp{'contactgroups'} } ) {
$tcgs{$mem} = 1;
}
my @cgs = split( /,/, $services{$key}{'contact_groups'} );
foreach my $cg (@cgs) {
$cg =~ s/^\s+|\s+$//g;
unless ( $tcgs{ $contactgroup_name{$cg} } ) {
push @cg_overrides, $contactgroup_name{$cg};
}
}
}
foreach my $hostid ( keys %hosts ) {
my $service_id = $hosts_services{$hostid}{ $service_name{ $services{$key}{'name'} } };
if ($service_id) {
$updated++;
StorProc->update_obj( 'services', 'service_id', $service_id, \%values );
}
else {
$imported++;
## FIX MAJOR NOW: unxmlify the notes
my @vals = (
\undef, $hostid,
$values{'servicename_id'},
$values{'servicetemplate_id'},
'', '', '1', $values{'check_command'},
$values{'command_line'}, $values{'comment'}, $values{'notes'}
);
$result = StorProc->insert_obj_id( 'services', \@vals, 'service_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$service_id = $result;
}
}
# Service overrides
StorProc->delete_all( 'service_overrides', 'service_id', $service_id );
if ( $overrides{'check_period'}
|| $overrides{'notification_period'}
|| $overrides{'event_handler'}
|| $data_xml )
{
my @values =
( $service_id, $overrides{'check_period'}, $overrides{'notification_period'}, $overrides{'event_handler'}, $data_xml );
$result = StorProc->insert_obj( 'service_overrides', \@values );
if ( $debug && $result =~ /error/i ) {
update_status( 'error', $result );
}
}
## do we still need this delete?
## my %w = ('type' => 'services','object' => $service_id);
## StorProc->delete_one_where('contactgroup_assign',\%w);
my %w = ( 'service_id' => $service_id );
StorProc->delete_one_where( 'contactgroup_service', \%w );
my %cg_assigned = ();
foreach my $mem (@cg_overrides) {
unless ( $cg_assigned{$hostid}{$mem} ) {
## my @vals = ($mem,'services',$service_id);
## $result = StorProc->insert_obj('contactgroup_assign',\@vals);
my @vals = ( $mem, $service_id );
$result = StorProc->insert_obj( 'contactgroup_service', \@vals );
if ( $debug && $result =~ /error/i ) {
update_status( 'error', $result );
}
$cg_assigned{$hostid}{$mem} = 1;
}
}
$host_services{$hostid}{ $services{$key}{'name'} } = $service_id;
if ( $services{$key}{'servicegroups'} ) {
$service_groups{$hostid}{$service_id} = $services{$key}{'servicegroups'};
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Services to hosts: $read read, $updated updated, $imported imported." );
# servicegroups
$read = $updated = $imported = 0;
update_status( 'info', 'Loading servicegroups ...' );
StorProc->truncate_table('servicegroup_service');
%where = ( 'type' => 'servicegroup' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
my @members = split( /,/, $data{'members'} );
if ( $servicegroup_name{ $objects{$key}[0] } ) {
$updated++;
my %values = ();
$values{'alias'} = $objects{$key}[2];
StorProc->update_obj( 'servicegroups', 'name', $objects{$key}[0], \%values );
}
else {
## FIX MAJOR NOW: unxmlify the notes
## FIX MAJOR NOW: should have escalation id here, too, instead of ''
my @vals = ( \undef, $objects{$key}[0], $objects{$key}[2], '', $objects{$key}[4], $data{'notes'} );
$result = StorProc->insert_obj_id( 'servicegroups', \@vals, 'servicegroup_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$servicegroup_name{ $objects{$key}[0] } = $result;
$imported++;
}
}
if ( $servicegroup_name{ $objects{$key}[0] } ) {
my @services = ();
my @hosts = ();
my $pairs = 0;
my $i = 0;
foreach my $m (@members) {
$m =~ s/^\s+|\s+$//g;
if ( $i == 1 ) {
push @services, $m;
$i = 0;
}
else {
push @hosts, $m;
$i = 1;
$pairs++;
}
}
for ( $i = 0 ; $i <= $pairs ; $i++ ) {
if ( $host_name{ $hosts[$i] }
&& $host_services{ $host_name{ $hosts[$i] } }{ $services[$i] } )
{
my @vals = (
$servicegroup_name{ $objects{$key}[0] },
$host_name{ $hosts[$i] },
$host_services{ $host_name{ $hosts[$i] } }{ $services[$i] }
);
$result = StorProc->insert_obj( 'servicegroup_service', \@vals );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Service groups: $read read, $updated updated, $imported imported." );
foreach my $hostid ( keys %service_groups ) {
foreach my $service_id ( keys %{ $service_groups{$hostid} } ) {
my @servicegroups =
split( /,/, $service_groups{$hostid}{$service_id} );
foreach my $sg (@servicegroups) {
$sg =~ s/^\s+|\s+$//g;
my @vals = ( $servicegroup_name{$sg}, $hostid, $service_id );
$result = StorProc->insert_obj( 'servicegroup_service', \@vals );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
}
############################################################################
######
###### Break
######
############################################################################
# service dependency templates
update_status( 'info', 'Loading service dependency templates ...' );
my %temp_no_desc = ();
%where = ( 'type' => 'servicedependency_template' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
unless ( $data{'service_description'} ) {
$temp_no_desc{ $objects{$key}[0] } = 1;
$data{'service_description'} = '*';
}
unless ( $service_name{ $data{'service_description'} } ) {
my @values = ( \undef, $data{'service_description'}, $data{'service_description'}, '0', '0', '0', '', '', "$xml_begin$xml_end" );
if ($gw4) { pop @values }
$result = StorProc->insert_obj_id( 'service_names', \@values, 'servicename_id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$service_name{ $data{'service_description'} } = $result;
}
update_status( 'note',
"Service name $data{'service_description'} does not exist and is required for dependency template $objects{$key}[0]." );
update_status( 'warning',
"Service name $data{'service_description'} added for dependency template $objects{$key}[0]. Advise you check properties." );
}
my $data_xml = $xml_begin;
foreach my $d ( keys %data ) {
if ( $d =~ /notification|execution/ ) {
$data_xml .= " \n";
$data_xml .= " \n";
}
}
$data_xml .= $xml_end;
if ( $service_dependency_templates{ $objects{$key}[0] }{'id'} ) {
$updated++;
my %values = ( 'data' => $data_xml );
StorProc->update_obj( 'service_dependency_templates', 'name', $objects{$key}[0], \%values );
}
else {
$imported++;
my @vals = ( \undef, $objects{$key}[0], $service_name{ $data{'service_description'} }, $data_xml, $objects{$key}[4] );
$result = StorProc->insert_obj_id( 'service_dependency_templates', \@vals, 'id' );
if ( $result =~ /error/i ) {
update_status( 'error', $result );
}
else {
$service_dependency_templates{ $objects{$key}[0] }{'id'} = $result;
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Service dependency templates: $read read, $updated updated, $imported imported." );
# service dependency
$read = $updated = $imported = 0;
update_status( 'info', 'Loading service dependencies ...' );
StorProc->truncate_table('service_dependency');
%where = ( 'type' => 'servicedependency' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
$index = StorProc->count('service_dependency_templates');
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
my $props = 0;
# The Nagios docs say notification_failure_criteria and execution_failure_criteria but
# the Nagios code emits notification_failure_options and execution_failure_options when
# it writes a precached object file, for either a host or service dependency. So we
# need to handle either case, to process robustly.
$data{'notification_failure_criteria'} = $data{'notification_failure_options'} if !$data{'notification_failure_criteria'};
$data{'execution_failure_criteria'} = $data{'execution_failure_options'} if !$data{'execution_failure_criteria'};
my @notify = split( /,/, $data{'notification_failure_criteria'} );
my @execute = split( /,/, $data{'execution_failure_criteria'} );
foreach (@notify) { $props++ }
foreach (@execute) { $props++ }
# FIX THIS: it's not at all clear what counting the existence of notification_failure_criteria has
# to do with the rest of the matching going on in this section of code. It looks like a hack to me.
if ( $data{'notification_failure_criteria'} ) { $props++ }
if ( $temp_no_desc{ $data{'use'} } && $data{'service_description'} ) {
my %values = ( 'servicename_id' => $service_name{ $data{'use'} } );
StorProc->update_obj( 'service_dependency_templates', 'servicename_id', \%values );
delete $temp_no_desc{ $data{'use'} };
}
unless ( $data{'use'} ) {
foreach my $temp ( keys %service_dependency_templates ) {
my $gotmatch = 0;
if ( $service_name{ $data{'service_description'} } eq $service_dependency_templates{$temp}{'servicename_id'} ) {
$gotmatch++;
}
my %tv = ();
my @e_temp = split( /,/, $service_dependency_templates{$temp}{'execution_failure_criteria'} );
my @execute = split( /,/, $data{'execution_failure_criteria'} );
foreach my $e (@e_temp) { $tv{$e} = 1 }
foreach my $e (@execute) {
$e =~ s/^\s+|\s+$//g;
if ( $tv{$e} ) { $gotmatch++; }
}
%tv = ();
my @n_temp = split( /,/, $service_dependency_templates{$temp}{'notification_failure_criteria'} );
foreach my $n (@n_temp) { $tv{$n} = 1 }
foreach my $n (@notify) {
$n =~ s/^\s+|\s+$//g;
if ( $tv{$n} ) { $gotmatch++ }
}
if ( $gotmatch == $props ) {
$data{'use'} = $temp;
last;
}
}
}
unless ( $data{'use'} ) {
my $name = $data{'service_description'};
$name =~ s/_/-/g;
$name = "dep-$name-n-$data{'notification_failure_criteria'}-e-$data{'execution_failure_criteria'}";
$name =~ s/,//g;
my $data_xml = $xml_begin;
foreach my $d ( keys %data ) {
unless ( $d =~ /^use$|service_description$|host_name/ ) {
$service_dependency_templates{$name}{$d} = $data{$d};
$data_xml .= " \n";
$data_xml .= " \n";
}
}
$data_xml .= $xml_end;
$service_dependency_templates{$name}{'servicename_id'} = $service_name{ $data{'service_description'} };
my @vals = ( \undef, $name, $service_name{ $data{'service_description'} }, $data_xml, $objects{$key}[4] );
$result = StorProc->insert_obj_id( 'service_dependency_templates', \@vals, 'id' );
if ( $result =~ /Error/i ) {
update_status( 'error', $result );
}
else {
$service_dependency_templates{$name}{'id'} = $result;
}
$data{'use'} = $name;
}
my @dhn = split( /,/, $data{'dependent_host_name'} );
my @dependent_hosts = ();
foreach my $dhn (@dhn) {
$dhn =~ s/^\s+|\s+$//g;
push @dependent_hosts, $host_name{$dhn};
}
my @mhn = split( /,/, $data{'host_name'} );
my @master_hosts = ();
foreach my $mhn (@mhn) {
$mhn =~ s/^\s+|\s+$//g;
push @master_hosts, $host_name{$mhn};
}
@dhn = split( /,/, $data{'dependent_hostgroup_name'} );
foreach my $dhn (@dhn) {
$dhn =~ s/^\s+|\s+$//g;
my %w = ( 'hostgroup_id' => $hostgroup_name{$dhn} );
my @hids = fetch_list_where( 'hostgroup_host', 'host_id', \%w );
push( @dependent_hosts, @hids );
}
@mhn = split( /,/, $data{'hostgroup_name'} );
foreach my $mhn (@mhn) {
$mhn =~ s/^\s+|\s+$//g;
my %w = ( 'hostgroup_id' => $hostgroup_name{$mhn} );
my @hids = fetch_list_where( 'hostgroup_host', 'host_id', \%w );
push( @master_hosts, @hids );
}
foreach my $dhn (@dependent_hosts) {
foreach my $mhn (@master_hosts) {
$objects{$key}[0] =~ s/-\d+$//;
if ( $host_services{$dhn}{ $objects{$key}[0] } ) {
$updated++;
if ( $dhn eq $mhn ) {
$sn_dep{ $objects{$key}[0] }{'NULL'} = $service_dependency_templates{ $data{'use'} }{'id'};
}
else {
$sn_dep{ $objects{$key}[0] }{$mhn} = $service_dependency_templates{ $data{'use'} }{'id'};
}
my @vals = (
\undef, $host_services{$dhn}{ $objects{$key}[0] },
$dhn, $mhn, $service_dependency_templates{ $data{'use'} }{'id'},
$objects{$key}[4]
);
$result = StorProc->insert_obj( 'service_dependency', \@vals );
if ( $debug && $result =~ /error/i ) {
update_status( 'error', $result );
}
}
else {
update_status( 'error', "service $objects{$key}[0] does not exist for dependency " );
}
}
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Service dependencies: $read read, $updated updated, $imported imported." );
# Update Service names
$read = $updated = $imported = 0;
update_status( 'info', "Updating services with dependency info ..." );
foreach my $service ( keys %sn_dep ) {
foreach my $mhn ( keys %{ $sn_dep{$service} } ) {
my @values = ( \undef, $service_name{$service}, $mhn, $sn_dep{$service}{$mhn} );
$result = StorProc->insert_obj( 'servicename_dependency', \@values );
if ( $debug && $result =~ /error/i ) {
update_status( 'error', $result );
}
}
}
# serviceextinfo templates
update_status( 'info', 'Loading service extended info templates ...' );
my %sn_extinfo = ();
%where = ( 'type' => 'serviceextinfo_template' );
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
foreach my $key ( keys %objects ) {
$read++;
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
foreach my $prop ( keys %data ) {
unless ( $data{'service_description'} ) {
$serviceextinfo_templates{ $objects{$key}[0] }{$prop} = $data{$prop};
}
}
if ( $serviceextinfo_templates{ $objects{$key}[0] }{'id'} ) {
$updated++;
my %values = ();
$values{'data'} = $objects{$key}[3];
$values{'comment'} = $objects{$key}[4];
StorProc->update_obj( 'extended_service_info_templates', 'name', $objects{$key}[0], \%values );
}
else {
$imported++;
my @values = ( \undef, $objects{$key}[0], $objects{$key}[3], '', $objects{$key}[4] );
$result = StorProc->insert_obj_id( 'extended_service_info_templates', \@values, 'serviceextinfo_id' );
if ( $result =~ /Error/i ) {
update_status( 'error', $result );
}
else {
$serviceextinfo_templates{ $objects{$key}[0] }{'id'} = $result;
}
}
if ( $data{'service_description'} ) {
$sn_extinfo{ $data{'service_description'} } = $serviceextinfo_templates{ $objects{$key}[0] }{'id'};
}
}
StorProc->delete_one_where( 'stage_other', \%where );
update_status( 'info', "Service extended info templates: $read read, $updated updated, $imported imported." );
# Service extended info
$read = $updated = $imported = 0;
use URI::Escape;
update_status( 'info', 'Loading service extended info ...' );
%where = ( 'type' => 'serviceextinfo' );
my %service_desc = ();
%objects = StorProc->fetch_list_hash_array( 'stage_other', \%where );
$index = StorProc->count('extended_service_info_templates');
foreach my $key ( keys %objects ) {
my %data = StorProc->parse_xml( $objects{$key}[3] );
update_status( 'error', delete $data{'error'} ) if defined $data{'error'};
if ( $data{'notes_url'} ) {
$data{'notes_url'} = uri_unescape( $data{'notes_url'} );
if ( $host_name{ $objects{$key}[2] } ) {
$data{'notes_url'} =~ s/$objects{$key}[2]/\$HOSTNAME\$/g;
}
if ( $service_name{ $objects{$key}[0] } ) {
$data{'notes_url'} =~ s/$objects{$key}[0]/\$SERVICENAME\$/g;
}
$data{'notes_url'} =~ s/\s/+/g;
}
if ( $data{'action_url'} ) {
$data{'action_url'} = uri_unescape( $data{'action_url'} );
if ( $host_name{ $objects{$key}[2] } ) {
$data{'action_url'} =~ s/$objects{$key}[2]/\$HOSTNAME\$/g;
}
if ( $service_name{ $objects{$key}[0] } ) {
$data{'action_url'} =~ s/$objects{$key}[0]/\$SERVICENAME\$/g;
}
$data{'action_url'} =~ s/\s/+/g;
}
unless ( $data{'use'} ) {
my $props = 0;
foreach ( keys %data ) { $props++ }
if ( $data{'host_name'} ) { $props -= 1 }
if ( $data{'service_description'} ) { $props -= 1 }
my %gotmatch = ();
foreach my $temp ( keys %serviceextinfo_templates ) {
foreach my $d ( keys %data ) {
if ( $data{$d} eq $serviceextinfo_templates{$temp}{$d} ) {
$gotmatch{$temp} += 1;
}
}
}
my $match = undef;
my $best = 0;
foreach my $key ( keys %gotmatch ) {
if ( $gotmatch{$key} > $best ) {
$match = $key;
$best = $gotmatch{$key};
}
}
if ( $gotmatch{$match} == $props ) { $data{'use'} = $match }
$sn_extinfo{ $objects{$key}[0] } = $data{'use'};
unless ( $data{'use'} ) {
my $name = undef;
unless ( $service_desc{ $objects{$key}[0] } ) {
$name = lc("$objects{$key}[0]-$index");
$name =~ s/_|\s/-/g;
$service_desc{ $objects{$key}[0] } = 1;
}
elsif ( $data{'icon_image_alt'} ) {
$name = lc("$data{'icon_image_alt'}-$index");
$name =~ s/_|\s/-/g;
}
elsif ( $data{'icon_image'} ) {
$name = lc("$data{'icon_image'}-$index");
$name =~ s/_|\s|\./-/g;
}
else {
$name = "generic-serviceextinfo-$index";
}
my $data_xml = $xml_begin;
foreach my $prop ( keys %data ) {
if ( $prop =~ /host_name/ ) { next }
$data_xml .= " \n";
$data_xml .= " \n";
$serviceextinfo_templates{ $data{'use'} }{$prop} = $data{$prop};
}
$data_xml .= $xml_end;
$data{'use'} = $name;
my $comment = undef;
my @values = ( \undef, $name, $data_xml, '', $comment );
$result = StorProc->insert_obj_id( 'extended_service_info_templates', \@values, 'serviceextinfo_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$serviceextinfo_templates{ $data{'use'} }{'id'} = $result;
}
}
}
else {
if ( $serviceextinfo_templates{ $data{'use'} }{'id'} && !$serviceextinfo_templates{ $data{'use'} }{'updated'} ) {
$sn_extinfo{ $objects{$key}[0] } = $serviceextinfo_templates{ $data{'use'} }{'id'};
my %values = ();
if ( $data{'notes_url'} ) {
unless ( $data{'notes_url'} eq $serviceextinfo_templates{ $data{'use'} }{'notes_url'} ) {
$serviceextinfo_templates{ $data{'use'} }{'notes_url'} = $data{'notes_url'};
}
}
if ( $data{'action_url'} ) {
unless ( $data{'action_url'} eq $serviceextinfo_templates{ $data{'use'} }{'action_url'} ) {
$serviceextinfo_templates{ $data{'use'} }{'action_url'} = $data{'action_url'};
}
}
if ( $data{'notes'} ) {
unless ( $data{'notes'} eq $serviceextinfo_templates{ $data{'use'} }{'notes'} ) {
$serviceextinfo_templates{ $data{'use'} }{'notes'} = $data{'notes'};
}
}
my $data_xml = $xml_begin;
foreach my $prop ( keys %{ $serviceextinfo_templates{ $data{'use'} } } ) {
unless ( $prop =~ /script|name|id|comment/ ) {
$data_xml .= " \n";
$data_xml .= " \n";
}
}
$data_xml .= $xml_end;
my %w = ( 'name' => $data{'use'} );
my %u = ( 'data' => $data_xml );
StorProc->update_obj_where( 'extended_service_info_templates', \%u, \%w );
$serviceextinfo_templates{ $data{'use'} }{'updated'} = 1;
}
}
$sn_extinfo{ $objects{$key}[0] } = $serviceextinfo_templates{ $data{'use'} }{'id'};
}
StorProc->delete_one_where( 'stage_other', \%where );
foreach my $service ( keys %sn_extinfo ) {
my %w = ( 'name' => $service );
my %u = ( 'extinfo' => $sn_extinfo{$service} );
StorProc->update_obj_where( 'service_names', \%u, \%w );
%w = ( 'servicename_id' => $service_name{$service} );
%u = ( 'serviceextinfo_id' => $sn_extinfo{$service} );
StorProc->update_obj_where( 'services', \%u, \%w );
}
return @messages;
}
############################################################################
######
###### Break
######
############################################################################
# host escalations
sub process_host_escalations() {
my $temp_created = 0;
my $trees_created = 0;
StorProc->truncate_table('escalation_tree_template', 'escalation_trees');
my %timeperiod_name = StorProc->get_table_objects('time_periods');
my %contactgroup_name = StorProc->get_table_objects('contactgroups');
my %host_name = StorProc->get_table_objects('hosts');
my %hostgroup_name = StorProc->get_table_objects('hostgroups');
my %escalation_templates = ();
my $result;
update_status( 'info', 'Loading host/hostgroup escalation templates ...' );
my %temp_templates = ();
my %objects = StorProc->get_staged_escalation_templates('host');
my $index = 0;
foreach my $obj ( keys %objects ) {
if ( $objects{$obj}{'contact_groups'} ) {
$temp_templates{$obj}{'contact_groups'} = $objects{$obj}{'contact_groups'};
}
if ( $objects{$obj}{'host_name'} ) {
$temp_templates{$obj}{'host_name'} = $objects{$obj}{'host_name'};
}
if ( $objects{$obj}{'hostgroup_name'} ) {
$temp_templates{$obj}{'hostgroup_name'} = $objects{$obj}{'hostgroup_name'};
}
if ( $objects{$obj}{'first_notification'} ) {
$temp_templates{$obj}{'first_notification'} = $objects{$obj}{'first_notification'};
}
if ( $objects{$obj}{'last_notification'} ) {
$temp_templates{$obj}{'last_notification'} = $objects{$obj}{'last_notification'};
}
if ( $objects{$obj}{'notification_interval'} ) {
$temp_templates{$obj}{'notification_interval'} = $objects{$obj}{'notification_interval'};
}
if ( $objects{$obj}{'escalation_options'} ) {
$temp_templates{$obj}{'escalation_options'} = $objects{$obj}{'escalation_options'};
}
unless ( $objects{$obj}{'escalation_options'} ) {
$objects{$obj}{'escalation_options'} = 'all';
}
if ( $objects{$obj}{'escalation_period'} ) {
$temp_templates{$obj}{'escalation_period'} = $objects{$obj}{'escalation_period'};
}
unless ( $objects{$obj}{'escalation_period'} ) {
$objects{$obj}{'escalation_period'} = '24x7';
}
# match with existing templates
my $matched = 0;
foreach my $temp ( keys %escalation_templates ) {
if ( $objects{$obj}{'first_notification'} eq $escalation_templates{$temp}{'first_notification'} ) {
$matched++;
}
if ( $objects{$obj}{'last_notification'} eq $escalation_templates{$temp}{'last_notification'} ) {
$matched++;
}
if ( $objects{$obj}{'notification_interval'} eq $escalation_templates{$temp}{'notification_interval'} ) {
$matched++;
}
if ( $objects{$obj}{'escalation_period'} eq $escalation_templates{$temp}{'escalation_period'} ) {
$matched++;
}
if ( $objects{$obj}{'escalation_options'} eq $escalation_templates{$temp}{'escalation_options'} ) {
$matched++;
}
}
unless ( $matched == 5 ) {
my $escalation = $objects{$obj}{'first_notification'};
if ( $escalation eq '-zero-' ) { $escalation = '0' }
my $last = $objects{$obj}{'last_notification'};
if ( $last eq '-zero-' ) { $last = '0' }
my $interval = $objects{$obj}{'notification_interval'};
if ( $interval eq '-zero-' ) { $last = '0' }
my $options = $objects{$obj}{'escalation_options'};
unless ($options) { $options = 'all' }
my $period = $objects{$obj}{'escalation_period'};
unless ($period) { $period = '24x7' }
my $name = "host_escalation_$escalation:last_$last:interval_$interval:options_$options:period_$period";
$name =~ s/,/./g;
$name =~ s/-zero-/0/g;
$escalation_templates{$name}{'first_notification'} = $objects{$obj}{'first_notification'};
$escalation_templates{$name}{'last_notification'} = $objects{$obj}{'last_notification'};
$escalation_templates{$name}{'notification_interval'} = $objects{$obj}{'notification_interval'};
$escalation_templates{$name}{'escalation_period'} = $objects{$obj}{'escalation_period'};
$escalation_templates{$name}{'escalation_options'} = $objects{$obj}{'escalation_options'};
}
$matched = 0;
}
foreach my $temp ( keys %escalation_templates ) {
my $data_xml = $xml_begin;
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= $xml_end;
my @values = (
\undef, $temp, 'host', $data_xml,
$escalation_templates{$temp}{'comment'},
$timeperiod_name{ $escalation_templates{$temp}{'escalation_period'} }
);
$result = StorProc->insert_obj_id( 'escalation_templates', \@values, 'template_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$escalation_templates{$temp}{'id'} = $result;
$temp_created++;
}
}
my %staged_escalations = StorProc->get_staged_escalations('host');
# find or create templates for each escalation
foreach my $esc ( keys %staged_escalations ) {
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'escalation_period'} ) {
unless ( $staged_escalations{$esc}{'escalation_period'} ) {
$staged_escalations{$esc}{'escalation_period'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'escalation_period'};
}
}
unless ( $staged_escalations{$esc}{'escalation_period'} ) {
$staged_escalations{$esc}{'escalation_period'} = '24x7';
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'escalation_options'} ) {
unless ( $staged_escalations{$esc}{'escalation_options'} ) {
$staged_escalations{$esc}{'escalation_options'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'escalation_options'};
}
}
unless ( $staged_escalations{$esc}{'escalation_options'} ) {
$staged_escalations{$esc}{'escalation_options'} = 'all';
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'contact_groups'} ) {
unless ( $staged_escalations{$esc}{'contact_groups'} ) {
$staged_escalations{$esc}{'contact_groups'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'contact_groups'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'host_name'} ) {
unless ( $staged_escalations{$esc}{'host_name'} ) {
$staged_escalations{$esc}{'host_name'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'host_name'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'hostgroup_name'} ) {
unless ( $staged_escalations{$esc}{'hostgroup_name'} ) {
$staged_escalations{$esc}{'hostgroup_name'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'hostgroup_name'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'last_notification'} ) {
unless ( $staged_escalations{$esc}{'last_notification'} ) {
$staged_escalations{$esc}{'last_notification'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'last_notification'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'first_notification'} ) {
unless ( $staged_escalations{$esc}{'first_notification'} ) {
$staged_escalations{$esc}{'first_notification'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'first_notification'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'notification_interval'} ) {
unless ( $staged_escalations{$esc}{'notification_interval'} ) {
$staged_escalations{$esc}{'notification_interval'} =
$temp_templates{ $staged_escalations{$esc}{'use'} }{'notification_interval'};
}
}
my $template = undef;
my $matched = 0;
foreach my $temp ( keys %escalation_templates ) {
if ( $staged_escalations{$esc}{'first_notification'} eq $escalation_templates{$temp}{'first_notification'} ) {
$matched++;
}
if ( $staged_escalations{$esc}{'last_notification'} eq $escalation_templates{$temp}{'last_notification'} ) {
$matched++;
}
if ( $staged_escalations{$esc}{'notification_interval'} eq $escalation_templates{$temp}{'notification_interval'} ) {
$matched++;
}
if ( $staged_escalations{$esc}{'escalation_period'} eq $escalation_templates{$temp}{'escalation_period'} ) {
$matched++;
}
if ( $staged_escalations{$esc}{'escalation_options'} eq $escalation_templates{$temp}{'escalation_options'} ) {
$matched++;
}
if ( $matched == 5 ) {
$template = $temp;
$staged_escalations{$esc}{'use'} = $temp;
last;
}
$matched = 0;
}
unless ($template) {
my $escalation = $staged_escalations{$esc}{'first_notification'};
if ( $escalation eq '-zero-' ) { $escalation = '0' }
my $last = $staged_escalations{$esc}{'last_notification'};
if ( $last eq '-zero-' ) { $last = '0' }
my $interval = $staged_escalations{$esc}{'notification_interval'};
if ( $interval eq '-zero-' ) { $last = '0' }
my $options = $staged_escalations{$esc}{'escalation_options'};
unless ($options) { $options = 'all' }
my $period = $staged_escalations{$esc}{'escalation_period'};
unless ($period) { $period = '24x7' }
my $name = "host_escalation_$escalation:last_$last:interval_$interval:options_$options:period_$period";
$name =~ s/,/./g;
$name =~ s/-zero-/0/g;
$escalation_templates{$name}{'first_notification'} = $staged_escalations{$esc}{'first_notification'};
$escalation_templates{$name}{'last_notification'} = $staged_escalations{$esc}{'last_notification'};
$escalation_templates{$name}{'notification_interval'} = $staged_escalations{$esc}{'notification_interval'};
$escalation_templates{$name}{'escalation_period'} = $staged_escalations{$esc}{'escalation_period'};
$escalation_templates{$name}{'escalation_options'} = $staged_escalations{$esc}{'escalation_options'};
$escalation_templates{$name}{'comment'} = $staged_escalations{$esc}{'comment'};
my $data_xml = $xml_begin;
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= $xml_end;
my @values = (
\undef, $name, 'host', $data_xml,
$escalation_templates{$name}{'comment'},
$timeperiod_name{ $escalation_templates{$name}{'escalation_period'} }
);
$result = StorProc->insert_obj_id( 'escalation_templates', \@values, 'template_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$escalation_templates{$name}{'id'} = $result;
$staged_escalations{$esc}{'use'} = $name;
$temp_created++;
}
}
}
# create template_contactgroups template_hosts template_hostgroups template_servicegroups template_service
my %trees = ();
my %tree_name = ();
foreach my $esc ( keys %staged_escalations ) {
if ( $staged_escalations{$esc}{'host_name'} ) {
$trees{ $staged_escalations{$esc}{'host_name'} }{ $staged_escalations{$esc}{'use'} }
{ $staged_escalations{$esc}{'contact_groups'} } = 1;
$tree_name{ $staged_escalations{$esc}{'host_name'} } = 'host';
}
if ( $staged_escalations{$esc}{'hostgroup_name'} ) {
$trees{ $staged_escalations{$esc}{'hostgroup_name'} }{ $staged_escalations{$esc}{'use'} }
{ $staged_escalations{$esc}{'contact_groups'} } = 1;
$tree_name{ $staged_escalations{$esc}{'hostgroup_name'} } = 'hostgroup';
}
}
$index = 0;
foreach my $tree ( keys %trees ) {
my @vals = split( /,/, $tree );
my $name = $tree_name{$tree};
if ( $vals[3] ) {
$name .= "($vals[0]-$vals[1]-$vals[2]...)";
}
elsif ( $vals[2] ) {
$name .= "($vals[0]-$vals[1]-$vals[2])";
}
elsif ( $vals[1] ) {
$name .= "($vals[0]-$vals[1])";
}
elsif ( $vals[0] =~ /^\*$|^\.\*$/ ) {
$name .= "default";
}
elsif ( $vals[0] =~ /\*|\.\*/ ) {
$name .= "generic-$index";
$index++;
}
else {
$name .= "$vals[0]";
}
my @values = ( \undef, $name, $tree, 'host' );
$result = StorProc->insert_obj_id( 'escalation_trees', \@values, 'tree_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
my $tree_id = $result;
$trees_created++;
if ( $tree_name{$tree} eq 'hostgroup' ) {
if ( $tree =~ /^\*$|^\.\*$/ ) {
StorProc->set_default_hostgroup_escalations($tree_id);
}
else {
my %hostgroups = ();
my @hostgroupnames = split( /,/, $tree );
foreach my $hn (@hostgroupnames) {
$hn =~ s/^\s+|\s+$//g;
foreach my $hostgroup ( keys %hostgroup_name ) {
if ( $hostgroup =~ /^$hn$/i ) {
## FIX MAJOR: fix the next line: Useless use of hash element in void context
$hostgroups{ $hostgroup_name{$hostgroup} };
}
}
}
foreach my $hostgroup ( keys %hostgroups ) {
my %values = ( 'host_escalation_id' => $tree_id );
my $err = StorProc->update_obj( 'hostgroups', 'hostgroup_id', $hostgroup, \%values );
}
}
}
else {
if ( $tree =~ /^\*$|^\.\*$/ ) {
StorProc->set_default_host_escalations($tree_id);
}
else {
my %hosts = ();
my @hostnames = split( /,/, $tree );
foreach my $hn (@hostnames) {
$hn =~ s/^\s+|\s+$//g;
foreach my $host ( keys %host_name ) {
if ( $host =~ /^$hn$/i ) {
$hosts{ $host_name{$host} } = 1;
}
}
}
foreach my $host ( keys %hosts ) {
my %values = ( 'host_escalation_id' => $tree_id );
StorProc->update_obj( 'hosts', 'host_id', $host, \%values );
}
}
}
foreach my $temp ( keys %{ $trees{$tree} } ) {
@vals = ( $tree_id, $escalation_templates{$temp}{'id'} );
$result = StorProc->insert_obj( 'escalation_tree_template', \@vals );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
foreach my $contactgroup ( keys %{ $trees{$tree}{$temp} } ) {
my @contact_grps = split( /,/, $contactgroup );
foreach my $grp (@contact_grps) {
if ( $contactgroup_name{$grp} ) {
@vals = ( $tree_id, $escalation_templates{$temp}{'id'}, $contactgroup_name{$grp} );
$result = StorProc->insert_obj( 'tree_template_contactgroup', \@vals );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
}
}
}
}
}
}
update_status( 'info', "Host escalations: $temp_created escalations created, $trees_created trees created." );
return @messages;
}
############################################################################
######
###### Break
######
############################################################################
# service escalations
sub process_service_escalations() {
my $temp_created = 0;
my $trees_created = 0;
my %timeperiod_name = StorProc->get_table_objects('time_periods');
my %contactgroup_name = StorProc->get_table_objects('contactgroups');
my %host_name = StorProc->get_table_objects('hosts');
my %hostgroup_name = StorProc->get_table_objects('hostgroups');
my %service_name = StorProc->get_table_objects('service_names');
my %servicegroup_name = StorProc->get_table_objects('servicegroups');
my %escalation_templates = ();
my $result;
update_status( 'info', 'Loading service escalation templates ...' );
my %temp_templates = ();
my %objects = StorProc->get_staged_escalation_templates('service');
my $index = 0;
foreach my $obj ( keys %objects ) {
if ( $objects{$obj}{'contact_groups'} ) {
$temp_templates{$obj}{'contact_groups'} = $objects{$obj}{'contact_groups'};
}
if ( $objects{$obj}{'host_name'} ) {
$temp_templates{$obj}{'host_name'} = $objects{$obj}{'host_name'};
}
if ( $objects{$obj}{'hostgroup_name'} ) {
$temp_templates{$obj}{'hostgroup_name'} = $objects{$obj}{'hostgroup_name'};
}
if ( $objects{$obj}{'service_description'} ) {
$temp_templates{$obj}{'service_description'} = $objects{$obj}{'service_description'};
}
if ( $objects{$obj}{'servicegroup_name'} ) {
$temp_templates{$obj}{'servicegroup_name'} = $objects{$obj}{'servicegroup_name'};
}
if ( $objects{$obj}{'first_notification'} ) {
$temp_templates{$obj}{'first_notification'} = $objects{$obj}{'first_notification'};
}
if ( $objects{$obj}{'last_notification'} ) {
$temp_templates{$obj}{'last_notification'} = $objects{$obj}{'last_notification'};
}
if ( $objects{$obj}{'notification_interval'} ) {
$temp_templates{$obj}{'notification_interval'} = $objects{$obj}{'notification_interval'};
}
if ( $objects{$obj}{'escalation_options'} ) {
$temp_templates{$obj}{'escalation_options'} = $objects{$obj}{'escalation_options'};
}
unless ( $objects{$obj}{'escalation_options'} ) {
$objects{$obj}{'escalation_options'} = 'all';
}
if ( $objects{$obj}{'escalation_period'} ) {
$temp_templates{$obj}{'escalation_period'} = $objects{$obj}{'escalation_period'};
}
unless ( $objects{$obj}{'escalation_period'} ) {
$objects{$obj}{'escalation_period'} = '24x7';
}
# match with existing templates
my $matched = 0;
foreach my $temp ( keys %escalation_templates ) {
if ( $objects{$obj}{'first_notification'} eq $escalation_templates{$temp}{'first_notification'} ) {
$matched++;
}
if ( $objects{$obj}{'last_notification'} eq $escalation_templates{$temp}{'last_notification'} ) {
$matched++;
}
if ( $objects{$obj}{'notification_interval'} eq $escalation_templates{$temp}{'notification_interval'} ) {
$matched++;
}
if ( $objects{$obj}{'escalation_period'} eq $escalation_templates{$temp}{'escalation_period'} ) {
$matched++;
}
if ( $objects{$obj}{'escalation_options'} eq $escalation_templates{$temp}{'escalation_options'} ) {
$matched++;
}
}
unless ( $matched == 5 ) {
my $escalation = $objects{$obj}{'first_notification'};
if ( $escalation eq '-zero-' ) { $escalation = '0' }
my $last = $objects{$obj}{'last_notification'};
if ( $last eq '-zero-' ) { $last = '0' }
my $interval = $objects{$obj}{'notification_interval'};
if ( $interval eq '-zero-' ) { $last = '0' }
my $options = $objects{$obj}{'escalation_options'};
unless ($options) { $options = 'all' }
my $period = $objects{$obj}{'escalation_period'};
unless ($period) { $period = '24x7' }
my $name = "service_escalation_$escalation:last_$last:interval_$interval:options_$options:period_$period";
$name =~ s/,/./g;
$name =~ s/-zero-/0/g;
$escalation_templates{$name}{'first_notification'} = $objects{$obj}{'first_notification'};
$escalation_templates{$name}{'last_notification'} = $objects{$obj}{'last_notification'};
$escalation_templates{$name}{'notification_interval'} = $objects{$obj}{'notification_interval'};
$escalation_templates{$name}{'escalation_period'} = $objects{$obj}{'escalation_period'};
$escalation_templates{$name}{'escalation_options'} = $objects{$obj}{'escalation_options'};
}
$matched = 0;
}
foreach my $temp ( keys %escalation_templates ) {
my $data_xml = $xml_begin;
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= $xml_end;
my @values = (
\undef, $temp, 'service', $data_xml,
$escalation_templates{$temp}{'comment'},
$timeperiod_name{ $escalation_templates{$temp}{'escalation_period'} }
);
$result = StorProc->insert_obj_id( 'escalation_templates', \@values, 'template_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$escalation_templates{$temp}{'id'} = $result;
$temp_created++;
}
}
my %staged_escalations = StorProc->get_staged_escalations('service');
# find or create templates for each escalation
foreach my $esc ( keys %staged_escalations ) {
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'escalation_period'} ) {
unless ( $staged_escalations{$esc}{'escalation_period'} ) {
$staged_escalations{$esc}{'escalation_period'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'escalation_period'};
}
}
unless ( $staged_escalations{$esc}{'escalation_period'} ) {
$staged_escalations{$esc}{'escalation_period'} = '24x7';
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'escalation_options'} ) {
unless ( $staged_escalations{$esc}{'escalation_options'} ) {
$staged_escalations{$esc}{'escalation_options'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'escalation_options'};
}
}
unless ( $staged_escalations{$esc}{'escalation_options'} ) {
$staged_escalations{$esc}{'escalation_options'} = 'all';
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'contact_groups'} ) {
unless ( $staged_escalations{$esc}{'contact_groups'} ) {
$staged_escalations{$esc}{'contact_groups'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'contact_groups'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'host_name'} ) {
unless ( $staged_escalations{$esc}{'host_name'} ) {
$staged_escalations{$esc}{'host_name'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'host_name'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'hostgroup_name'} ) {
unless ( $staged_escalations{$esc}{'hostgroup_name'} ) {
$staged_escalations{$esc}{'hostgroup_name'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'hostgroup_name'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'servicegroup_name'} ) {
unless ( $staged_escalations{$esc}{'servicegroup_name'} ) {
$staged_escalations{$esc}{'servicegroup_name'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'servicegroup_name'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'service_description'} ) {
unless ( $staged_escalations{$esc}{'service_description'} ) {
$staged_escalations{$esc}{'service_description'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'service_description'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'last_notification'} ) {
unless ( $staged_escalations{$esc}{'last_notification'} ) {
$staged_escalations{$esc}{'last_notification'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'last_notification'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'first_notification'} ) {
unless ( $staged_escalations{$esc}{'first_notification'} ) {
$staged_escalations{$esc}{'first_notification'} = $temp_templates{ $staged_escalations{$esc}{'use'} }{'first_notification'};
}
}
if ( $temp_templates{ $staged_escalations{$esc}{'use'} }{'notification_interval'} ) {
unless ( $staged_escalations{$esc}{'notification_interval'} ) {
$staged_escalations{$esc}{'notification_interval'} =
$temp_templates{ $staged_escalations{$esc}{'use'} }{'notification_interval'};
}
}
my $template = 0;
my $matched = 0;
foreach my $temp ( keys %escalation_templates ) {
if ( $staged_escalations{$esc}{'first_notification'} eq $escalation_templates{$temp}{'first_notification'} ) {
$matched++;
}
if ( $staged_escalations{$esc}{'last_notification'} eq $escalation_templates{$temp}{'last_notification'} ) {
$matched++;
}
if ( $staged_escalations{$esc}{'notification_interval'} eq $escalation_templates{$temp}{'notification_interval'} ) {
$matched++;
}
if ( $staged_escalations{$esc}{'escalation_period'} eq $escalation_templates{$temp}{'escalation_period'} ) {
$matched++;
}
if ( $staged_escalations{$esc}{'escalation_options'} eq $escalation_templates{$temp}{'escalation_options'} ) {
$matched++;
}
if ( $matched == 5 ) {
$template = $temp;
$staged_escalations{$esc}{'use'} = $temp;
last;
}
$matched = 0;
}
unless ($template) {
my $escalation = $staged_escalations{$esc}{'first_notification'};
if ( $escalation eq '-zero-' ) { $escalation = '0' }
my $last = $staged_escalations{$esc}{'last_notification'};
if ( $last eq '-zero-' ) { $last = '0' }
my $interval = $staged_escalations{$esc}{'notification_interval'};
if ( $interval eq '-zero-' ) { $last = '0' }
my $options = $staged_escalations{$esc}{'escalation_options'};
unless ($options) { $options = 'all' }
my $period = $staged_escalations{$esc}{'escalation_period'};
unless ($period) { $period = '24x7' }
my $name = "service_escalation_$escalation:last_$last:interval_$interval:options_$options:period_$period";
$name =~ s/,/./g;
$name =~ s/-zero-/0/g;
$escalation_templates{$name}{'first_notification'} = $staged_escalations{$esc}{'first_notification'};
$escalation_templates{$name}{'last_notification'} = $staged_escalations{$esc}{'last_notification'};
$escalation_templates{$name}{'notification_interval'} = $staged_escalations{$esc}{'notification_interval'};
$escalation_templates{$name}{'escalation_period'} = $staged_escalations{$esc}{'escalation_period'};
$escalation_templates{$name}{'escalation_options'} = $staged_escalations{$esc}{'escalation_options'};
$escalation_templates{$name}{'comment'} = $staged_escalations{$esc}{'comment'};
my $data_xml = $xml_begin;
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= " \n";
$data_xml .= $xml_end;
my @values = (
\undef, $name, 'service', $data_xml,
$escalation_templates{$name}{'comment'},
$timeperiod_name{ $escalation_templates{$name}{'escalation_period'} }
);
$result = StorProc->insert_obj_id( 'escalation_templates', \@values, 'template_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
$escalation_templates{$name}{'id'} = $result;
$staged_escalations{$esc}{'use'} = $name;
$temp_created++;
}
}
}
# create template_contactgroups template_hosts template_hostgroups template_servicegroups template_service
my %trees = ();
my %tree_name = ();
my %tree_service = ();
my %tree_hosts = ();
my %tree_hostgroups = ();
foreach my $esc ( keys %staged_escalations ) {
if ( $staged_escalations{$esc}{'host_name'} && $staged_escalations{$esc}{'service_description'} =~ /\*|\.\*/ ) {
$trees{ $staged_escalations{$esc}{'host_name'} }{ $staged_escalations{$esc}{'use'} }
{ $staged_escalations{$esc}{'contact_groups'} } = 1;
$tree_name{ $staged_escalations{$esc}{'host_name'} } = 'host';
}
if ( $staged_escalations{$esc}{'hostgroup_name'} && $staged_escalations{$esc}{'service_description'} =~ /\*|\.\*/ ) {
$trees{ $staged_escalations{$esc}{'hostgroup_name'} }{ $staged_escalations{$esc}{'use'} }
{ $staged_escalations{$esc}{'contact_groups'} } = 1;
$tree_name{ $staged_escalations{$esc}{'hostgroup_name'} } = 'hostgroup';
}
if ( $staged_escalations{$esc}{'servicegroup_name'} && $staged_escalations{$esc}{'service_description'} =~ /\*|\.\*/ ) {
$trees{ $staged_escalations{$esc}{'servicegroup_name'} }{ $staged_escalations{$esc}{'use'} }
{ $staged_escalations{$esc}{'contact_groups'} } = 1;
$tree_name{ $staged_escalations{$esc}{'servicegroup_name'} } = 'servicegroup';
}
if ( $staged_escalations{$esc}{'service_description'} && $staged_escalations{$esc}{'service_description'} !~ /\*|\.\*/ ) {
if ( $staged_escalations{$esc}{'host_name'} ) {
$trees{ $staged_escalations{$esc}{'host_name'} }{ $staged_escalations{$esc}{'use'} }
{ $staged_escalations{$esc}{'contact_groups'} } = 1;
$tree_name{ $staged_escalations{$esc}{'host_name'} } = 'service';
$tree_service{ $staged_escalations{$esc}{'host_name'} } = $staged_escalations{$esc}{'service_description'};
$tree_hosts{ $staged_escalations{$esc}{'host_name'} } = $staged_escalations{$esc}{'host_name'};
}
if ( $staged_escalations{$esc}{'hostgroup_name'} ) {
$trees{ $staged_escalations{$esc}{'hostgroup_name'} }{ $staged_escalations{$esc}{'use'} }
{ $staged_escalations{$esc}{'contact_groups'} } = 1;
$tree_name{ $staged_escalations{$esc}{'hostgroup_name'} } = 'service';
$tree_service{ $staged_escalations{$esc}{'hostgroup_name'} } = $staged_escalations{$esc}{'service_description'};
$tree_hostgroups{ $staged_escalations{$esc}{'hostgroup_name'} } = $staged_escalations{$esc}{'hostgroup_name'};
}
}
}
$index = 0;
foreach my $tree ( keys %trees ) {
my @vals = split( /,/, $tree );
my $name = $tree_name{$tree};
if ( $vals[3] ) {
$name .= "-service($vals[0]-$vals[1]-$vals[2]...)";
}
elsif ( $vals[2] ) {
$name .= "-service($vals[0]-$vals[1]-$vals[2])";
}
elsif ( $vals[1] ) {
$name .= "-service($vals[0]-$vals[1])";
}
elsif ( $vals[0] =~ /^\*$|^\.\*$/ ) {
$name .= "-default-service";
}
elsif ( $vals[0] =~ /\*|\.\*/ ) {
$name .= "-generic-service-$index";
$index++;
}
else {
$name .= "-service-$vals[0]";
}
if ( $name =~ /^service-service/ ) { $name =~ s/^service-// }
my @values = ( \undef, $name, $tree, 'service' );
$result = StorProc->insert_obj_id( 'escalation_trees', \@values, 'tree_id' );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
else {
my $tree_id = $result;
$trees_created++;
if ( $tree_name{$tree} eq 'hostgroup' ) {
if ( $tree =~ /^\*$|^\.\*$/ ) {
StorProc->set_default_hostgroup_escalations($tree_id);
}
else {
my %hostgroups = ();
my @hostgroupnames = split( /,/, $tree );
foreach my $hn (@hostgroupnames) {
$hn =~ s/^\s+|\s+$//g;
my $got_hostgroup = 0;
foreach my $hostgroup ( keys %hostgroup_name ) {
if ( $hostgroup =~ /^$hn$/i ) {
$hostgroups{ $hostgroup_name{$hostgroup} } = 1;
}
}
}
foreach my $hostgroup ( keys %hostgroups ) {
my %values = ( 'service_escalation_id' => $tree_id );
my $err = StorProc->update_obj( 'hostgroups', 'hostgroup_id', $hostgroup, \%values );
}
}
}
elsif ( $tree_name{$tree} eq 'host' ) {
if ( $tree =~ /^\*$|^\.\*$/ ) {
StorProc->set_default_host_escalations($tree_id);
}
else {
my %hosts = ();
my @hostnames = split( /,/, $tree );
foreach my $hn (@hostnames) {
$hn =~ s/^\s+|\s+$//g;
foreach my $host ( keys %host_name ) {
if ( $host eq /^$hn$/i ) {
$hosts{ $host_name{$host} } = 1;
}
}
}
foreach my $host ( keys %hosts ) {
my %values = ( 'service_escalation_id' => $tree_id );
StorProc->update_obj( 'hosts', 'host_id', $host, \%values );
}
}
}
elsif ( $tree_name{$tree} eq 'servicegroup' ) {
if ( $tree =~ /^\*$|^\.\*$/ ) {
StorProc->set_default_servicegroup_escalations($tree_id);
}
else {
my %servicegroups = ();
my @servicegroupnames = split( /,/, $tree );
foreach my $sgn (@servicegroupnames) {
$sgn =~ s/^\s+|\s+$//g;
foreach my $servicegroup ( keys %servicegroup_name ) {
if ( $servicegroup =~ /^$sgn$/i ) {
$servicegroups{ $servicegroup_name{$servicegroup} } = 1;
}
}
}
foreach my $servicegroup ( keys %servicegroups ) {
my %values = ( 'escalation_id' => $tree_id );
StorProc->update_obj( 'servicegroups', 'servicegroup_id', $servicegroup, \%values );
}
}
}
elsif ( $tree_name{$tree} eq 'service' ) {
my %services = ();
my %hosts = ();
my @hostnames = ();
if ( $tree_hostgroups{$tree} ) {
if ( $tree_hostgroups{$tree} =~ /^\*$|^\.\*$/ ) {
@hostnames = StorProc->fetch_list( 'hosts', 'name' );
}
else {
my @hostgroupnames = split( /,/, $tree_hostgroups{$tree} );
foreach my $host (@hostgroupnames) {
my @hosts = StorProc->fetch_list( 'hosts', 'name' );
push( @hostnames, (@hosts) );
}
}
}
elsif ( $tree_hosts{$tree} ) {
if ( $tree_hosts{$tree} =~ /^\*$|^\.\*$/ ) {
@hostnames = StorProc->fetch_list( 'hosts', 'name' );
}
else {
@hostnames = split( /,/, $tree_hosts{$tree} );
}
}
foreach my $hn (@hostnames) {
$hn =~ s/^\s+|\s+$//g;
foreach my $host ( keys %host_name ) {
if ( $host =~ /^$hn$/i ) { $hosts{ $host_name{$host} } = 1 }
}
}
my @servicenames = split( /,/, $tree_service{$tree} );
foreach my $sn (@servicenames) {
$sn =~ s/^\s+|\s+$//g;
foreach my $service ( keys %service_name ) {
if ( $service =~ /^$sn$/i ) {
$services{ $service_name{$service} } = 1;
}
}
}
foreach my $service ( keys %services ) {
foreach my $hostid ( keys %hosts ) {
my %where = ( 'host_id' => $hostid, 'servicename_id' => $service );
my %values = ( 'escalation_id' => $tree_id );
StorProc->update_obj_where( 'services', \%values, \%where );
}
my %values = ( 'escalation' => $tree_id );
StorProc->update_obj( 'service_names', 'servicename_id', $service, \%values );
}
}
my %tcg_exists = ();
foreach my $temp ( keys %{ $trees{$tree} } ) {
@vals = ( $tree_id, $escalation_templates{$temp}{'id'} );
$result = StorProc->insert_obj( 'escalation_tree_template', \@vals );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
foreach my $contactgroup ( keys %{ $trees{$tree}{$temp} } ) {
my @contact_grps = split( /,/, $contactgroup );
foreach my $grp (@contact_grps) {
if ( $contactgroup_name{$grp} ) {
unless ( $tcg_exists{$tree_id}{ $escalation_templates{$temp}{'id'} }{ $contactgroup_name{$grp} } ) {
@vals = ( $tree_id, $escalation_templates{$temp}{'id'}, $contactgroup_name{$grp} );
$result = StorProc->insert_obj( 'tree_template_contactgroup', \@vals );
if ( $result =~ /Error/ ) {
update_status( 'error', $result );
}
$tcg_exists{$tree_id}{ $escalation_templates{$temp}{'id'} }{ $contactgroup_name{$grp} } = 1;
}
}
}
}
}
}
}
update_status( 'info', "Service escalations: $temp_created escalations created, $trees_created trees created." );
return @messages;
}
if ($debug) {
my $connect = StorProc->dbconnect();
StorProc->purge();
stage_load( '', '/usr/local/groundwork/nagios/etc', '1' );
process_commands();
process_timeperiods();
process_contacts();
process_hosts();
process_services();
process_host_escalations();
process_service_escalations();
my $result = StorProc->dbdisconnect();
}
1;