File Coverage

blib/lib/PowerDNS/Control/Client.pm
Criterion Covered Total %
statement 15 72 20.8
branch 0 18 0.0
condition 0 3 0.0
subroutine 5 13 38.4
pod 8 8 100.0
total 28 114 24.5


line stmt bran cond sub pod time code
1             # $Id: Client.pm 4435 2012-01-14 01:13:46Z augie $
2             # Provides an interface to communicate with PowerDNS::Control::Server which
3             # is used to control both the Authoritative and Recursive servers.
4              
5             package PowerDNS::Control::Client;
6              
7 1     1   24697 use warnings;
  1         3  
  1         36  
8 1     1   7 use strict;
  1         2  
  1         37  
9              
10 1     1   1157 use IO::Socket;
  1         30815  
  1         5  
11 1     1   1840 use English;
  1         2552  
  1         7  
12 1     1   710 use Carp;
  1         2  
  1         793  
13              
14             =head1 NAME
15              
16             PowerDNS::Control::Client - Provides an interface to control the PowerDNS daemon.
17              
18             =head1 VERSION
19              
20             Version 0.03
21              
22             =cut
23              
24             our $VERSION = '0.03';
25              
26             =head1 SYNOPSIS
27              
28             use PowerDNS::Control::Client;
29              
30             # Setting parameters and their default values.
31             my $params = { servers => ['localhost:988'],
32             auth_cred => 'pa55word',
33             };
34              
35             my $pdns = PowerDNS::Control::Client->new($params);
36              
37             =head1 DESCRIPTION
38              
39             PowerDNS::Control::Client provides a client interface to interact
40             with the PowerDNS::Control::Server server.
41              
42             It is maintained in tandem with PowerDNS::Control::Server and is
43             intended to be used with that code; it also serves as a point of
44             reference for anyone who wishes to create their own client code.
45              
46             The methods described below are based on those available in the
47             PowerDNS::Control::Server module which are in turn based on the
48             pdns_control and rec_control programs. Documentation for these
49             programs can be found at:
50              
51             http://docs.powerdns.com/
52              
53             Note: All the commands may not be supported in this module, but the list of
54             supported commands is listed in the Methods section below. Methods that begin
55             with 'auth' control the Authoritative PowerDNS Server and methods that begin
56             with 'rec' control the Recursive PowerDNS Server.
57              
58              
59             =head1 METHODS
60              
61             =head2 new(\%params)
62              
63             my $params = { servers => ['localhost:988'],
64             auth_cred => 'pa55word',
65             };
66              
67             my $pdns = PowerDNS::Control::Client->new($params);
68              
69             Creates a new PowerDNS::Control::Client object.
70              
71             =over 4
72              
73             =item servers
74              
75             A list of servers and ports to connect to. Default is 'localhost:988'.
76              
77             =item auth_cred
78              
79             The authentication credentials the client should provide when the server
80             asks for authentication.
81              
82             =back
83              
84             =cut
85              
86             sub new
87             {
88 0     0 1   my $class = shift;
89 0           my $params= shift;
90 0           my $self = {};
91              
92 0           $OUTPUT_AUTOFLUSH = 1;
93              
94 0   0       bless $self , ref $class || $class;
95              
96 0 0         $self->{'servers'} = defined $params->{'servers'} ? $params->{'servers'} : ['localhost:988'];
97 0 0         $self->{'auth_cred'} = defined $params->{'auth_cred'} ? $params->{'auth_cred'} : undef;
98              
99 0           return $self;
100             }
101              
102             =head2 tell($command_string)
103              
104             Internal method.
105             Expects a scalar command string to send to all of the servers
106             in the 'servers' param; i.e. tell the servers what to do.
107             Returns 0 on success and an Error Message if there was a problem.
108              
109             =cut
110              
111             sub tell
112             {
113 0     0 1   my $self = shift;
114 0           my $command = shift;
115 0           my $errmsg = '';
116              
117 0           for my $server ( @{ $self->{'servers'} } )
  0            
118             {
119             # Try and connect to the server.
120 0           my $conn = $self->connect(\$server);
121              
122 0 0         if ( ! defined $conn )
123             {
124 0           $errmsg .= "Could not connect to server ($server), trying next server if there is one.\n";
125 0           next;
126             }
127              
128             # Tell the server what to do.
129 0           print $conn "$command\n";
130              
131             # Check what the server returned for errors.
132 0           my $line = <$conn>;
133 0           chomp $line;
134              
135 0 0         if ( $line =~ /^-ERR/ )
136             {
137 0           $errmsg .= "Command ($command) on server ($server) failed: $line\n";
138             }
139              
140             # Tell the server we are done sending data.
141 0           print $conn "quit\n";
142             }
143            
144 0 0         return $errmsg ? $errmsg : 0 ;
145             }
146              
147             =head2 connect(\$server)
148              
149             Internal method.
150             Connects to a server and handle authentication if need be.
151             Expects a scalar reference to a single server to connect to.
152             Returns a socket object that can be used to communicate with
153             the server or undef if there was a problem.
154              
155             =cut
156              
157             sub connect
158             {
159 0     0 1   my $self = shift;
160 0           my $server = shift;
161              
162 0           my $sock = new IO::Socket::INET (
163             PeerAddr => $$server,
164             Proto => 'tcp');
165            
166 0 0         if ( ! $sock )
167             {
168 0           carp "Could not connect to $$server : $!";
169 0           return undef;
170             }
171              
172 0           my $line = <$sock>;
173 0           chomp $line;
174              
175             # Check to see if we need to provide authentication.
176 0 0         if ( $line eq '+OK ready for authentication' )
    0          
177             {
178 0           print $sock "AUTH $self->{'auth_cred'}\n";
179              
180 0           $line = <$sock>;
181 0           chomp $line;
182             # Check if we were authenticated.
183 0 0         if ( ! $line eq '+OK Auth sucessful' )
184             {
185 0           carp "Authentication failed\n";
186 0           return undef;
187             }
188             }
189             elsif ($line !~ /^\+OK Welcome/ ) #check that we got the proper banner.
190             {
191 0           carp "Did not receive proper banner from server; got '$line' instead.\n";
192 0           return undef;
193             }
194              
195 0           return $sock;
196             }
197              
198             =head2 auth_retrieve($domain)
199              
200             Tells the Authoritative PowerDNS Server to retrieve a domain.
201             Expects a scalar domain name.
202             Returns 0 on success, error message otherwise.
203              
204             =cut
205              
206             sub auth_retrieve
207             {
208 0     0 1   my $self = shift;
209 0           my $domain = shift;
210 0           return $self->tell("auth_retrieve $domain");
211             }
212              
213             =head2 auth_wipe_cache($domain)
214              
215             Tells the Authoritative PowerDNS server to wipe $domain out of its cache.
216             Expects a scalar domain name.
217             Returns 0 on success, error message otherwise.
218              
219             =cut
220              
221             sub auth_wipe_cache
222             {
223 0     0 1   my $self = shift;
224 0           my $domain = shift;
225 0           return $self->tell("auth_wipe_cache $domain");
226             }
227              
228             =head2 rec_wipe_cache($domain)
229              
230             Tells the Recursive PowerDNS server to wipe $domain out of its cache.
231             Expects a scalar domain name.
232             Returns 0 on success, error message otherwise.
233              
234             =cut
235              
236             sub rec_wipe_cache
237             {
238 0     0 1   my $self = shift;
239 0           my $domain = shift;
240 0           return $self->tell("rec_wipe_cache $domain");
241             }
242              
243             =head2 rec_ping
244              
245             Asks the server if the recursor is running.
246             Expects nothing.
247             Returns 0 on success, error message otherwise.
248              
249             =cut
250              
251             sub rec_ping
252             {
253 0     0 1   my $self = shift;
254 0           my $domain = shift;
255 0           return $self->tell("rec_ping");
256             }
257              
258             =head2 auth_ping
259              
260             Asks the server if the authoritative server is running.
261             Expects nothing.
262             Returns 0 on success, error message otherwise.
263              
264             =cut
265              
266             sub auth_ping
267             {
268 0     0 1   my $self = shift;
269 0           my $domain = shift;
270 0           return $self->tell("auth_ping");
271             }
272              
273             =head1 AUTHOR
274              
275             Augie Schwer, C<< >>
276              
277             http://www.schwer.us
278              
279             =head1 BUGS
280              
281             Please report any bugs or feature requests to
282             C, or through the web interface at
283             L.
284             I will be notified, and then you'll automatically be notified of progress on
285             your bug as I make changes.
286              
287             =head1 SUPPORT
288              
289             You can find documentation for this module with the perldoc command.
290              
291             perldoc PowerDNS::Control::Client
292              
293             You can also look for information at:
294              
295             =over 4
296              
297             =item * AnnoCPAN: Annotated CPAN documentation
298              
299             L
300              
301             =item * CPAN Ratings
302              
303             L
304              
305             =item * RT: CPAN's request tracker
306              
307             L
308              
309             =item * Search CPAN
310              
311             L
312              
313             =back
314              
315             =head1 ACKNOWLEDGEMENTS
316              
317             I would like to thank Sonic.net for allowing me to release this to the public.
318              
319             =head1 COPYRIGHT & LICENSE
320              
321             Copyright 2007 Augie Schwer, all rights reserved.
322              
323             This program is free software; you can redistribute it and/or modify it
324             under the same terms as Perl itself.
325              
326             =head1 VERSION
327              
328             0.03
329             $Id: Client.pm 4435 2012-01-14 01:13:46Z augie $
330              
331             =cut
332              
333             1; # End of PowerDNS::Control::Client