<!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>