lib/DNS/Vi.pm
changeset 15 aa1598910bb0
parent 10 efba68ef7f89
child 16 1cbe9dc60243
--- 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;