Order of output is configurable (command line switch) hs12
authorHeiko Schlittermann <hs@schlittermann.de>
Tue, 21 Dec 2010 15:39:50 +0100
branchhs12
changeset 44 8b487ebf8d99
parent 42 2baba9f77020
child 47 31f29baca131
child 48 04cefcf6f4ac
Order of output is configurable (command line switch)
zone-ls.pl
--- a/zone-ls.pl	Tue Dec 21 14:02:22 2010 +0100
+++ b/zone-ls.pl	Tue Dec 21 15:39:50 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 (<CONFIG>) {
-    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
+				(?<year>\d\d\d\d)
+				(?<mon>\d\d)
+				(?<day>\d\d)
+				(?<hour>\d\d)
+				(?<min>\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";
-    () = <FILE>;
-    $info_zsk = $.;
+    {    # output
 
-    # prueft wie viele ksks genutzt werden
-    close(FILE);
-    open(FILE, $_ = "<$dir/.index.ksk") or die "Can't open $_: $!\n";
-    () = <FILE>;
-    $info_ksk = $.;
-
-    # prueft wie oft die schluessel zum signieren genutzt wurden
-    open(FILE, $_ = "<$dir/.keycounter") or die "Can't open $_: $!\n";
-    chomp($info_kc = <FILE>);
+        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 (<FILE>) {
-        $info_end = "$+{day}.$+{mon}.$+{year} $+{hour}:$+{min}"
-          if /RSIG.*SOA.*\s
-			(?<year>\d\d\d\d)
-			(?<mon>\d\d)
-			(?<day>\d\d)
-			(?<hour>\d\d)
-			(?<min>\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<zone-ls> 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<andre.suess@pipkin.cc>
+
+=cut
+
+# vim:ts=4 sw=4 ai si aw: