File Coverage

lib/Text/DHCPLeases/Object.pm
Criterion Covered Total %
statement 88 111 79.2
branch 105 124 84.6
condition 4 9 44.4
subroutine 7 7 100.0
pod 0 2 0.0
total 204 253 80.6


line stmt bran cond sub pod time code
1             package Text::DHCPLeases::Object;
2              
3 2     2   22740 use warnings;
  2         5  
  2         62  
4 2     2   10 use strict;
  2         8  
  2         57  
5 2     2   12 use Carp;
  2         3  
  2         189  
6 2     2   1876 use Class::Struct;
  2         4254  
  2         13  
7 2     2   254 use vars qw($VERSION);
  2         4  
  2         5153  
8             $VERSION = '1.0';
9              
10             # IPv4 regular expression
11             my $IPV4 = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
12              
13             # weekday year/month/day hour:minute:second
14             my $DATE = '\d+ \d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2}';
15              
16             =head1 NAME
17              
18             Text::DHCPLeases::Object - Leases Object Class
19              
20             =head1 SYNOPSIS
21              
22             my $obj = Text::DHCPLeases::Object->parse($string);
23              
24             or
25              
26             my $obj = Text::DHCPLeases::Object->new(%lease_data);
27              
28             print $obj->name;
29             print $obj->type;
30             print $obj->binding_state;
31              
32             =head1 DESCRIPTION
33              
34             DHCPLeases object class. Lease objects can be one of the following types:
35              
36             lease
37             host
38             group
39             subgroup
40             failover-state
41              
42             =cut
43              
44             struct (
45             'type' => '$',
46             'name' => '$',
47             'ip_address' => '$',
48             'fixed_address' => '$',
49             'starts' => '$',
50             'ends' => '$',
51             'tstp' => '$',
52             'tsfp' => '$',
53             'atsfp' => '$',
54             'cltt' => '$',
55             'next_binding_state' => '$',
56             'binding_state' => '$',
57             'uid' => '$',
58             'client_hostname' => '$',
59             'abandoned' => '$',
60             'deleted' => '$',
61             'dynamic_bootp' => '$',
62             'dynamic' => '$',
63             'option_agent_circuit_id' => '$',
64             'option_agent_remote_id' => '$',
65             'hardware_type' => '$',
66             'mac_address' => '$',
67             'set' => '%',
68             'on' => '%',
69             'bootp' => '$',
70             'reserved' => '$',
71             'my_state' => '$',
72             'my_state_date' => '$',
73             'partner_state' => '$',
74             'partner_state_date' => '$',
75             'mclt' => '$',
76             'ddns_rev_name' => '$',
77             'ddns_fwd_name' => '$',
78             'ddns_txt' => '$'
79             );
80              
81             =head1 CLASS METHODS
82              
83             =head2 new - Constructor
84              
85             Arguments:
86             type one of (lease|host|group|subgroup|failover-state)
87             name identification string (address, host name, group name, etc)
88             ip_address
89             fixed_address
90             starts
91             ends
92             tstp
93             tsfp
94             atsfp
95             cltt
96             next_binding_state
97             binding_state
98             uid
99             client_hostname
100             abandoned (flag)
101             deleted (flag)
102             dynamic_bootp (flag)
103             dynamic (flag)
104             option_agent_circuit_id
105             option_agent_remote_id
106             hardware_type
107             mac_address
108             set (hash)
109             on (hash)
110             bootp (flag)
111             reserved (flag)
112             my_state
113             my_state_date
114             partner_state
115             partner_state_date
116             mclt
117             dns_rev_name
118             ddns_fwd_name
119             ddns_txt
120             Returns:
121             New Text::DHCPLeases::Object object
122             Examples:
123              
124             my $lease = Text::DHCPLeases::Object->new(type => 'lease',
125             ip_address => '192.168.1.10',
126             starts => '3 2007/08/15 11:34:58',
127             ends => '3 2007/08/15 11:44:58');
128            
129             =cut
130              
131             ############################################################
132             =head2 parse - Parse object declaration
133              
134             Arguments:
135             Array ref with declaration lines
136             Returns:
137             Hash reference.
138             Examples:
139              
140             my $text = '
141             lease 192.168.254.55 {
142             starts 3 2007/08/15 11:34:58;
143             ends 3 2007/08/15 11:44:58;
144             tstp 3 2007/08/15 11:49:58;
145             tsfp 2 2007/08/14 21:24:19;
146             cltt 3 2007/08/15 11:34:58;
147             binding state active;
148             next binding state expired;
149             hardware ethernet 00:11:85:5d:4e:11;
150             uid "\001\000\021\205]Nh";
151             client-hostname "blah";
152             }';
153              
154             my $lease_data = Text::DHCPLeases::Lease->parse($text);
155             =cut
156             sub parse{
157 36     36 0 691 my ($self, $lines) = @_;
158 36         38 my %obj;
159 36         61 for ( @$lines ){
160 277         730 $_ =~ s/^\s+//o;
161 277         953 $_ =~ s/\s+$//o;
162 277 100       2096 next if ( /^#|^$|\}$/o );
163 240 100       2603 if ( /^lease ($IPV4) /o ){
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
164 30         65 $obj{type} = 'lease';
165 30         73 $obj{name} = $1;
166 30         87 $obj{'ip_address'} = $1;
167             }elsif ( /^(host|group|subgroup) (.*) /o ){
168 1         3 $obj{type} = $1;
169 1         3 $obj{name} = $2;
170             }elsif ( /^failover peer (.*) state/o ){
171 5         11 $obj{type} = 'failover-state';
172 5         17 $obj{name} = $1;
173             }elsif ( /starts ($DATE);/o ){
174 30         92 $obj{starts} = $1;
175             }elsif ( /ends ($DATE|never);/o ){
176 9         26 $obj{ends} = $1;
177             }elsif ( /tstp ($DATE|never);/o ){
178 30         90 $obj{tstp} = $1;
179             }elsif ( /atsfp ($DATE|never);/o ){
180 24         73 $obj{atsfp} = $1;
181             }elsif ( /tsfp ($DATE|never);/o ){
182 29         86 $obj{tsfp} = $1;
183             }elsif ( /cltt ($DATE);/o ){
184 9         27 $obj{cltt} = $1;
185             }elsif ( /^next binding state (\w+);/o ){
186 6         17 $obj{'next_binding_state'} = $1;
187             }elsif ( /^binding state (\w+);/o ){
188 30         110 $obj{'binding_state'} = $1;
189             }elsif ( /^rewind binding state (\w+);/o ){
190 0         0 $obj{'rewind_binding_state'} = $1;
191             }elsif ( /uid (\".*\");/o ){
192 7         21 $obj{uid} = $1;
193             }elsif ( /client-hostname \"(.*)\";/o ){
194 4         12 $obj{'client_hostname'} = $1;
195             }elsif ( /abandoned;/o ){
196 0         0 $obj{abandoned} = 1;
197             }elsif ( /deleted;/o ){
198 0         0 $obj{deleted} = 1;
199             }elsif ( /dynamic-bootp;/o ){
200 0         0 $obj{dynamic_bootp} = 1;
201             }elsif ( /dynamic;/o ){
202 1         3 $obj{dynamic} = 1;
203             }elsif ( /hardware (.+) (.*);/o ){
204 10         27 $obj{'hardware_type'} = $1;
205 10         26 $obj{'mac_address'} = $2;
206             }elsif ( /fixed-address (.*);/o ){
207 1         4 $obj{'fixed_address'} = $1;
208             }elsif ( /option agent\.circuit-id (.*);/o ){
209 0         0 $obj{'option_agent_circuit_id'} = $1;
210             }elsif ( /option agent\.remote-id (.*);/o ){
211 0         0 $obj{'option_agent_remote_id'} = $1;
212             }elsif ( /set (\w+) = (.*);/o ){
213 0         0 $obj{set}{$1} = $2;
214             }elsif ( /on (.*) \{(.*)\};/o ){
215 0         0 my $events = $1;
216 0         0 my @events = split /\|/, $events;
217 0         0 my $statements = $2;
218 0         0 my @statements = split /\n;/, $statements;
219 0         0 $obj{on}{events} = @events;
220 0         0 $obj{on}{statements} = @statements;
221             }elsif ( /bootp;/o ){
222 0         0 $obj{bootp} = 1;
223             }elsif ( /reserved;/o ){
224 0         0 $obj{reserved} = 1;
225             }elsif ( /failover peer \"(.*)\" state/o ){
226 0         0 $obj{name} = $1;
227             }elsif ( /my state (.*) at ($DATE);/o ){
228 5         17 $obj{my_state} = $1;
229 5         13 $obj{my_state_date} = $2;
230             }elsif (/partner state (.*) at ($DATE);/o ){
231 5         15 $obj{partner_state} = $1;
232 5         14 $obj{partner_state_date} = $2;
233             }elsif (/mclt (\w+);/o ){
234 1         4 $obj{mclt} = $1;
235             }elsif (/set ddns-rev-name = \"(.*)\";/o){
236 1         4 $obj{ddns_rev_name} = $1;
237             }elsif (/set ddns-fwd-name = \"(.*)\";/o){
238 1         4 $obj{ddns_fwd_name} = $1;
239             }elsif (/set ddns-txt = \"(.*)\";/o){
240 1         3 $obj{ddns_txt} = $1;
241             }else{
242 0         0 carp "Text::DHCPLeases::Object::parse Error: Statement not recognized: '$_'\n";
243             }
244             }
245 36         113 return \%obj;
246             }
247              
248             =head1 INSTANCE METHODS
249             =cut
250              
251             ############################################################
252             =head2 print - Print formatted string with lease contents
253              
254             Arguments:
255             None
256             Returns:
257             Formatted String
258             Examples:
259             print $obj->print;
260             =cut
261             sub print{
262 36     36 0 11297 my ($self) = @_;
263 36         45 my $out = "";
264 36 100       750 if ( $self->type eq 'lease' ){
    100          
265 30         766 $out .= sprintf("lease %s {\n", $self->ip_address);
266             }elsif ( $self->type eq 'failover-state' ){
267             # These are printed with an extra carriage return in 3.1.0
268 5         250 $out .= sprintf("\nfailover peer %s state {\n", $self->name);
269             }else{
270 1         51 $out .= sprintf("%s %s {\n", $self->type, $self->name);
271             }
272 36 100       966 $out .= sprintf(" starts %s;\n", $self->starts) if $self->starts;
273 36 100       1612 $out .= sprintf(" ends %s;\n", $self->ends) if $self->ends;
274 36 100       1096 $out .= sprintf(" tstp %s;\n", $self->tstp) if $self->tstp;
275 36 100       1663 $out .= sprintf(" tsfp %s;\n", $self->tsfp) if $self->tsfp;
276 36 100       1605 $out .= sprintf(" atsfp %s;\n", $self->atsfp) if $self->atsfp;
277 36 100       1450 $out .= sprintf(" cltt %s;\n", $self->cltt) if $self->cltt;
278 36 100       1155 $out .= sprintf(" binding state %s;\n", $self->binding_state)
279             if $self->binding_state;
280 36 100       1637 $out .= sprintf(" next binding state %s;\n", $self->next_binding_state)
281             if $self->next_binding_state;
282 36 50       1047 $out .= sprintf(" dynamic-bootp;\n") if $self->dynamic_bootp;
283 36 100       907 $out .= sprintf(" dynamic;\n") if $self->dynamic;
284 36 100 66     1087 $out .= sprintf(" hardware %s %s;\n", $self->hardware_type, $self->mac_address)
285             if ( $self->hardware_type && $self->mac_address );
286 36 100       1614 $out .= sprintf(" uid %s;\n", $self->uid) if $self->uid;
287 36 100       1030 $out .= sprintf(" set ddns-rev-name = \"%s\";\n", $self->ddns_rev_name) if $self->ddns_rev_name;
288 36 100       932 $out .= sprintf(" set ddns-txt = \"%s\";\n", $self->ddns_txt) if $self->ddns_txt;
289 36 100       910 $out .= sprintf(" set ddns-fwd-name = \"%s\";\n", $self->ddns_fwd_name) if $self->ddns_fwd_name;
290 36 100       899 $out .= sprintf(" fixed-address %s;\n", $self->fixed_address) if $self->fixed_address;
291 36 50       918 $out .= sprintf(" abandoned;\n") if $self->abandoned;
292 36 50       889 $out .= sprintf(" deleted;\n") if $self->abandoned;
293 36 50       856 $out .= sprintf(" option agent.circuit-id %s;\n", $self->option_agent_circuit_id)
294             if $self->option_agent_circuit_id;
295 36 50       862 $out .= sprintf(" option agent.remote-id %s;\n", $self->option_agent_remote_id)
296             if $self->option_agent_remote_id;
297 36 50       863 if ( defined $self->set ){
298 36         202 foreach my $var ( keys %{ $self->set } ){
  36         724  
299 0         0 $out .= sprintf(" set %s = %s;\n", $var, $self->set->{$var});
300             }
301             }
302 36 50 33     965 if ( $self->on && $self->on->{events} && $self->on->{statements} ){
      33        
303 0         0 my $events = join '|', @{$self->on->{events}};
  0         0  
304 0         0 my $statements = join '\n;', @{$self->on->{statements}};
  0         0  
305 0         0 $out .= sprintf(" on %s { %s }", $events, $statements);
306              
307             }
308 36 100       1800 $out .= sprintf(" client-hostname \"%s\";\n", $self->client_hostname) if $self->client_hostname;
309             # These are only for failover-state objects
310 36 100       1030 $out .= sprintf(" my state %s at %s;\n", $self->my_state, $self->my_state_date)
311             if $self->my_state;
312 36 100       1079 $out .= sprintf(" partner state %s at %s;\n", $self->partner_state, $self->partner_state_date)
313             if $self->partner_state;
314 36 100       1077 $out .= sprintf(" mclt %s;\n", $self->mclt) if $self->mclt;
315 36         231 $out .= "}\n";
316 36         211 return $out;
317             }
318              
319              
320             # Make sure to return 1
321             1;
322              
323             =head1 AUTHOR
324              
325             Carlos Vicente
326              
327              
328             =head1 LICENCE AND COPYRIGHT
329              
330             Copyright (c) 2012, Carlos Vicente . All rights reserved.
331              
332             This module is free software; you can redistribute it and/or
333             modify it under the same terms as Perl itself. See L.
334              
335              
336             =head1 DISCLAIMER OF WARRANTY
337              
338             BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
339             FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
340             OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
341             PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
342             EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
343             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
344             ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
345             YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
346             NECESSARY SERVICING, REPAIR, OR CORRECTION.
347              
348             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
349             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
350             REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
351             LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
352             OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
353             THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
354             RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
355             FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
356             SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
357             SUCH DAMAGES.
358             =cut