File Coverage

blib/lib/DNS/ZoneEdit.pm
Criterion Covered Total %
statement 55 66 83.3
branch 19 30 63.3
condition 1 3 33.3
subroutine 12 13 92.3
pod 3 3 100.0
total 90 115 78.2


line stmt bran cond sub pod time code
1             package DNS::ZoneEdit;
2              
3 3     3   52063 use warnings;
  2         4  
  2         57  
4 3     3   392 use strict;
  2         2  
  2         59  
5 2     2   10 use Carp;
  2         6  
  2         179  
6 2     2   25211 use LWP::UserAgent;
  2         151547  
  2         70  
7 2     2   2976 use CGI::Util qw(escape);
  2         10336  
  2         159  
8              
9 2     2   15 use base qw(LWP::UserAgent);
  2         4  
  2         171  
10              
11 2     2   9 use constant URL => 'dynamic.zoneedit.com/auth/dynamic.html';
  2         3  
  2         1283  
12              
13             our $VERSION = 1.1;
14              
15             =head1 NAME
16              
17             DNS::ZoneEdit - Update your ZoneEdit dynamic DNS entries
18              
19             =head1 SYNOPSIS
20              
21             This module allows you to update your ZoneEdit ( http://www.zoneedit.com/ )
22             dynamic DNS records. This is done via an http get using the C
23             module.
24              
25             use DNS::ZoneEdit;
26              
27             my $ze = DNS::ZoneEdit->new();
28             $ze->update( hostname => "cpan.org", username => "foo", password => "bar" ) || die "Failed: $@";
29              
30             =head1 METHODS
31              
32             =over 4
33              
34             =cut
35              
36             =item DNS::ZoneEdit->new();
37              
38             Create a new ZoneEdit object. This is actually an inheritted L
39             object so you can use any of the methods defined in that class. For example,
40             if you are behind a proxy server:
41              
42             my $ze = DNS::ZoneEdit->new();
43             $ze->proxy('http', 'http://proxy.sn.no:8001/');
44              
45             =cut
46              
47             sub new {
48 2     2 1 22 my ($pack,@args) = @_;
49 2         29 my $obj = $pack->SUPER::new(@args);
50 2         6603 $obj->agent("DNS::ZoneEdit perl module");
51 2         108 return $obj;
52             }
53              
54              
55             sub _can_do_https {
56 2     2   795 eval "use Crypt::SSLeay";
  0     4   0  
  0         0  
  4         2818  
57              
58 4         35 return ($@ eq "");
59             }
60              
61              
62             sub _make_request_url {
63 4     4   688 my ($self,%args) = @_;
64              
65 4         8 my %get;
66 4         199 while (my ($k,$v) = each %args) {
67 7 100       223 if ( $k eq "username" ) { $self->{"username"} = $v }
  1 100       3  
    100          
    100          
    50          
    50          
68 1         6 elsif ( $k eq "password" ) { $self->{"password"} = $v }
69 2         9 elsif ( $k eq "hostname" ) { $get{host} = $v }
70 1         5 elsif ( $k eq "myip" ) { $get{dnsto} = $v }
71 0         0 elsif ( $k eq "tld" ) { $get{zones} = $v }
72 2         209 elsif ( $k eq "secure" ) { $self->{"secure"} = $v }
73 0         0 else { carp "update(): Bad argument $k" }
74             }
75              
76 4 100       12 if (defined $self->{secure}) {
77 1 50 33     8 if ($self->{secure} && ! _can_do_https()) {
78 0         0 croak "Can't run in secure mode - try installing Crypt::SSLeay";
79             }
80             } else {
81 3         194 $self->{secure} = _can_do_https();
82             }
83              
84 4 50       14 if ( !$self->{secure} ) {
85 4         710 carp "** USING INSECURE MODE - PLEASE READ THE DOCUMENTATION **\n";
86             }
87              
88             ## Make the GET request URL.
89 4 50       635 my $proto = $self->{"secure"} ? "https://" : "http://";
90 4         14 my $query = join('&', map { escape($_)."=".escape($get{$_}) } keys %get);
  3         31  
91 4         110 return $proto . URL() . "?" . $query;
92             }
93              
94             =item update(%args);
95              
96             Updates your ZoneEdit dynamic DNS records. Valid C<%args> are:
97              
98             =over 8
99              
100             C - Your ZoneEdit login name. This is required.
101              
102             C - The corresponding password. This is required.
103              
104             C - The FQDN of host being updated. This is required.
105              
106             Contains a comma-delimited list of hosts that have IP addresses. This parameter
107             may be C<*.domain.com> to update a wildcard A-record.
108              
109             C - The IP address of the client to be updated. This
110             defaults to the IP address of the incoming connection (handy if you are
111             being natted).
112              
113             C - The root domain of your hostname, for example if your hostname is
114             C you can set C to C. This is to support an
115             undocumented "feature" of zoneedit where you sometimes need to specify it to
116             to update your zone.
117              
118             C - Values are either C<1> or C<0>. If C<1>, then SSL https is used to
119             connect to ZoneEdit. The SSL connection has the big advantage that your
120             passwords are not passed in plain-text accross the internet. Secure is on by
121             default if Crypt::SSLeay is installed. A warning will be generated if it's not
122             installed unless you set C to C<0>. If you set C to C<1> and the
123             module is unavailable, the module will C.
124              
125             =back
126              
127             Returns C on success. On failure it returns C and
128             sets C<$@>.
129              
130             =cut
131              
132             sub update {
133 1     1 1 1648 my ($self,%args) = @_;
134              
135 1 50       6 croak "update(): Argument 'username' is required"
136             unless defined $args{"username"};
137              
138 1 50       4 croak "update(): Argument 'password' is required"
139             unless defined $args{"password"};
140              
141 1 50       3 croak "update(): Argument 'hostname' is required"
142             unless defined $args{"hostname"};
143              
144 1         4 my $update = $self->_make_request_url(%args);
145              
146 1         9 my $resp = $self->get($update);
147 1 50       602806 if ($resp->is_success) {
148 0         0 chomp(my $content = $resp->content);
149 0 0       0 if ( $content =~ m/CODE="2\d+"/ ) {
150 0         0 return 1;
151             } else {
152 0         0 $@ = 'Request failed: "'.$content.'"';
153 0         0 return;
154             }
155             } else {
156 1         20 $@ = 'HTTP Request failed: "'.$resp->status_line.'"';
157 1         49 return;
158             }
159             }
160              
161             =item get_basic_credentials();
162              
163             Since a ZoneEdit object is an subclass of C, it overrides
164             this UserAgent method for your convenience. It uses the credentials passed
165             in the update method. There is no real reason to call, or override this method.
166              
167             =cut
168              
169 0     0 1   sub get_basic_credentials { ($_[0]->{"username"}, $_[0]->{"password"}) }
170              
171             =back
172              
173             =head1 NOTES
174              
175             There are some example scripts in the C directory of the module
176             distribution. These are designed to run out of cron (or similar). You should
177             not run them too often to avoid overloading the ZoneEdit servers. Ideally
178             your code should cache the existing value for your IP, and only update
179             ZoneEdit when it changes.
180              
181             =head1 ACKNOWLEDGEMENTS
182              
183             This module is based on Gavin Brock's excellent L.
184              
185             For more information about the ZoneEdit services please visit
186             http://www.zoneedit.com/. This module is not written nor supported by
187             ZoneEdit LLC.
188              
189             =head1 COPYRIGHT
190              
191             Copyright (c) 2003-2006 Gavin Brock gbrock@cpan.org,
192             Copyright 2009-2010 Evan Giles.
193              
194             This module is free software; you can redistribute it and/or modify it
195             under the same terms as Perl itself.
196              
197             =head1 SEE ALSO
198              
199             L, L
200              
201             =cut
202              
203             1; # End of DNS::ZoneEdit