From ecf4d0c7da167251d80553b9f77bb25b0e9cba5b Mon Sep 17 00:00:00 2001 From: Jorj Bauer Date: Mon, 22 Feb 2016 12:42:57 -0500 Subject: [PATCH] added slave sync; bugfix for deletion; added a list-all --- DDNS.pm | 26 +++++++++++++++------ Makefile.PL | 1 + bin/add-custom | 3 ++- bin/list-all | 12 ++++++++++ bin/sync-slave | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 8 deletions(-) create mode 100755 bin/list-all create mode 100755 bin/sync-slave diff --git a/DDNS.pm b/DDNS.pm index b3264fb..d4154e8 100644 --- a/DDNS.pm +++ b/DDNS.pm @@ -43,10 +43,10 @@ sub _validateOrDie { } sub _lookupOrDie { - my ($dom) = @_; + my ($dom, $type) = @_; _validateOrDie($dom); - my $fqdn = _fqdn($dom, '_vhosts'); + my $fqdn = _fqdn($dom, $type); my $res = Net::DNS::Resolver->new; my $query = $res->query($fqdn, "TXT"); @@ -91,7 +91,9 @@ sub __docmd { sub _gethosts { my ($this, $type) = @_; - _validateTypeOrDie($type); + unless (!defined($type)) { + _validateTypeOrDie($type); + } my $fh; open($fh, "dig -t AXFR \@127.0.0.1 private.invalid. |") @@ -100,9 +102,19 @@ sub _gethosts { my @vh; while (<$fh>) { - if (/^(\S+).$type.private.invalid.\s+\d+\s+IN\s+TXT\s+\"(.+)\"$/) { - push (@vh, { zone => $1, - master => $2 }); + if ($type) { + if (/^(\S+)\.$type\.private\.invalid\.\s+\d+\s+IN\s+TXT\s+\"(.+)\"$/) { + push (@vh, { zone => $1, + type => $type, + master => $2 }); + } + } else { + # Querying everything + if (/^(\S+)\.(\S+)\.private\.invalid\.\s+\d+\s+IN\s+TXT\s+\"(.+)\"$/) { + push (@vh, { zone => $1, + type => $2, + master => $3 }); + } } } @@ -121,7 +133,7 @@ sub add { sub del { my ($this, $dom, $type) = @_; - _lookupOrDie($dom); + _lookupOrDie($dom, $type); my $fqdn = _fqdn($dom, $type); $this->__docmd("update delete $fqdn TXT"); diff --git a/Makefile.PL b/Makefile.PL index fd44aaf..41af2b4 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -17,6 +17,7 @@ WriteMakefile( 'bin/add-custom', 'bin/del-custom', 'bin/list-custom', + 'bin/sync-slave', ], 'AUTHOR' => 'Jorj Bauer ', ); diff --git a/bin/add-custom b/bin/add-custom index 68eaa50..6b9a13a 100755 --- a/bin/add-custom +++ b/bin/add-custom @@ -6,7 +6,8 @@ use Martnet::DDNS; use Regexp::Common qw/net/; my $host = shift || die "No zonename provided"; -my $master = shift || die "No master DNS IP provided"; +my $master = shift; +$master ||= '74.109.12.14'; die "Zonename must end in a dot" unless ($host =~ /^[a-zA-Z0-9\.\-\_]+\.$/); diff --git a/bin/list-all b/bin/list-all new file mode 100755 index 0000000..353b93a --- /dev/null +++ b/bin/list-all @@ -0,0 +1,12 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use Martnet::DDNS; + +my $ddns = Martnet::DDNS->new(); + +my @vh = $ddns->get(); +foreach my $i (sort {$a->{zone} cmp $b->{zone}} @vh) { + print $i->{zone}, ". $i->{type} master: ", $i->{master},"\n"; +} diff --git a/bin/sync-slave b/bin/sync-slave new file mode 100755 index 0000000..89dcff2 --- /dev/null +++ b/bin/sync-slave @@ -0,0 +1,61 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use Martnet::DDNS; +use File::Temp qw/tempfile/; + +my $ddns = Martnet::DDNS->new(); + +my @vh = $ddns->get(); + +my @all = parse_slavefile("/etc/bind/martnet.slave.zones.9"); + +# For each virtual host, see if we've got it already +my $changecount = 0; +foreach my $i (@vh) { + unless (contains_zone($i, @all)) { + # If we find any differences, we rewrite the file + do_rewrite(@vh); + last; + } +} + +exit 0; + +sub parse_slavefile { + my ($f) = @_; + + my @ret; + + open(my $fh, $f) || die "Can't open $f: $!"; + while (<$fh>) { + if (/^zone\s+\"([^\"]+)\"\s+\{/) { + push ( @ret, { zone => $1 } ); + } + } + return @ret; +} + +sub do_rewrite { + my (@vh) = @_; + my ($fh, $path) = tempfile(); + foreach my $i (sort {$a->{zone} cmp $b->{zone}} @vh) { + print $fh "zone \"$i->{zone}\" { type slave; file \"/var/cache/bind/db.$i->{zone}\"; masters { $i->{master}; } };\n"; + } + close $fh; + print "Installing new slave host list\n"; + system("install -o bind -g bind $path /etc/bind/martnet.slave.zones.9"); + print "Reloading DNS files\n"; + system("rndc reload"); +} + +sub contains_zone { + my ($zone, @zl) = @_; + + foreach my $i (@zl) { + return 1 + if ($i->{zone} eq $zone); + } + return 0; +}