|      1 #!/usr/bin/perl  |      1 #!/usr/bin/perl  | 
|      2  |      2  | 
|         |      3 use 5.010; | 
|      3 use warnings; |      4 use warnings; | 
|      4 use strict; |      5 use strict; | 
|      5 use FindBin; |      6 use Pod::Usage; | 
|         |      7 use if $ENV{DEBUG} => "Smart::Comments"; | 
|         |      8 use Cwd qw(abs_path); | 
|         |      9 use File::Path qw(make_path); | 
|         |     10 use File::Basename; | 
|         |     11 use Getopt::Long; | 
|         |     12 use Net::LibIDN qw(:all); | 
|      6 use DNStools::Config qw(get_config); |     13 use DNStools::Config qw(get_config); | 
|         |     14 use Template; | 
|      7  |     15  | 
|      8 my %config; |     16 my $CHARSET = "UTF-8"; | 
|      9  |     17  | 
|     10 if (@ARGV < 2) { |     18 my $opt_force = 0; | 
|     11     print "usage: zone-mk kundennummer domain ... \n"; |     19  | 
|     12     exit 1; |     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                 -noperldoc => system("perldoc -V &>/dev/null"), | 
|         |     31                 -exit      => 0 | 
|         |     32             ); | 
|         |     33         }, | 
|         |     34       ) | 
|         |     35       and @ARGV >= 2 | 
|         |     36       or pod2usage; | 
|         |     37  | 
|         |     38     my $customer = shift; | 
|         |     39  | 
|         |     40     die "$cf{master_dir}: $!"    if not -d -r -x $cf{master_dir}; | 
|         |     41     die "$cf{zone_conf_dir}: $!" if not -d -r -x $cf{zone_conf_dir}; | 
|         |     42  | 
|         |     43     # legt fuer jede domain in @ARGV ein verzeichnis in $master_dir an. | 
|         |     44     # schreibt aus den angegebenen templates die dateien $zonefile und $config | 
|         |     45     # in die entsprechenden verzeichnisse. | 
|         |     46     for my $utf8domain (@ARGV) { | 
|         |     47  | 
|         |     48         my $domain     = idn_to_ascii($utf8domain, $CHARSET); | 
|         |     49         my $zonefile   = "$cf{master_dir}/$domain/$domain"; | 
|         |     50         my $configfile = "$cf{zone_conf_dir}/$domain"; | 
|         |     51         my $now        = time; | 
|         |     52  | 
|         |     53         make_path dirname $zonefile; | 
|         |     54  | 
|         |     55         if (-f $zonefile and not $opt_force) { | 
|         |     56             say "skipping $utf8domain: zone file '$zonefile' exists."; | 
|         |     57             next; | 
|         |     58         } | 
|         |     59  | 
|         |     60         if (-f $configfile and not $opt_force) { | 
|         |     61             say "skipping $utf8domain: config file '$configfile' exists."; | 
|         |     62             next; | 
|         |     63         } | 
|         |     64  | 
|         |     65         say "domain $utf8domain ($domain) for $customer."; | 
|         |     66  | 
|         |     67         my %vars = ( | 
|         |     68             domain     => $domain, | 
|         |     69             utf8domain => $utf8domain, | 
|         |     70             now        => $now, | 
|         |     71             zonefile   => abs_path($zonefile), | 
|         |     72             customer   => $customer, | 
|         |     73             hostmaster => $cf{hostmaster}, | 
|         |     74             primary    => $cf{primary}, | 
|         |     75             secondary  => $cf{secondary}, | 
|         |     76         ); | 
|         |     77  | 
|         |     78         my $tt = Template->new(INCLUDE_PATH => $cf{template_dir}) | 
|         |     79           or die "$Template::ERROR\n"; | 
|         |     80  | 
|         |     81         $tt->process("named.zone",   \%vars, $zonefile)   || die $tt->error; | 
|         |     82         $tt->process("named.config", \%vars, $configfile) || die $tt->error; | 
|         |     83  | 
|         |     84     } | 
|         |     85  | 
|     13 } |     86 } | 
|     14  |     87  | 
|     15 # oeffnet Konfigurations- und Templatefiles - relativ oder absolut |     88 __END__ | 
|     16 my @templc = ( |         | 
|     17     "$FindBin::Bin/templates/named.config", |         | 
|     18     "/etc/dnstools/templates/named.config" |         | 
|     19 ); |         | 
|     20 my @templz = |         | 
|     21   ("$FindBin::Bin/templates/named.zone", "/etc/dnstools/templates/named.zone"); |         | 
|     22  |     89  | 
|     23 for (grep { -f } @templc) { |     90 =head1 NAME | 
|     24     open(TEMPCONF, $_) or die "Can't open $_: $!\n"; |         | 
|     25 } |         | 
|     26 unless (seek(TEMPCONF, 0, 0)) { |         | 
|     27     die "Can't open template (searched: @templc)\n"; |         | 
|     28 } |         | 
|     29  |     91  | 
|     30 for (grep { -f } @templz) { |     92     zone-mk - create a new zone | 
|     31     open(TEMPZONE, $_) or die "Can't open $_: $!\n"; |         | 
|     32 } |         | 
|     33 unless (seek(TEMPZONE, 0, 0)) { |         | 
|     34     die "Can't open template (searched: @templz)\n"; |         | 
|     35 } |         | 
|     36  |     93  | 
|         |     94 =head1 SYNOPSIS | 
|     37  |     95  | 
|     38 %config = get_config(); |     96     zone-mk [-f|--force] <customer-id> <domain>... | 
|     39  |     97  | 
|     40 my $primary       = $config{primary}; |     98 =head1 DESCRIPTION | 
|     41 my $secondary     = $config{secondary}; |         | 
|     42 my $zone_conf_dir = $config{zone_conf_dir}; |         | 
|     43 my $master_dir    = $config{master_dir}; |         | 
|     44 my $customer      = shift @ARGV; |         | 
|     45 chomp(my $primary_ip   = `dig +short $primary`); |         | 
|     46 chomp(my $secondary_ip = `dig +short $secondary`); |         | 
|     47 chomp(my $this_host    = `hostname -f`); |         | 
|     48 chomp(my $this_ip      = `hostname -i`); |         | 
|     49 chomp(my $this_domain  = `hostname -d`); |         | 
|     50 chomp(my $time         = `date +%Y%m%d00`); |         | 
|     51 chomp(my $start        = `date -I`); |         | 
|     52 my $hostmaster = "hostmaster.$this_domain"; |         | 
|     53  |     99  | 
|     54 unless (-d $master_dir and -r $master_dir) { |    100 B<zone-mk> creates a new DNS zone file and the config snipped. | 
|     55     die "$master_dir: $!\n"; |         | 
|     56 } |         | 
|     57  |    101  | 
|     58 unless (-d $zone_conf_dir and -r $zone_conf_dir) { |    102 =head1 OPTIONS | 
|     59     die "$master_dir: $!\n"; |         | 
|     60 } |         | 
|     61  |    103  | 
|     62 # legt fuer jede domain in @ARGV ein verzeichnis in $master_dir an. |    104 =over | 
|     63 # schreibt aus den angegebenen templates die dateien $zonefile und $config |         | 
|     64 # in die entsprechenden verzeichnisse. |         | 
|     65 for (@ARGV) { |         | 
|     66  |    105  | 
|     67     chomp(my $domain = `idn --quiet "$_"`); |    106 =item B<-f>|B<--force> | 
|     68     my $zonefile   = "$master_dir/$domain/$domain"; |         | 
|     69     my $config     = "$zone_conf_dir/$domain"; |         | 
|     70     my $utf8domain = "$_"; |         | 
|     71  |    107  | 
|     72     unless (-d "$master_dir/$domain") { |    108 Crate zone file and config even if they exist. (default: off) | 
|     73         `mkdir $master_dir/$domain`; |         | 
|     74     } |         | 
|     75  |    109  | 
|     76     if (-f $zonefile) { |    110 =item B<-h>|B<--help> | 
|     77         $zonefile =~ s#/.*/##; |         | 
|     78         print "$zonefile exists. Skipping $domain\n"; |         | 
|     79         next; |         | 
|     80     } |         | 
|     81     if (-f $config) { |         | 
|     82         $config =~ s#/.*/##; |         | 
|     83         print "$config exists. Skipping $domain\n"; |         | 
|     84         next; |         | 
|     85     } |         | 
|     86  |    111  | 
|     87     print "$domain ($_) for $customer \n"; |    112 =item B<-m>|B<--man> | 
|     88  |    113  | 
|     89     my @tempzone = <TEMPZONE>; |    114 =back | 
|     90     for (@tempzone) { |         | 
|     91         s#<start>#$start#; |         | 
|     92         s#<domain>#$domain#; |         | 
|     93         s#<time>#$time#; |         | 
|     94         s#<primary>#$primary#; |         | 
|     95         s#<secondary>#$secondary#; |         | 
|     96         s#<hostmaster>#$hostmaster#; |         | 
|     97         s#<customer>#$customer#; |         | 
|     98         s#<utf8domain>#$utf8domain#; |         | 
|     99     } |         | 
|    100  |    115  | 
|    101     open(ZONEOUT, ">$zonefile"); |    116 =head1 FILES | 
|    102     print ZONEOUT @tempzone; |         | 
|    103     close(ZONEOUT); |         | 
|    104  |    117  | 
|    105     my @tempconf = <TEMPCONF>; |    118 The F<dnstools.conf> is used. | 
|    106     for (@tempconf) { |         | 
|    107         s#<domain>#$domain#; |         | 
|    108         s#<start>#$start#; |         | 
|    109         s#<customer>#$customer#; |         | 
|    110         s#<utf8domain>#$utf8domain#; |         | 
|    111         s#<file>#$master_dir/$domain/$domain#; |         | 
|    112         s#<primary_ip>#$primary_ip#; |         | 
|    113         s#<secondary_ip>#$secondary_ip#; |         | 
|    114     } |         | 
|    115  |    119  | 
|    116     open(CONFOUT, ">$config"); |    120 =cut | 
|    117     print CONFOUT @tempconf; |         | 
|    118     close(CONFOUT); |         | 
|    119 } |         |