File Coverage

blib/lib/NoZone.pm
Criterion Covered Total %
statement 62 62 100.0
branch 48 60 80.0
condition 2 5 40.0
subroutine 7 7 100.0
pod 3 3 100.0
total 122 137 89.0


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   80949 use strict;
  2         16  
  2         62  
24 2     2   12 use warnings;
  2         2  
  2         63  
25              
26 2     2   1011 use File::Spec::Functions qw(catfile);
  2         1761  
  2         151  
27              
28 2     2   1058 use NoZone::Zone;
  2         9  
  2         1814  
29              
30             our $VERSION = '1.3';
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 64344 my $proto = shift;
73 2   33     20 my $class = ref($proto) || $proto;
74 2         5 my $self = {};
75 2         14 my %params = @_;
76              
77 2 50       12 $self->{datadir} = $params{datadir} ? $params{datadir} : "/var/named/data";
78 2 50       10 $self->{confdir} = $params{confdir} ? $params{confdir} : "/etc/named";
79 2 100       9 $self->{masters} = $params{masters} ? $params{masters} : [];
80              
81 2         7 bless $self, $class;
82              
83 2         40 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 13 my $self = shift;
98 2         6 my $cfg = shift;
99              
100 2 50       9 my $zones = exists $cfg->{"zones"} ? $cfg->{"zones"} : {};
101 2         23 foreach my $name (keys %{$zones}) {
  2         16  
102 6         14 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             dmarc => exists $subcfg->{"dmarc"} ? $subcfg->{"dmarc"} : undef,
117 6 100       107 txt => exists $subcfg->{"txt"} ? $subcfg->{"txt"} : {},
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
118             );
119 6         24 $self->{zones}->{$name} = $zone;
120             }
121              
122 2         6 foreach my $name (keys %{$zones}) {
  2         7  
123 6         11 my $subcfg = $zones->{$name};
124 6 100       14 my $inherits = exists $subcfg->{"inherits"} ? $subcfg->{"inherits"} : undef;
125 6 100       16 if ($inherits) {
126 4         7 my $parentzone = $self->{zones}->{$inherits};
127 4         7 my $zone = $self->{zones}->{$name};
128 4         13 $zone->set_inherits($parentzone);
129             }
130             }
131             }
132              
133              
134             =item $nozone->generate_zones($verbose=0);
135              
136             Generate all the bind DNS zone data files for loaded zones.
137             If the C<$verbose> flag is set to a true value, the progress
138             will be printed
139              
140             =cut
141              
142             sub generate_zones {
143 2     2 1 10 my $self = shift;
144 2   50     7 my $verbose = shift || 0;
145              
146 2         17 my $mainfile = catfile($self->{confdir}, "nozone.conf");
147 2 50       20 my $mainfh = IO::File->new(">$mainfile")
148             or die "cannot create $mainfile: $!";
149              
150 2         304 foreach my $name (sort { $a cmp $b } keys %{$self->{zones}}) {
  6         20  
  2         21  
151 6 50       248 print "Processing zone $name\n" if $verbose;
152 6         26 my $zone = $self->{zones}->{$name};
153 6         29 foreach my $domain (sort { $a cmp $b } $zone->get_domains()) {
  2         9  
154 6         163 my $conffile = catfile($self->{confdir}, $domain . ".conf");
155 6         30 my $datafile = catfile($self->{datadir}, $domain . ".data");
156              
157 6         38 print $mainfh "include \"$conffile\";\n";
158              
159 6 50       44 my $conffh = IO::File->new(">$conffile")
160             or die "cannot create $conffile: $!";
161 6 50       820 print " - Generating $conffile\n" if $verbose;
162 6         108 $zone->generate_conffile($conffh, $domain, $datafile, $self->{masters}, $verbose);
163 6 50       33 $conffh->close() or die "cannot save $conffile: $!";
164              
165 6 100       294 next if int(@{$self->{masters}});
  6         30  
166              
167 3 50       21 my $datafh = IO::File->new(">$datafile")
168             or die "cannot create $datafile: $!";
169 3 50       421 print " - Generating $datafile\n" if $verbose;
170 3         21 $zone->generate_datafile($datafh, $domain, $verbose);
171 3 50       17 $datafh->close() or die "cannot save $datafile: $!";
172             }
173             }
174              
175 2 50       80 $mainfh->close() or die "cannot save $mainfile; $!";
176             }
177              
178              
179             1;
180              
181             =back
182              
183             =head1 AUTHORS
184              
185             C was written by Daniel P. Berrange
186              
187             =head1 LICENSE
188              
189             C is distributed under the terms of the GNU GPL version 3
190             or any later version. You should have received a copy of the GNU
191             General Public License along with this program. If not, see
192             C.
193              
194             =head1 SEE ALSO
195              
196             L, C