--- a/lib/DNS/Vi.pm Fri May 23 16:15:41 2014 +0200
+++ b/lib/DNS/Vi.pm Sat May 24 23:01:17 2014 +0200
@@ -4,14 +4,16 @@
use warnings;
use if $ENV{DEBUG}//'' eq 'dnsvi' => 'Smart::Comments';
use Digest::SHA qw(sha512_hex);
+use File::Temp;
use base 'Exporter';
-our @EXPORT = qw(ttl2h h2ttl parse delta nice);
+our @EXPORT = qw(ttl2h h2ttl parse delta nice edit update show save);
our @EXPORT_OK = ();
sub parse {
- my $data = join '', @_;
+ my %arg = %{pop @_} if ref $_[-1] eq 'HASH';
+ my $data = shift;
my @lines = split /\n/, $data;
my @zone;
@@ -42,6 +44,7 @@
rrtype => uc $+{rrtype},
data => $+{data},
);
+ next if $rrset{rrtype} ~~ $arg{-skip};
if ($rrset{rrtype} eq 'SOA') {
next if $soa_seen;
@@ -117,8 +120,9 @@
return $out // $ttl;
}
+{
+ my %order = map { state $n = 0; $_ => ++$n } qw(SOA NS TXT MX A AAAA);
sub nice {
- my %order = map { state $n = 0; $_ => ++$n } qw(SOA NS TXT MX A AAAA);
# get a list of { id => $id, rrset => \%rrset }
my @zone =
@@ -155,9 +159,9 @@
$r{data};
};
push @out, $print->($_) foreach @zone;
- return join "\n", @out;
+ return join "\n", @out, '';
}
-
+}
sub delta {
my ($zone1, $zone2) = @_;
my %zone1 = map { $_->{id}, $_->{rrset} } @$zone1;
@@ -174,4 +178,66 @@
return (\@add, \@del);
}
+sub edit {
+ my %arg = %{pop @_} if ref $_[-1] eq 'HASH';
+ my @zone = @_;
+
+ my $tmp = File::Temp->new();
+ $tmp->print(nice @zone);
+ $tmp->flush();
+ system $arg{-editor} => $tmp->filename;
+ $tmp->seek(0, 0);
+ return parse(do { local $/ = undef; <$tmp>}, {-skip => $arg{-skip}});
+}
+
+sub show {
+ my ($add, $del) = @_;
+ my @out = (
+ (map { " - $_ " } @$del),
+ (map { " + $_ " } @$add),
+ );
+ return @out;
+}
+
+sub update {
+ my %arg = %{pop @_} if ref $_[-1] eq 'HASH';
+ my ($zone1, $add, $del) = @_;
+
+ my $orig_soa =
+ (grep { $_->{rrtype} eq 'SOA' } map { $_->{rrset} } @$zone1)[0];
+
+ my @cmds = (
+ $arg{-local} ? () : "server $arg{-server}",
+ "prereq yxrrset @{$orig_soa}{qw{label rrtype data}}",
+ (map { "update delete $_" } @$del),
+ (map { "update add $_" } @$add),
+ 'show',
+ 'send',
+ 'answer',
+ );
+ my @nsupdate = (
+ 'nsupdate',
+ defined $arg{-debug} ? ('-d') : (),
+ defined $arg{-key} ? (-k => $arg{-key}) : (),
+ defined $arg{-local} ? ('-l') : (),
+ );
+
+ open(my $nsupdate, '|-') or do {
+ exec @nsupdate;
+ die "Can't exec @nsupdate: $!\n";
+ };
+ say $nsupdate join "\n", @cmds;
+ close($nsupdate);
+ say "nsupdate returned $?";
+ return $? ? undef : 1;
+}
+
+sub save {
+ my ($zone, $file) = @_;
+ open(my $fh, '>', $file) or die "Can't open >$file: $!\n";
+ print $fh nice @$zone;
+ close($fh);
+
+}
+
1;