<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2800.1264" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>Dear All,</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>I wrote this hack to run nsupdate when my primary 
server is not available to redirect traffic to my backup server.  this perl 
script uses two config files to give nsupdate all the stuff it needs to do the 
dynamic update.  One config is for the general configuration and one for 
each server.  I am finding this script useful and a) want to share with 
other people and b) hopefully improve it as I am FAR from being a 
programmer.  Nagios configuration is described in event handler 
doc.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>failover.conf</FONT></DIV>
<DIV><FONT face=Arial size=2># DNS server IP<BR>server=192.168.1.1</FONT></DIV>
<DIV><FONT face=Arial size=2># requesting server<BR>tsigname=msoeq</FONT></DIV>
<DIV><FONT face=Arial size=2># requesting server 
key<BR>tsigkey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><A 
href="http://www.server.com.conf">www.server.com.conf</A></FONT></DIV>
<DIV><FONT face=Arial size=2># DNS records (hostnames) that will be effected 
when failover occures<BR># hostnames must be separated by a 
(,)<BR>records=www.server.com,www1.server.com,www2.server.com,server.com</FONT></DIV>
<DIV><FONT face=Arial size=2># TTL to set for each 
record<BR>ttl=300</FONT></DIV>
<DIV><FONT face=Arial size=2># IP of the primary 
server<BR>primary=x.x.x.x</FONT></DIV>
<DIV><FONT face=Arial size=2># IP of the backup 
server<BR>backup=y.y.y.y</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>The actual script:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>failover</FONT></DIV>
<DIV><FONT face=Arial size=2>#!/usr/bin/perl</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>use IO::File;<BR>use POSIX qw(tmpnam);</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>$conf_path="/usr/local/failover";</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>$DOMAIN = "$ARGV[ 0 ]\.conf";<BR>$SERVICESTATE = 
$ARGV[ 1 ];<BR>$STATETYPE = $ARGV[ 2 ];<BR>$SERVICEATTEMPT = $ARGV[ 3 
];</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>open(GEN_CONFIG, "< 
$conf_path/failover.conf")<BR>        or die 
"Can't open $conf_path/failover.conf: $!\n";<BR>while (<GEN_CONFIG>) 
{<BR>    chomp;<BR>    
s/#.*//;<BR>    s/^\s+//;<BR>    
s/\s+$//;<BR>    next unless length;<BR>    my 
($var, $value) = split(/\s*=\s*/, $_, 2);<BR>    
$failover_params{$var} = $value;<BR>}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>open(SERVER_CONFIG, "< 
$conf_path/$DOMAIN")<BR>    or die "Couldn't open $DOMAIN for 
reading: $!\n";</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>while (<SERVER_CONFIG>) 
{<BR>    chomp;<BR>    
s/#.*//;<BR>    s/^\s+//;<BR>    
s/\s+$//;<BR>    next unless length;<BR>    my 
($var, $value) = split(/\s*=\s*/, $_, 2);<BR>    
$server_params{$var} = $value;<BR>} </FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2># Build temp files based on how many hostnames will 
be effected.<BR>        @array = 
split(/\s*,\s*/, 
$server_params{records});<BR>        foreach 
$url (@array) {</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial 
size=2>                
# Create a temp 
file<BR>                
$tmp_file = 
tmpnam();<BR>                
$fh = IO::File->new($tmp_file, 
O_RDWR|O_CREAT|O_EXCL);<BR>                
open(OUTFILE, ">>$tmp_file") or die "Can't write to $tmp_file: 
$!\n";</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial 
size=2>                
if ($SERVICESTATE eq 'CRITICAL' && $STATETYPE eq 'HARD') 
{<BR>                        
print OUTFILE "server 
$failover_params{server}\nsend\n";<BR>                        
print OUTFILE "key $failover_params{tsigname} 
$failover_params{tsigkey}\nsend\n";<BR>                        
print OUTFILE "update delete $url 
A\nsend\n";<BR>                        
print OUTFILE "update add $url $server_params{ttl} A 
$server_params{backup}\nsend\n";</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial 
size=2>                        
# perform actual 
update<BR>                        
system("/usr/bin/nsupdate -d $tmp_file");</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial 
size=2>                        
}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial 
size=2>                
elsif ($SERVICESTATE eq 'CRITICAL' && $STATETYPE eq 'SOFT') 
{<BR>                        
print "Soft Critical State... Please wait... 
\n";<BR>                        
}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial 
size=2>                
elsif ($SERVICESTATE eq 'OK' && $STATETYPE eq 'HARD') 
{<BR>                        
print OUTFILE "server 
$failover_params{server}\nsend\n";<BR>                        
print OUTFILE "key $failover_params{tsigname} 
$failover_params{tsigkey}\nsend\n";<BR>                        
print OUTFILE "update delete $url 
A\nsend\n";<BR>                        
print OUTFILE "update add $url $server_params{ttl} A 
$server_params{primary}\nsend\n";</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial 
size=2>                        
# perform actual 
update<BR>                        
system("/usr/bin/nsupdate -d $tmp_file");</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial 
size=2>                        
}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial 
size=2>                
else 
{<BR>                        
}<BR>                        
# Delete temp 
file<BR>                        
unlink($tmp_file) or die "Can't delete $tmp_file: 
$!\n";<BR>        
}</DIV></FONT></BODY></HTML>