added validation and runtime detection of addition to a second group

This commit is contained in:
2016-03-05 09:39:33 -05:00
parent c72968f277
commit a52124e582
3 changed files with 88 additions and 1 deletions

28
DDNS.pm
View File

@ -4,6 +4,9 @@ use strict;
use warnings;
use Net::DNS;
use File::Temp qw/tempfile/;
use Memoize;
memoize('_gethosts');
our $VERSION = '0.2';
@ -21,7 +24,7 @@ sub _validateTypeOrDie {
my ($t) = @_;
die "Invalid type"
unless ($t =~ /^_(vhosts|hostedservers|pureslave|custom)$/);
unless ($t =~ /^_(vhosts|pureslave|custom)$/);
}
sub _fqdn {
@ -121,11 +124,34 @@ sub _gethosts {
return @vh;
}
# Find the type of domin that $dom is. If we don't find it, return
# undef. (The domain $dom ends in a dot; the DNS info we find won't;
# hence the concat of the extra "." after the lc.)
sub type {
my ($this, $dom) = @_;
_validateOrDie($dom);
my @vh = $this->get();
foreach my $i (@vh) {
if (lc($i->{zone})."." eq lc($dom)) {
return $i->{type};
}
}
# Didn't find it.
return undef;
}
sub add {
my ($this, $dom, $master, $type) = @_;
_validateOrDie($dom);
my $fqdn = _fqdn($dom, $type);
if (my $type = $this->type($dom)) {
die "Domain $dom already exists [of type $type]";
}
$this->__docmd("update add $fqdn 60 TXT $master");
$this->cleanup();
}

View File

@ -20,6 +20,7 @@ WriteMakefile(
'bin/sync-slave',
'bin/list-all',
'bin/is-managed',
'bin/validate-master',
],
'AUTHOR' => 'Jorj Bauer <jorj@jorj.org>',
);

60
bin/validate-master Executable file
View File

@ -0,0 +1,60 @@
#!/usr/bin/perl
use strict;
use warnings;
use Martnet::DDNS;
my $ddns = Martnet::DDNS->new();
my $path = '/etc/bind';
my %files = ( 'custom.zones.9' => '_custom',
'martnet.zones.9' => '_custom',
'hostedservers.zones.9' => '_custom',
'vhost.zones.9' => '_vhosts',
'martnet.slave.zones.9' => '*' );
our %fixes = ( '_custom' => 'add-custom',
'_vhosts' => 'add-vhost',
'_pureslave' => 'add-slave',
'*' => 'one of the add-* scripts',
);
foreach my $i (keys %files) {
validate_file($path . '/' . $i, $files{$i});
}
exit 0;
sub validate_file {
my ($path, $expected_type) = @_;
open(my $fh, $path) || die "Can't open $path: $!";
while (<$fh>) {
my ($zonename) = ($_ =~ /zone \"([^\"]+)\"/i);
next unless ($zonename);
$zonename = lc($zonename);
unless ($zonename =~ /\.$/) {
$zonename .= '.'; # must end with a dot
}
findOrDie($path, $zonename, $expected_type);
}
close $fh;
}
sub findOrDie {
my ($path, $zonename, $expected_type) = @_;
my $type = $ddns->type($zonename);
unless ($type) {
my $fix = $fixes{$expected_type};
die "domain $zonename is not managed, but is in $path [expected $expected_type]; to fix, either remove the domain from the file, or use $fix to fix it";
}
if ($expected_type ne '*') {
unless ($type eq $expected_type) {
die "domain $zonename is managed in $path of type [$type] but should be [$expected_type] if it's in that file";
}
}
}