File Coverage

blib/lib/NoZone.pm
Criterion Covered Total %
statement 62 62 100.0
branch 17 28 60.7
condition 2 5 40.0
subroutine 7 7 100.0
pod 3 3 100.0
total 91 105 86.6


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             #
3             # NoZone: a Bind DNS zone file generator
4             #
5             # Copyright (C) 2013 Daniel P. Berrange
6             #
7             # This program is free software: you can redistribute it and/or modify
8             # it under the terms of the GNU General Public License as published by
9             # the Free Software Foundation, either version 3 of the License, or
10             # (at your option) any later version.
11             #
12             # This program is distributed in the hope that it will be useful,
13             # but WITHOUT ANY WARRANTY; without even the implied warranty of
14             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15             # GNU General Public License for more details.
16             #
17             # You should have received a copy of the GNU General Public License
18             # along with this program. If not, see .
19             #
20              
21             package NoZone;
22              
23 2     2   31999 use strict;
  2         6  
  2         94  
24 2     2   12 use warnings;
  2         5  
  2         68  
25              
26 2     2   2070 use File::Spec::Functions qw(catfile);
  2         1970  
  2         184  
27              
28 2     2   1413 use NoZone::Zone;
  2         8  
  2         2032  
29              
30             our $VERSION = '1.0';
31              
32             =head1 NAME
33              
34             NoZone - a Bind DNS zone file generator
35              
36             =head1 SYNOPSIS
37              
38             use NoZone;
39              
40             my $cfg = Config::Record->new();
41             $cfg->load("/etc/nozone.cfg");
42              
43             my $nozone = NoZone->new();
44             $nozone->load_config($cfg);
45             $nozone->generate_zones();
46              
47             =head1 DESCRIPTION
48              
49             The C module provides a system for generating
50             Bind DNS zone files from data stored in a much simpler
51             configuration file format.
52              
53             =head1 METHODS
54              
55             =over 4
56              
57             =item my $nozone = NoZone->new(
58             datadir => "/var/named/data",
59             confdir => "/etc/named",
60             masters => []);
61              
62             Creates a new C object instance. The C parameter
63             specifies where the zone data files should be created, while C
64             specifies where the zone conf files should be created. Both have
65             sensible defaults if omitted. The optional C list provides
66             a list of master servers. If present, only a slave zone config will
67             be generated.
68              
69             =cut
70              
71             sub new {
72 2     2 1 32146 my $proto = shift;
73 2   33     18 my $class = ref($proto) || $proto;
74 2         4 my $self = {};
75 2         10 my %params = @_;
76              
77 2 50       10 $self->{datadir} = $params{datadir} ? $params{datadir} : "/var/named/data";
78 2 50       9 $self->{confdir} = $params{confdir} ? $params{confdir} : "/etc/named";
79 2 100       9 $self->{masters} = $params{masters} ? $params{masters} : [];
80              
81 2         3 bless $self, $class;
82              
83 2         8 return $self;
84             }
85              
86             =item $nozone->load_config($cfg);
87              
88             Load details for the DNS zones from the configuration
89             data in C<$cfg>, which is an instance of the C
90             class. See L for a description of the required
91             configuration file format.
92              
93             =cut
94              
95             sub load_config {
96 2     2 1 37 my $self = shift;
97 2         5 my $cfg = shift;
98              
99 2         13 my $zones = $cfg->get("zones", {});
100 2         77 foreach my $name (keys %{$zones}) {
  2         10  
101 6         25 my $subcfg = $cfg->view("zones/$name");
102 6         524 my $zone = NoZone::Zone->new(
103             default => $subcfg->get("default", undef),
104             domains => $subcfg->get("domains", []),
105             lifetimes => $subcfg->get("lifetimes", undef),
106             hostmaster => $subcfg->get("hostmaster", undef),
107             machines => $subcfg->get("machines", {}),
108             dns => $subcfg->get("dns", {}),
109             mail => $subcfg->get("mail", {}),
110             names => $subcfg->get("names", {}),
111             aliases => $subcfg->get("aliases", {}),
112             wildcard => $subcfg->get("wildcard", undef),
113             );
114 6         52 $self->{zones}->{$name} = $zone;
115             }
116              
117 2         23 foreach my $name (keys %{$zones}) {
  2         6  
118 6         22 my $subcfg = $cfg->view("zones/$name");
119 6         379 my $inherits = $subcfg->get("inherits", undef);
120 6 100       157 if ($inherits) {
121 4         10 my $parentzone = $self->{zones}->{$inherits};
122 4         8 my $zone = $self->{zones}->{$name};
123 4         15 $zone->set_inherits($parentzone);
124             }
125             }
126             }
127              
128              
129             =item $nozone->generate_zones($verbose=0);
130              
131             Generate all the bind DNS zone data files for loaded zones.
132             If the C<$verbose> flag is set to a true value, the progress
133             will be printed
134              
135             =cut
136              
137             sub generate_zones {
138 2     2 1 10 my $self = shift;
139 2   50     6 my $verbose = shift || 0;
140              
141 2         13 my $mainfile = catfile($self->{confdir}, "nozone.conf");
142 2 50       20 my $mainfh = IO::File->new(">$mainfile")
143             or die "cannot create $mainfile: $!";
144              
145 2         281 foreach my $name (sort { $a cmp $b } keys %{$self->{zones}}) {
  4         11  
  2         15  
146 6 50       160 print "Processing zone $name\n" if $verbose;
147 6         12 my $zone = $self->{zones}->{$name};
148 6         23 foreach my $domain (sort { $a cmp $b } $zone->get_domains()) {
  2         6  
149 6         86 my $conffile = catfile($self->{confdir}, $domain . ".conf");
150 6         33 my $datafile = catfile($self->{datadir}, $domain . ".data");
151              
152 6         34 print $mainfh "include \"$conffile\";\n";
153              
154 6 50       40 my $conffh = IO::File->new(">$conffile")
155             or die "cannot create $conffile: $!";
156 6 50       747 print " - Generating $conffile\n" if $verbose;
157 6         29 $zone->generate_conffile($conffh, $domain, $datafile, $self->{masters}, $verbose);
158 6 50       207 $conffh->close() or die "cannot save $conffile: $!";
159              
160 6 100       350 next if int(@{$self->{masters}});
  6         30  
161              
162 3 50       19 my $datafh = IO::File->new(">$datafile")
163             or die "cannot create $datafile: $!";
164 3 50       324 print " - Generating $datafile\n" if $verbose;
165 3         12 $zone->generate_datafile($datafh, $domain, $verbose);
166 3 50       11 $datafh->close() or die "cannot save $datafile: $!";
167             }
168             }
169              
170 2 50       125 $mainfh->close() or die "cannot save $mainfile; $!";
171             }
172              
173              
174             1;
175              
176             =back
177              
178             =head1 AUTHORS
179              
180             C was written by Daniel P. Berrange
181              
182             =head1 LICENSE
183              
184             C is distributed under the terms of the GNU GPL version 3
185             or any later version. You should have received a copy of the GNU
186             General Public License along with this program. If not, see
187             C.
188              
189             =head1 SEE ALSO
190              
191             L, C