| 
     1 #!/usr/bin/perl   | 
         | 
     2   | 
         | 
     3 use 5.010;  | 
         | 
     4 use warnings;  | 
         | 
     5 use strict;  | 
         | 
     6 use Pod::Usage;  | 
         | 
     7 use if $ENV{DEBUG} => "Smart::Comments"; | 
         | 
     8 use Cwd qw(abs_path);  | 
         | 
     9 use File::Path;  | 
         | 
    10 use File::Basename;  | 
         | 
    11 use Getopt::Long;  | 
         | 
    12 use Net::LibIDN qw(:all);  | 
         | 
    13 use DNStools::Config qw(get_config);  | 
         | 
    14 use Template;  | 
         | 
    15   | 
         | 
    16 my $CHARSET = "UTF-8";  | 
         | 
    17   | 
         | 
    18 my $opt_force = 0;  | 
         | 
    19   | 
         | 
    20 MAIN: { | 
         | 
    21   | 
         | 
    22     my %cf = get_config;  | 
         | 
    23   | 
         | 
    24     GetOptions(  | 
         | 
    25         "f|force" => \$opt_force,  | 
         | 
    26         "h|help"  => sub { pod2usage(-verbose => 1, -exit => 0) }, | 
         | 
    27         "m|man"   => sub { | 
         | 
    28             pod2usage(  | 
         | 
    29                 -verbose   => 2,  | 
         | 
    30                 # "system('perldoc -V &>/dev/null')" appears shorter, but may not | 
         | 
    31                 # do what you expect ( it still returns 0 on debian squeeze with  | 
         | 
    32                 # dash as system shell even if cannot find the command in $PATH)  | 
         | 
    33                 -noperldoc => system('perldoc -V >/dev/null 2>&1'), | 
         | 
    34                 -exit      => 0  | 
         | 
    35             );  | 
         | 
    36         },  | 
         | 
    37       )  | 
         | 
    38       and @ARGV >= 2  | 
         | 
    39       or pod2usage;  | 
         | 
    40   | 
         | 
    41     my $customer = shift;  | 
         | 
    42   | 
         | 
    43     die "$cf{master_dir}: $!"    if not -d -r -x $cf{master_dir}; | 
         | 
    44     die "$cf{zone_conf_dir}: $!" if not -d -r -x $cf{zone_conf_dir}; | 
         | 
    45   | 
         | 
    46     # legt fuer jede Zone in @ARGV ein verzeichnis in $master_dir an.  | 
         | 
    47     # schreibt aus den angegebenen templates die dateien $zonefile und $config  | 
         | 
    48     # in die entsprechenden verzeichnisse.  | 
         | 
    49     for my $utf8zone (@ARGV) { | 
         | 
    50   | 
         | 
    51         my $zone     = idn_to_ascii($utf8zone, $CHARSET);  | 
         | 
    52         my $zonefile   = "$cf{master_dir}/$zone/$zone"; | 
         | 
    53         my $configfile = "$cf{zone_conf_dir}/$zone"; | 
         | 
    54         my $now        = time;  | 
         | 
    55   | 
         | 
    56         mkpath dirname $zonefile;  | 
         | 
    57   | 
         | 
    58         if (-f $zonefile and not $opt_force) { | 
         | 
    59             say "skipping $utf8zone: zone file '$zonefile' exists.";  | 
         | 
    60             next;  | 
         | 
    61         }  | 
         | 
    62   | 
         | 
    63         if (-f $configfile and not $opt_force) { | 
         | 
    64             say "skipping $utf8zone: config file '$configfile' exists.";  | 
         | 
    65             next;  | 
         | 
    66         }  | 
         | 
    67   | 
         | 
    68         say "zone $utf8zone ($zone) for $customer.";  | 
         | 
    69   | 
         | 
    70         my %vars = (  | 
         | 
    71             zone     => $zone,  | 
         | 
    72             utf8zone => $utf8zone,  | 
         | 
    73             now        => $now,  | 
         | 
    74             zonefile   => abs_path($zonefile),  | 
         | 
    75             customer   => $customer,  | 
         | 
    76             hostmaster => $cf{hostmaster}, | 
         | 
    77             primary    => $cf{primary}, | 
         | 
    78             secondary  => $cf{secondary}, | 
         | 
    79         );  | 
         | 
    80   | 
         | 
    81         $vars{hostmaster} =~ s/@/./g; | 
         | 
    82   | 
         | 
    83         my $tt = Template->new(INCLUDE_PATH => $cf{template_dir}) | 
         | 
    84           or die "$Template::ERROR\n";  | 
         | 
    85   | 
         | 
    86         $tt->process("named.zone",   \%vars, $zonefile)   || die $tt->error; | 
         | 
    87         $tt->process("named.config", \%vars, $configfile) || die $tt->error; | 
         | 
    88   | 
         | 
    89     }  | 
         | 
    90   | 
         | 
    91 }  | 
         | 
    92   | 
         | 
    93 __END__  | 
         | 
    94   | 
         | 
    95 =head1 NAME  | 
         | 
    96   | 
         | 
    97     zone-mk - create a new zone  | 
         | 
    98   | 
         | 
    99 =head1 SYNOPSIS  | 
         | 
   100   | 
         | 
   101     zone-mk [-f|--force] <customer-id> <zone>...  | 
         | 
   102   | 
         | 
   103 =head1 DESCRIPTION  | 
         | 
   104   | 
         | 
   105 B<zone-mk> creates a new DNS zone file and the config snippet. Nothing  | 
         | 
   106 else (especially no DNSSEC, and no bind integration) is done.  | 
         | 
   107   | 
         | 
   108 =head1 OPTIONS  | 
         | 
   109   | 
         | 
   110 =over  | 
         | 
   111   | 
         | 
   112 =item B<-f>|B<--force>  | 
         | 
   113   | 
         | 
   114 Create zone file and config even if they exist. (default: off)  | 
         | 
   115   | 
         | 
   116 =item B<-h>|B<--help>  | 
         | 
   117   | 
         | 
   118 =item B<-m>|B<--man>  | 
         | 
   119   | 
         | 
   120 =back  | 
         | 
   121   | 
         | 
   122 =head1 FILES  | 
         | 
   123   | 
         | 
   124 The F<dnstools.conf> is used.  | 
         | 
   125   | 
         | 
   126 =cut  |