File Coverage

blib/lib/NoZone.pm
Criterion Covered Total %
statement 62 62 100.0
branch 46 58 79.3
condition 2 5 40.0
subroutine 7 7 100.0
pod 3 3 100.0
total 120 135 88.8


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-2021 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   80477 use strict;
  2         15  
  2         68  
24 2     2   11 use warnings;
  2         5  
  2         75  
25              
26 2     2   1034 use File::Spec::Functions qw(catfile);
  2         1879  
  2         148  
27              
28 2     2   1072 use NoZone::Zone;
  2         10  
  2         1820  
29              
30             our $VERSION = '1.2';
31              
32             =head1 NAME
33              
34             NoZone - a Bind DNS zone file generator
35              
36             =head1 SYNOPSIS
37              
38             use NoZone;
39             use YAML qw();
40              
41             my $cfg = YAML::LoadFile("/etc/nozone.yml");
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 62307 my $proto = shift;
73 2   33     21 my $class = ref($proto) || $proto;
74 2         7 my $self = {};
75 2         13 my %params = @_;
76              
77 2 50       34 $self->{datadir} = $params{datadir} ? $params{datadir} : "/var/named/data";
78 2 50       12 $self->{confdir} = $params{confdir} ? $params{confdir} : "/etc/named";
79 2 100       10 $self->{masters} = $params{masters} ? $params{masters} : [];
80              
81 2         7 bless $self, $class;
82              
83 2         41 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 a hash reference, typically
90             resulting from loading a YAML file. See L
91             for a description of the required configuration file
92             format.
93              
94             =cut
95              
96             sub load_config {
97 2     2 1 15 my $self = shift;
98 2         5 my $cfg = shift;
99              
100 2 50       12 my $zones = exists $cfg->{"zones"} ? $cfg->{"zones"} : {};
101 2         21 foreach my $name (keys %{$zones}) {
  2         26  
102 6         17 my $subcfg = $zones->{$name};
103             my $zone = NoZone::Zone->new(
104             default => exists $subcfg->{"default"} ? $subcfg->{"default"} : undef,
105             domains => exists $subcfg->{"domains"} ? $subcfg->{"domains"} : [],
106             lifetimes => exists $subcfg->{"lifetimes"} ? $subcfg->{"lifetimes"} : undef,
107             hostmaster => exists $subcfg->{"hostmaster"} ? $subcfg->{"hostmaster"} : undef,
108             machines => exists $subcfg->{"machines"} ? $subcfg->{"machines"} : {},
109             dns => exists $subcfg->{"dns"} ? $subcfg->{"dns"} : {},
110             mail => exists $subcfg->{"mail"} ? $subcfg->{"mail"} : {},
111             names => exists $subcfg->{"names"} ? $subcfg->{"names"} : {},
112             aliases => exists $subcfg->{"aliases"} ? $subcfg->{"aliases"} : {},
113             wildcard => exists $subcfg->{"wildcard"} ? $subcfg->{"wildcard"} : undef,
114             spf => exists $subcfg->{"spf"} ? $subcfg->{"spf"} : undef,
115             dkim => exists $subcfg->{"dkim"} ? $subcfg->{"dkim"} : {},
116 6 100       120 txt => exists $subcfg->{"txt"} ? $subcfg->{"txt"} : {},
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
117             );
118 6         25 $self->{zones}->{$name} = $zone;
119             }
120              
121 2         6 foreach my $name (keys %{$zones}) {
  2         7  
122 6         12 my $subcfg = $zones->{$name};
123 6 100       15 my $inherits = exists $subcfg->{"inherits"} ? $subcfg->{"inherits"} : undef;
124 6 100       18 if ($inherits) {
125 4         7 my $parentzone = $self->{zones}->{$inherits};
126 4         6 my $zone = $self->{zones}->{$name};
127 4         13 $zone->set_inherits($parentzone);
128             }
129             }
130             }
131              
132              
133             =item $nozone->generate_zones($verbose=0);
134              
135             Generate all the bind DNS zone data files for loaded zones.
136             If the C<$verbose> flag is set to a true value, the progress
137             will be printed
138              
139             =cut
140              
141             sub generate_zones {
142 2     2 1 10 my $self = shift;
143 2   50     8 my $verbose = shift || 0;
144              
145 2         15 my $mainfile = catfile($self->{confdir}, "nozone.conf");
146 2 50       23 my $mainfh = IO::File->new(">$mainfile")
147             or die "cannot create $mainfile: $!";
148              
149 2         395 foreach my $name (sort { $a cmp $b } keys %{$self->{zones}}) {
  6         22  
  2         24  
150 6 50       348 print "Processing zone $name\n" if $verbose;
151 6         30 my $zone = $self->{zones}->{$name};
152 6         44 foreach my $domain (sort { $a cmp $b } $zone->get_domains()) {
  2         9  
153 6         118 my $conffile = catfile($self->{confdir}, $domain . ".conf");
154 6         30 my $datafile = catfile($self->{datadir}, $domain . ".data");
155              
156 6         38 print $mainfh "include \"$conffile\";\n";
157              
158 6 50       129 my $conffh = IO::File->new(">$conffile")
159             or die "cannot create $conffile: $!";
160 6 50       844 print " - Generating $conffile\n" if $verbose;
161 6         102 $zone->generate_conffile($conffh, $domain, $datafile, $self->{masters}, $verbose);
162 6 50       36 $conffh->close() or die "cannot save $conffile: $!";
163              
164 6 100       344 next if int(@{$self->{masters}});
  6         34  
165              
166 3 50       24 my $datafh = IO::File->new(">$datafile")
167             or die "cannot create $datafile: $!";
168 3 50       479 print " - Generating $datafile\n" if $verbose;
169 3         24 $zone->generate_datafile($datafh, $domain, $verbose);
170 3 50       15 $datafh->close() or die "cannot save $datafile: $!";
171             }
172             }
173              
174 2 50       122 $mainfh->close() or die "cannot save $mainfile; $!";
175             }
176              
177              
178             1;
179              
180             =back
181              
182             =head1 AUTHORS
183              
184             C was written by Daniel P. Berrange
185              
186             =head1 LICENSE
187              
188             C is distributed under the terms of the GNU GPL version 3
189             or any later version. You should have received a copy of the GNU
190             General Public License along with this program. If not, see
191             C.
192              
193             =head1 SEE ALSO
194              
195             L, C