-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfollowdns
executable file
·81 lines (72 loc) · 2.65 KB
/
followdns
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/perl
use strict;
use File::Tail;
use Net::Domain qw(hostfqdn);
my $ns="localhost";
my $dig="/usr/bin/dig";
my $git="git";
my $repo="/var/lib/followdns/dyn";
my $logd="/var/log/followdns";
my $log=File::Tail->new(
name=>"/var/log/daemon.log",
maxinterval=>10
);
my $commiter = (getpwuid($>))[0] . '@' . hostfqdn();
unless ( -d "$repo" ) { die "No such directory $repo, $!"; }
while (defined(my $line = $log->read)) {
my ($client, $key, $zone, $change);
if ( $line =~ m{named\[\d+\]: client (?:\@0x\S+ )?(\S+?)/key ([^:]+): updating zone '(.+?)/IN': (.+)} ) {
$client="$1";
$key="$2";
$zone="$3";
$change="$4";
} elsif ( $line =~ m{named\[\d+\]: thawing zone '(.+?)/IN': success} ) {
$client='localhost';
$key='thaw';
$zone="$1";
$change='manual edit';
} else {
next;
}
#print "DEBUG: client: $client, key: $key, zone: $zone, change: $change\n";
# Get the updated zone file
open(my $axfr, "$dig axfr $zone \@$ns |") or die "Unable to run $dig axfr $zone \@$ns, $!";
open(my $zonefile,'>', "$repo/$zone") or die "Unable to open $repo/$zone for writing, $!";
my $serial = 0;
while (<$axfr>) {
# Extract serial and replace it with magic string to reduce noise in diff
if (s{^($zone\. \s+
\d+ # TTL
\s+ IN \s+ SOA \s+
\S+ # master
\s+
\S+ # tech-c
\s+)(\d+) # serial
} {$1(serial)}x)
{
next if $serial; # no reason to include SOA twice
$serial = $2;
}
print $zonefile $_ unless /^;;/ ;
}
close $axfr;
close $zonefile;
# Add the changes to a log file
open (my $logfile,'>>',"$logd/changes.log") or die "Unable to open $logd/changes.log for appending, $!";
print $logfile localtime . " key: $key, zone: $zone, client: $client, serial: $serial, change: $change\n";
close $logfile;
# Let's hope the sorting is the same every time
# Check in changes. Upgrade to Git::Repository some other time
chdir "$repo" or die "$repo: chdir failed: $!";
die "$repo is not a git repo" unless ( -d ".git" );
my @sysargs;
#@sysargs=("$git", 'add', "$zone", "changes.log");
@sysargs = ($git, 'add', $zone);
system (@sysargs) == 0 or die "Unable to run @sysargs, $! ";
@sysargs = ($git, 'commit',
'--author', "\"key $key\" <$commiter>",
"-m", "serial $serial: $change (client $client)");
system (@sysargs) == 0 or print "Unable to run @sysargs, change might be within one single zone file. $! ";
@sysargs = ($git, 'push');
system (@sysargs) == 0 or print "Unable to run @sysargs, $! ";
}