File Coverage

blib/lib/Net/DNS/ZoneParse/Zone.pm
Criterion Covered Total %
statement 40 81 49.3
branch 8 36 22.2
condition 4 10 40.0
subroutine 8 16 50.0
pod 8 8 100.0
total 68 151 45.0


line stmt bran cond sub pod time code
1             package Net::DNS::ZoneParse::Zone;
2              
3 7     7   43707 use strict;
  7         16  
  7         317  
4 7     7   42 use warnings;
  7         14  
  7         332  
5 7     7   49 use vars qw($VERSION);
  7         13  
  7         409  
6 7     7   717 use Net::DNS::ZoneParse;
  7         32  
  7         254  
7 7     7   52 use base qw(Class::Accessor);
  7         13  
  7         8710  
8              
9             $VERSION = 0.102;
10              
11             __PACKAGE__->mk_accessors(qw/rr ttl/);
12              
13             =pod
14              
15             =head1 NAME
16              
17             Net::DNS::ZoneParse::Zone - A representation of a given zone.
18              
19             =head1 SYNOPSIS
20              
21             use Net::DNS::ZoneParse::Zone;
22             use Net::DNS::RR;
23              
24             my $zone = Net::DNS::ZoneParse::Zone->new({ filename => "db.example.com" });
25            
26             my $newrr = Net::DNS::RR::new({ ... });
27             $zone->add($newrr);
28             $zone->rr->[-1]->name eq $newrr->name;
29             $zone->save;
30              
31             =head1 DESCRIPTION
32              
33             Net::DNS::ZoneParse::Zone is the representation of one zonefile, used by
34             N::D::ZoneParse. It can be used to access and modify all information of
35             this zone and write them back transperantly.
36              
37             =head2 METHODS
38              
39             =head3 new
40              
41             $zone = Net::DNS::ZoneParse::Zone->new("example.com" [, $param]);
42              
43             returns a new Zone-object. The first parameter is the domain-name or origin
44             of that zone, the optional second is a hash-reference of one or more
45             of the followin:
46              
47             =over
48              
49             =item path
50              
51             The directory to use as working dir for the file. The current directory, if not
52             given.
53              
54             =item filename
55              
56             The name of the file to read. If not given, "db." will prepended to the name
57             of the zone; thus "db.example.com" would be used for "example.com".
58              
59             =item ttl
60              
61             The default time to live for the resource records.
62              
63             =item parent
64              
65             if given, is the Net::DNS::ZoneParse object, this Zone is derived from
66              
67             =item dontload
68              
69             by default, the corresponding zonefile will be loaded on creating the new
70             zone. If this dontload is true, the zone will start empty.
71              
72             =back
73              
74             =cut
75              
76             sub new {
77 2     2 1 6530 my ($self, $zone, $config) = @_;
78 2 50       12 $config = {} unless(defined $config);
79 2   100     47 my %config = (
      33        
      50        
80             filename => ($config->{path} || ".")."/".
81             ($config->{filename} || "db.$zone"),
82             zone => $zone,
83             ttl => $config->{ttl} || 0,
84             parent => $config->{parent},
85             rr => [],
86             );
87 2         5 my $zpz = bless(\%config);
88 2 100       13 $zpz->load() unless($config->{dontload});
89 1         4 return $zpz;
90             }
91              
92             =pod
93              
94             =head3 load
95              
96             $zone->load()
97              
98             Will open the corresspondig file and parse it, intializing the array
99             of resource records
100              
101             =cut
102              
103             sub load {
104 1     1 1 3 my ($self) = @_;
105 1 50       28 return unless( -f $self->{filename} );
106 1 50       5 if($self->{parent}) {
107 0         0 my %param = (
108             origin => $self->{zone},
109             ttl => $self->ttl,
110             nocache => 1,
111             );
112 0         0 $self->{rr} = $self->{parent}->parse($self->{filename}, \%param);
113 0 0       0 $self->{ttl} = $param{ttl} if($param{ttl});
114             } else {
115 1         9 $self->{rr} = Net::DNS::ZoneParse::parse({
116             file => $self->{filename}
117             });
118             }
119             }
120              
121             =pod
122              
123             =head3 save
124              
125             $zone->save();
126              
127             will write back the contents of the zone to the corresponding filename
128              
129             =cut
130              
131             sub save {
132 0     0 1 0 my ($self) = @_;
133 0         0 my $file;
134 0         0 open($file, ">", $self->{filename});
135 0         0 print $file $self->string;
136 0         0 close $file;
137             }
138              
139             =pod
140              
141             =head3 string
142              
143             $zonetext = $zone->string();
144              
145             string will return the contents of a zonefile representing the current state of
146             the zone.
147              
148             =cut
149              
150             sub string {
151 0     0 1 0 my ($self) = @_;
152 0 0       0 if($self->{parent}) {
153 0         0 return $self->{parent}->writezone($self->{zone});
154             } else {
155 0         0 return Net::DNS::ZoneParse::writezone($self->rr, {
156             origin => $self->{zone},
157             ttl => $self->ttl,
158             });
159             }
160             }
161              
162             =pod
163              
164             =head3 add
165              
166             $zone->add($rr)
167              
168             add can be used to add further resource records to the zone
169              
170             =cut
171              
172             sub add {
173 1     1 1 3 my $self = shift;
174 1         2 my $lnr = 0;
175 1         2 my $rr = ${$self->rr}[-1];
  1         6  
176 1 50       25 $lnr = $rr->{Line} if $rr->{Line};
177              
178 1         2 $rr = $_[0];
179 1 50       13 $rr = [ @_ ] if(ref($rr) ne "ARRAY");
180             map {
181 2 50       12 if($_->{Line}) {
  1         3  
182 0         0 $lnr = $_{Line};
183             } else {
184 2         3 $lnr+=1;
185 2         5 $_->{Line} = $lnr
186             }
187 1         2 } @{$rr};
188 1         2 push(@{$self->rr}, @{$rr});
  1         3  
  1         11  
189             }
190              
191             # returns a generic search routine depending on the given argumenttype
192             sub _findffunc {
193 0     0     my ($rr) = @_;
194              
195 0 0   0     return sub { $_[0]->string ne $_[1]->string } if(ref($rr) eq "Net::DNS::RR");
  0            
196             return sub {
197 0     0     my $item = $_[0];
198 0           for(keys(%{$_[1]})) {
  0            
199 0 0         return 1 if($_[1]->{$_} ne $_[0]->{$_});
200             }
201 0           return undef;
202 0 0         } if(ref($rr) eq "HASH");
203 0           return 1;
204             }
205              
206             =pod
207              
208             =head3 delete
209              
210             $zone->delete($rr)
211              
212             deletes the given RR from the zone. If no RR is given, the zone will be purged.
213             The RR can either be given as a Net::DNS::RR-object, in this case, the
214             string representation of the record is compared to find the correct one.
215             As an alternative a HASH-reference can be used, to filter for a set of RRs. In
216             this case all keys of the hash must be found and equal in the RR.
217              
218             =cut
219              
220             sub delete {
221 0     0 1   my ($self, $rr) = @_;
222 0 0         unless($rr) {
223 0           $self->{rr} = [];
224 0           return;
225             }
226 0           my $ffunc = _findffunc($rr);
227              
228 0           $self->{rr} = [ grep &$ffunc($_,$rr), @{$self->{rr}} ];
  0            
229             }
230              
231             =pod
232              
233             =head3 replace
234              
235             $zone->replace($old, $new)
236              
237             Replaces all RRs of the zone matching $old by the Net::DNS::RR-object given in
238             $new. $old is handled in the same way as $rr in the delete-method. If $new
239             is not given, replace behaves exactly like delete.
240              
241             =cut
242              
243             sub replace {
244 0     0 1   my ($self, $rr, $new) = @_;
245 0 0         return unless($rr);
246 0 0         return $self->delete($rr) unless($new);
247 0           my $ffunc = _findffunc($rr);
248 0 0         $self->{rr} = [ map { &$ffunc($_,$rr)? $_ :$new } @{$self->{rr}}];
  0            
  0            
249             }
250              
251             =head3 delall
252              
253             $zone->delall();
254              
255             Deletes all parsed resource records and deletes the corresponding zonefile from
256             disk.
257              
258             =cut
259              
260             sub delall {
261 0     0 1   my ($self) = @_;
262              
263 0 0 0       unlink($self->{filename})
264             if($self->{filename} and -f $self->{filename});
265 0           $self->{rr} = [];
266 0 0         $self->{parent}->uncache($self->{zone}) if($self->{parent});
267             }
268              
269             =head1 SEE ALSO
270              
271             Net::DNS::ZoneParse
272              
273             =head1 AUTHOR
274              
275             Benjamin Tietz Ebenjamin@micronet24.deE
276              
277             =head1 COPYRIGHT
278              
279             Copyright (C) 2010 by Benjamin Tietz
280              
281             This library is free software; you can redistribute it and/or modify
282             it under the same terms as Perl itself, either Perl version 5.10.0 or,
283             at your option, any later version of Perl 5 you may have available.
284              
285             =cut
286              
287             1;
288