Script for adding or removing hosts in a hostgroup
Re: Script for adding or removing hosts in a hostgroup
It seems like we're all trying to solve this. I too have written (or am writing) a utility to allow you to programmatically execute almost everything you can do in the GUI.
The thing we need to watch out for is "collisions" between a user in the GUI making changes which are not yet applied, while the external utility is making its changes. In other words, if I make an external change and reconfigure, then the user in the GUI will be working in an "unsynchronized" environment.
I'm going to ask this question in separate thread.
The thing we need to watch out for is "collisions" between a user in the GUI making changes which are not yet applied, while the external utility is making its changes. In other words, if I make an external change and reconfigure, then the user in the GUI will be working in an "unsynchronized" environment.
I'm going to ask this question in separate thread.
Re: Script for adding or removing hosts in a hostgroup
Going to post a link to your new thread: Nagios XI Reconfiguration Collisions and Conflicts
http://support.nagios.com/forum/viewtop ... 40#p126992
http://support.nagios.com/forum/viewtop ... 40#p126992
Re: Script for adding or removing hosts in a hostgroup
Modification of a single attribute is really just a matter of determining the characteristics and dependencies of that attribute. For example, if I modify the service_description of a service check (perhaps it was misspelled), Nagios would assume it to be a new service upon import. But if I wanted that service check and its associated history and performance data to stay together, how would I achieve that?
The utility I'm working on is going to do this. I already have host cloning working consistently. Modifying all hosts within a host group should just be a matter of identifying the hosts and iteratively performing modifications on the appropriate configuration file(s).
You would need to understand the relationship between that service description and all objects associated with it. These relationships are not well-defined in the documentation. So, in this specific example, to modify all members of a hostgroup, assuming you are not changing the service_description directive value, you should consider doing the following:
1) Identify the object (dependency, host, service, etc.) you want to modify or add
2) Identify the directive(s) you are modifying
3) Trace any dependencies that directive may have through the configuration files (reference: http://nagios.sourceforge.net/docs/nagi ... tions.html)
4) Determine a method for modifying the directive's value
5) Iteratively parse and modify copies of the configuration files
6) Place these modified copies into the /usr/local/nagios/etc/import directive
7) Execute the /usr/local/nagios/nagiosxi/scripts/reconfigure_nagios.sh script
8) Verify that the changes were made
The preceding is probably obvious to many in this forum, but as I've progressed through my own development, there are aspects of how Nagios works that may not be immediately apparent.
A more deterministic, although dangerous, method of making these changes would be to perform direct updates on the MySQL and PostgreSQL databases and then flush the changes to the configuration files. This would be a non-trivial effort and is not something I'm going to try at this point.
The utility I'm working on is going to do this. I already have host cloning working consistently. Modifying all hosts within a host group should just be a matter of identifying the hosts and iteratively performing modifications on the appropriate configuration file(s).
You would need to understand the relationship between that service description and all objects associated with it. These relationships are not well-defined in the documentation. So, in this specific example, to modify all members of a hostgroup, assuming you are not changing the service_description directive value, you should consider doing the following:
1) Identify the object (dependency, host, service, etc.) you want to modify or add
2) Identify the directive(s) you are modifying
3) Trace any dependencies that directive may have through the configuration files (reference: http://nagios.sourceforge.net/docs/nagi ... tions.html)
4) Determine a method for modifying the directive's value
5) Iteratively parse and modify copies of the configuration files
6) Place these modified copies into the /usr/local/nagios/etc/import directive
7) Execute the /usr/local/nagios/nagiosxi/scripts/reconfigure_nagios.sh script
8) Verify that the changes were made
The preceding is probably obvious to many in this forum, but as I've progressed through my own development, there are aspects of how Nagios works that may not be immediately apparent.
A more deterministic, although dangerous, method of making these changes would be to perform direct updates on the MySQL and PostgreSQL databases and then flush the changes to the configuration files. This would be a non-trivial effort and is not something I'm going to try at this point.
Re: Script for adding or removing hosts in a hostgroup
There exists already that function in Nagios XI Enterprise the Bulk Renaming Tool that:
Bulk Renaming Tool
The Renaming Tool allows for host and service names to be updated in bulk, while retaining all historical status information and performance data. The renaming tool updates configurations based on what is defined in the Core Config Manager.
Re: Script for adding or removing hosts in a hostgroup
I'm not sure how that would be applicable here.
Re: Script for adding or removing hosts in a hostgroup
@mp4783
I would be very interested in testing this in house. It could benefit many XI users with large environments, who want to manage hosts/services from the CLI.I too have written (or am writing) a utility to allow you to programmatically execute almost everything you can do in the GUI.
Be sure to check out our Knowledgebase for helpful articles and solutions!
Re: Script for adding or removing hosts in a hostgroup
I'll +1 this. It it has been done well and is reliable, this would indeed be very beneficial. C'mon mp, convince your boss. Explain him Nagios is build on the work of many.I would be very interested in testing this in house. It could benefit many XI users with large environments, who want to manage hosts/services from the CLI.
It could also help you to discover issues faster if more people use it..
Grtz
Willem
Nagios XI 5.8.1
https://outsideit.net
https://outsideit.net
Re: Script for adding or removing hosts in a hostgroup
Sorry for the delay...I ended up almost completely re-writing my perl script. Now it runs every hour via cron as the nagios user and only does a nagios restart if the new hostgroups.cfg is different from the existing hostgroups.cfg (*not* using direct file comparison since timestamps, sort order, etc make comparing the files problematic). Following are code snippets from the actual script so may be missing libraries, subs, variable declarations, etc...
Notes: I only use/modify hostgroups.cfg. You can still make hostgroup assignments in the individual host config files and they will not be affected
by this script. My script does read the host configs and check a few things like notification periods which are compared to an external database, but
I just add those to the info array so I get email and manually make those changes. I might automate those changes later but so far it hasn't been
necessary.
First I import the existing hostgroups.cfg into a hash:
Then clone the hash
and build a new hash ($hg_external) based on the external data (source specific so not shown here)
Then merge the two into a third hash for export.
If changes made, then create the new hostgroups.cfg file in the import directory
Write new hosttroups.cfg and restart nagios (if necessary)
This is the subroutine that imports the hostgroups.cfg file into a hash.
Notes: I only use/modify hostgroups.cfg. You can still make hostgroup assignments in the individual host config files and they will not be affected
by this script. My script does read the host configs and check a few things like notification periods which are compared to an external database, but
I just add those to the info array so I get email and manually make those changes. I might automate those changes later but so far it hasn't been
necessary.
First I import the existing hostgroups.cfg into a hash:
Code: Select all
#!/usr/bin/perl
#####################################################
# nagios-import
#####################################################
use Data::Dumper;
use Clone qw(clone);
use Array::Utils qw(:all);
use strict;
my $hg_current;
my $hg_external;
my $hg_import;
my @info; #array to store info msgs for email notification
my @error; #array to store error msgs for email notification
my $restart_required=0;
get_hostgroups_hash(\$hg_current,"$WorkFile");
#iterate through hash example
#foreach my $key (sort keys %{$hg_current}) {
# print "check key $key\n";
# foreach my $subkey (sort keys %{$hg_current->{$key}}) {
# print "check subkey $subkey\n";
# my $type=ref($hg_current->{$key}{$subkey});
# if ($type eq '') {
# print "VALUE: ".$hg_current->{$key}{$subkey}."\n";
# } elsif ($type eq 'HASH') {
# foreach my $subsubkey (sort keys %{$hg_current->{$key}{$subkey}}) {
# print "subsubkey: $subsubkey\n";
# print "value: ".$hg_current->{$key}{$subkey}{$subsubkey}."\n";
# }
# } else {
# print "REF: $type\n";
# }
# }
#}
Code: Select all
$hg_import = clone($hg_current);Then merge the two into a third hash for export.
Code: Select all
#check for changes and if found, merge hg_external hosts into hg_import;
foreach my $hostgroup (sort keys %{$hg_external->{'hostgroup'}}) {
my $hosts_import = $hg_import->{'hostgroup'}{$hostgroup}{'hosts'};
my $hosts_external = $hg_external->{'hostgroup'}{$hostgroup}{'hosts'};
my $mask = $hosts_import ^ $hosts_external;
my @s1=split(",",$hosts_import);
my @s2=split(",",$hosts_external);
my $diff=array_diff(@s1,@s2);
#print "$hostgroup: diff=$diff\n";
if ("$diff" == 0) {
#print "$hostgroup : match\n";
} else {
my @removed=array_minus(@s1,@s2);
my @added=array_minus(@s2,@s1);
$restart_required=1; #trigger import file write and nagios restart
if ($diff > 1) {
push(@info,"HOSTGROUP: *$hostgroup* : $diff changes");
} else {
push(@info,"HOSTGROUP: *$hostgroup* : $diff change");
}
my $removed_detail;
foreach my $host (@removed) {
if ($removed_detail eq '') {
$removed_detail.="$host";
} else {
$removed_detail.=",$host";
}
}
my $added_detail;
foreach my $host (@added) {
if ($added_detail eq '') {
$added_detail.="$host";
} else {
$added_detail.=",$host";
}
}
push(@info,"Removed: $removed_detail") if ($removed_detail);
#print "Removed: $removed_detail\n" if ($removed_detail);
push(@info,"Added : $removed_detail") if ($added_detail);
#print "Added : $removed_detail\n" if ($added_detail);
push(@info,"---") if ($diff);
}
#print "merge $hostgroup\n";
#print " using: *".$hg_external->{'hostgroup'}{$hostgroup}{'hosts'}."*\n";
$hg_import->{'hostgroup'}{$hostgroup}{'hosts'} = $hg_external->{'hostgroup'}{$hostgroup}{'hosts'};
$restart_required=1;
}Code: Select all
#now create data array for import file hostgroups.cfg.
push (@data,"###############################################################################");
push (@data,"#");
push (@data,"# Hostgroup configuration file");
push (@data,"#");
push (@data,"# Created by: $0");
push (@data,"# Date: $timestamp");
push (@data,"# Nagios 4.x config file");
push (@data,"#");
push (@data,"###############################################################################");
foreach my $hostgroup (sort keys %{$hg_import->{'hostgroup'}}) {
#print "create data for $hostgroup\n";
my $alias=$hg_import->{'hostgroup'}{$hostgroup}{'alias'};
my $members=$hg_import->{'hostgroup'}{$hostgroup}{'hosts'};
my $hostgroup_members=$hg_import->{'hostgroup'}{$hostgroup}{'hostgroup_members'};
#print "alias = $alias\n";
#print "members = $members\n";
#print "hostgroup_members = $hostgroup_members\n";
push (@data,"");
push (@data,"define hostgroup {");
push (@data," hostgroup_name $hostgroup");
push (@data," alias $alias");
push (@data," members $members") if ($members ne '');
push (@data," hostgroup_members $hostgroup_members") if ($hostgroup_members ne '');
push (@data," }");
}
push (@data,"###############################################################################");
push (@data,"#");
push (@data,"# Hostgroups configuration file");
push (@data,"#");
push (@data,"# END OF FILE");
push (@data,"#");
push (@data,"###############################################################################");Code: Select all
my $errors=@error;
my $infos = @info;
if (("$errors" == 0) && ($restart_required)) {
#create and write import file
open(IMPORTFILE,">$ImportFile");
foreach my $line (@data) {
print IMPORTFILE "$line\n";
}
close(IMPORTFILE);
#restart nagios
print "restart nagios\n";
my $reconfig=`cd /usr/local/nagiosxi/scripts/;/usr/local/nagiosxi/scripts/reconfigure_nagios.sh`;
push(@info," ");
if ($reconfig=~/Starting nagios\: done\./) {
push(@info,"Nagios restarted with new hostgroups.cfg");
}
} else {
#don't import or restart due to info or err msgs
push(@info,"Import deferred due to error messages");
print "Import deferred due to error messages";
}
print "errors = $errors\n";
if ($errors) {
print "sending errors email\n";
send_error_email();
}
my $infos = @info;
if ($infos) {
print "sending infos email\n";
send_info_email();
}
exit 0;Code: Select all
sub get_hostgroups_hash($$) {
my $file = $_[1];
my $hostgroup;
my $hostgroup_members;
my $alias;
my $hosts;
open(FILE,"<$file");
while (my $line = <FILE>) {
#print "line: $line\n";
if ($line=~/^define hostgroup/) {
if ($hostgroup ne '') {
#print "storing hostgroup $hostgroup\n";
${($_[0])}->{'hostgroup'}{$hostgroup}{'alias'}=$alias;
${($_[0])}->{'hostgroup'}{$hostgroup}{'hosts'}=$hosts;
${($_[0])}->{'hostgroup'}{$hostgroup}{'hostgroup_members'}=$hostgroup_members if ($hostgroup_members ne '') ;
${($_[0])}->{'alias'}{$alias}=$hostgroup;
}
$hostgroup='';
$hostgroup_members='';
$alias='';
$hosts='';
#print "hostgroup=*$hostgroup* alias=*$alias* hosts=*$hosts*\n";
} elsif ($line=~/hostgroup_name\s+(\S+)/) {
$hostgroup=$1;
#print "Starting hostgroup $hostgroup\n";
} elsif ($line=~/^\s+alias\s+(\S+.*)$/) {
$alias=$1;
#print "alias for hostgroup $hostgroup is $alias\n";
} elsif ($line=~/^\s+members\s+(\S+)/) {
$hosts=$1;
#print "hosts for hostgroup $hostgroup is $hosts\n";
my @members=split(",",$hosts);
$hosts='';
foreach my $host (sort @members) {
#print "Inserting $host into $hostgroup\n";
if ($hosts eq '') {
$hosts=$host;
} else {
$hosts.=",$host";
}
}
} elsif ($line=~/^\s+hostgroup_members\s+(\S+)/) {
$hostgroup_members=$1;
}
}
}Re: Script for adding or removing hosts in a hostgroup
Thanks for sharing your code Jwelch.
I'll have a look at it asap.
Willem
I'll have a look at it asap.
Willem
Nagios XI 5.8.1
https://outsideit.net
https://outsideit.net
Re: Script for adding or removing hosts in a hostgroup
Thanks from me too, jwelch! I will set a reminder for testing this later. It's not going to be today for sure
Monday is not a good day.
Be sure to check out our Knowledgebase for helpful articles and solutions!