# HG changeset patch # User Heiko Schlittermann # Date 1292943575 -3600 # Node ID 31f29baca131ad0a5f5002d847617d86e91b3cc9 # Parent de6761ce0d5b85c2a4a57b27c74cd6e2c23baca6# Parent 8b487ebf8d994f31e201fe083a22c71ca5352c89 [merged] from hs12 diff -r de6761ce0d5b -r 31f29baca131 zone-ls.pl --- a/zone-ls.pl Tue Dec 21 15:59:05 2010 +0100 +++ b/zone-ls.pl Tue Dec 21 15:59:35 2010 +0100 @@ -1,100 +1,156 @@ #! /usr/bin/perl +use v5.10; use strict; use warnings; +use Pod::Usage; use File::Basename; use FindBin; - -# liest die Konfiguration ein -my @configs = ("$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf"); -my %config; +use Time::Local; +use Getopt::Long; -for (grep { -f } @configs) { - open(CONFIG, $_) or die "Can't open $_: $!\n"; -} +my %config; +my $opt_expiry = undef; -unless (seek(CONFIG, 0, 0)) { - die "Can't open config (searched: @configs)\n"; -} +MAIN: { + my %info; # will hold the information we collected -while () { - chomp; - s/#.*//; - s/\t//g; - s/\s//g; - next unless length; - my ($cname, $ccont) = split(/\s*=\s*/, $_, 2); - $config{$cname} = $ccont; -} -close(CONFIG); - -my $master_dir = $config{master_dir}; -my $zone; -my ($info_zsk, $info_ksk, $info_kc, $info_end, $info_status); + GetOptions( + "e|expiry" => \$opt_expiry, + "h|help" => sub { pod2usage(-exit => 0, -verbose => 1) }, + "m|man" => sub { + pod2usage( + -exit => 0, + -verbose => 2, + -noperldoc => system("perldoc -V &>/dev/null") + ); + }, + ) or pod2usage; -unless (-d $master_dir and -r $master_dir) { - die "$master_dir: $!\n"; -} - -printf "%-35s %-8s %1s/%1s %3s %7s\n", "Domain", "Status", "ZSK", "KSK", - "Used", "Sig-end"; - -for my $dir (glob "$master_dir/*") { + { # find and read/parse the config (could use some common config parser) + my @configs = ("$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf"); + ($_) = grep { -f } @configs; + open(my $config, $_) or die "Can't open $_: $!\n"; - $zone = basename($dir); - - # prueft mit dig nach der zone - $info_status = "OK"; - for (`dig \@localhost $zone`) { - if (/root-servers/) { - $info_status = "FAILED"; - last; + while (<$config>) { + chomp; + s/#.*//; + s/\s//g; + my ($k, $v) = split(/\s*=\s*/, $_, 2) or next; + $config{$k} = $v; } } - if (not -f "$dir/.index.zsk") { - $info_zsk = $info_ksk = $info_kc = 0; - $info_end = "-"; - next; + die "$config{master_dir}: $!\n" if not -d $config{master_dir}; + + foreach my $dir (grep { -d } glob "$config{master_dir}/*") { + + my $zone = basename($dir); + $info{$zone} = { status => "OK" }; + + if (not -f "$dir/.index.zsk") { + $info{$zone}{zsk} = 0; + $info{$zone}{ksk} = 0; + $info{$zone}{kc} = 0; + $info{$zone}{end} = "-"; + $info{$zone}{expiry} = undef; + next; + } + + # prueft wie viele zsks genutzt werden + { + open(my ($fh), $_ = "<$dir/.index.zsk") + or die "Can't open $_: $!\n"; + () = <$fh>; + $info{$zone}{zsk} = $. + } + + # prueft wie viele ksks genutzt werden + { + open(my ($fh), $_ = "<$dir/.index.ksk") + or die "Can't open $_: $!\n"; + () = <$fh>; + $info{$zone}{ksk} = $. + } + + # prueft wie oft die schluessel zum signieren genutzt wurden + { + open(my ($fh), $_ = "<$dir/.keycounter") + or die "Can't open $_: $!\n"; + chomp($info{$zone}{kc} = <$fh>); + } + + # prueft das ablaufdatum + if (!-f "$dir/$zone.signed") { + $info{$zone}{end} = "-"; + next; + } + + open(my ($fh), $_ = "<$dir/$zone.signed") or die "Can't open $_: $!\n"; + while (<$fh>) { + next if not /RSIG.*SOA.*\s + (?\d\d\d\d) + (?\d\d) + (?\d\d) + (?\d\d) + (?\d\d)\d+\s\(/ix; + $info{$zone}{end} = "$+{day}.$+{mon}.$+{year} $+{hour}:$+{min}"; + $info{$zone}{expiry} = + timelocal(0, $+{min}, $+{hour}, $+{day}, $+{mon} - 1, $+{year}); + } } - # prueft wie viele zsks genutzt werden - close(FILE); - open(FILE, $_ = "<$dir/.index.zsk") or die "Can't open $_: $!\n"; - () = ; - $info_zsk = $.; + { # output - # prueft wie viele ksks genutzt werden - close(FILE); - open(FILE, $_ = "<$dir/.index.ksk") or die "Can't open $_: $!\n"; - () = ; - $info_ksk = $.; - - # prueft wie oft die schluessel zum signieren genutzt wurden - open(FILE, $_ = "<$dir/.keycounter") or die "Can't open $_: $!\n"; - chomp($info_kc = ); + my $sort_by = + $opt_expiry + ? sub { ($info{$a}{expiry} // 2**64) <=> ($info{$b}{expiry} // 2**64) } + : sub { $a cmp $b }; - # prueft das ablaufdatum - if (!-f "$dir/$zone.signed") { - $info_end = "-"; - next; - } + my $format_h = "%-35s %-8s %1s/%1s %3s %7s\n"; + my $format_l = "%-35s %-8s %1d/%1d %5d %19s\n"; + + printf $format_h => qw(Domain Status ZSK KSK Used Sig-end); - open(FILE, $_ = "<$dir/$zone.signed") or die "Can't open $_: $!\n"; - while () { - $info_end = "$+{day}.$+{mon}.$+{year} $+{hour}:$+{min}" - if /RSIG.*SOA.*\s - (?\d\d\d\d) - (?\d\d) - (?\d\d) - (?\d\d) - (?\d\d)\d+\s\(/ix; + foreach my $zone (sort $sort_by keys %info) { + printf $format_l => $zone, + @{ $info{$zone} }{qw(status zsk ksk kc end)}; + } } - -} -continue { - printf "%-35s %-8s %1d/%1d %5d %19s\n", $zone, $info_status, $info_zsk, - $info_ksk, $info_kc, - $info_end; } +__END__ + +=head1 NAME + + zone-ls -- lists all zones + +=head1 SYNOPSIS + + zone-ls [-e|--expiry] + +=head1 DESCRIPTION + +This B lists all zones under control of our dnstools suite. The output is ordered by domain name. + +=head1 OPTIONS + +=over + +=item B<-e>|B<--expiry> + +Order the output by expiry date. The sooner the key expires, the more top the +domain is listed. + +=back + +Additionally the common B<-h>|B<--help>|B<-m>|B<--man> options, which should be +self explanatory. + +=head1 AUTHORS + +L + +=cut + +# vim:ts=4 sw=4 ai si aw: