File Coverage

blib/lib/Monit/HTTP.pm
Criterion Covered Total %
statement 103 127 81.1
branch 19 34 55.8
condition 12 32 37.5
subroutine 19 22 86.3
pod 8 8 100.0
total 161 223 72.2


line stmt bran cond sub pod time code
1             #!/bin/false
2             # ABSTRACT: An OOP interface to Monit.
3             # PODNAME: Monit::HTTP
4              
5 5     5   419772 use warnings;
  5         77  
  5         139  
6 5     5   24 use strict;
  5         9  
  5         78  
7 5     5   47 use v5.10;
  5         12  
8              
9             package Monit::HTTP;
10             $Monit::HTTP::VERSION = '0.05';
11 5     5   3081 use HTTP::Tiny;
  5         193070  
  5         156  
12 5     5   1986 use XML::Fast;
  5         47174  
  5         242  
13 5     5   30 use Carp qw( croak );
  5         8  
  5         850  
14              
15             our (
16             %MONIT_ACTIONS,
17             %MONIT_ACTIONS_REV,
18             %MONIT_STATUS,
19             %MONIT_STATUS_REV,
20             %MONIT_TYPES,
21             %MONIT_TYPES_REV,
22             %MONIT_MONITOR,
23             %MONIT_MONITOR_REV,
24             );
25              
26             BEGIN {
27              
28 5     5   32 %MONIT_ACTIONS_REV = (
29             'stop' => 'ACTION_STOP',
30             'start' => 'ACTION_START',
31             'restart' => 'ACTION_RESTART',
32             'monitor' => 'ACTION_MONITOR',
33             'unmonitor' => 'ACTION_UNMONITOR',
34             );
35 5         34 %MONIT_ACTIONS = reverse %MONIT_ACTIONS_REV;
36              
37 5         21 %MONIT_MONITOR_REV = (
38             0 => 'off',
39             1 => 'monitored',
40             2 => 'initializing',
41             );
42 5         24 %MONIT_MONITOR = reverse %MONIT_MONITOR_REV;
43              
44 5         16 %MONIT_STATUS_REV = (
45             0 => 'Running',
46             32 => 'Connection Failed',
47             512 => 'Does not exist',
48             );
49 5         16 %MONIT_STATUS = reverse %MONIT_STATUS_REV;
50              
51 5         30 %MONIT_TYPES_REV = (
52             0 => 'TYPE_FILESYSTEM',
53             1 => 'TYPE_DIRECTORY',
54             2 => 'TYPE_FILE',
55             3 => 'TYPE_PROCESS',
56             4 => 'TYPE_HOST',
57             5 => 'TYPE_SYSTEM',
58             6 => 'TYPE_FIFO',
59             7 => 'TYPE_STATUS',
60             );
61 5         245 %MONIT_TYPES = reverse %MONIT_TYPES_REV;
62              
63             }
64              
65             # This creates constants from all the above values
66             # perl 5.10 has strange issues just going:
67             # use constant reverse %{ MONIT_TYPES() }
68             # So work around it with do {}
69 5     5   28 use constant do { my %foo = reverse( %MONIT_TYPES_REV ); \%foo };
  5         8  
  5         22  
  5         29  
  5         637  
70 5     5   30 use constant do { my %foo = reverse( %MONIT_ACTIONS_REV ); \%foo };
  5         16  
  5         7  
  5         39  
  5         416  
71              
72 5     5   730 use parent qw(Exporter);
  5         529  
  5         30  
73             our (%EXPORT_TAGS, @EXPORT_OK);
74              
75             %EXPORT_TAGS = (
76             constants => [qw/
77             ACTION_MONITOR
78             ACTION_RESTART
79             ACTION_START
80             ACTION_STOP
81             ACTION_UNMONITOR
82              
83             TYPE_DIRECTORY
84             TYPE_FIFO
85             TYPE_FILE
86             TYPE_FILESYSTEM
87             TYPE_HOST
88             TYPE_PROCESS
89             TYPE_SYSTEM
90             /],
91              
92             hashes => [qw/
93             %MONIT_ACTIONS
94             %MONIT_ACTIONS_REV
95             %MONIT_STATUS
96             %MONIT_STATUS_REV
97             %MONIT_TYPES
98             %MONIT_TYPES_REV
99             %MONIT_MONITOR
100             %MONIT_MONITOR_REV
101             /],
102             );
103              
104             @EXPORT_OK = (
105             @{$EXPORT_TAGS{constants}},
106             @{$EXPORT_TAGS{hashes}},
107             );
108              
109             Exporter::export_ok_tags( keys %EXPORT_TAGS );
110              
111              
112             sub new {
113 3     3 1 1744 my ($class, %self) = @_;
114              
115             # OOP stuff
116 3   33     18 $class = ref($class) || $class;
117 3         5 my $self = \%self;
118 3         6 bless $self, $class;
119              
120             # set some defaults, if not already set
121 3   100     31 $self->{hostname} ||= 'localhost';
122 3   50     17 $self->{port} ||= 2812;
123 3   50     13 $self->{use_auth} ||= 0;
124 3 50       9 if($self->{use_auth}) {
125 0   0     0 $self->{username} ||= 'admin';
126 0   0     0 $self->{password} ||= 'monit';
127             }
128              
129 3         29 $self->{ua} = HTTP::Tiny->new( agent => sprintf('Perl %s/%s',__PACKAGE__,$Monit::HTTP::VERSION) );
130 3         234 $self->_generate_url;
131              
132 3         6 return $self
133             }
134              
135             sub _generate_url {
136              
137 5     5   8 my $self = shift;
138              
139 5         9 my $auth = '';
140 5 0 33     19 if (defined $self->{username} and defined $self->{password} and $self->{use_auth}) {
      33        
141             $auth = sprintf('%s:%s@',$self->{username},$self->{password})
142 0         0 }
143              
144             $self->{status_url} = sprintf('http://%s%s:%d/_status?format=xml',
145 5         24 $auth, $self->{hostname}, $self->{port});
146             }
147              
148              
149             sub set_hostname {
150 1     1 1 1100 my ($self, $hostname) = @_;
151 1         3 $self->{hostname} = $hostname;
152 1         4 $self->_generate_url;
153 1         3 return $hostname
154             }
155              
156              
157             sub set_port {
158 1     1 1 810 my ($self, $port) = @_;
159 1         2 $self->{port} = $port;
160 1         4 $self->_generate_url;
161 1         3 return $port
162             }
163              
164              
165             sub set_username {
166 0     0 1 0 my ($self, $username) = @_;
167 0         0 $self->{username} = $username;
168 0         0 $self->_generate_url;
169 0         0 return $username
170             }
171              
172              
173             sub set_password {
174 0     0 1 0 my ($self, $password ) = @_;
175 0         0 $self->{password} = $password;
176 0         0 $self->_generate_url;
177 0         0 return $password
178             }
179              
180              
181             sub _fetch_info {
182 7     7   10 my ($self) = @_;
183              
184 7         102 my $res = $self->{ua}->get( $self->{status_url} );
185 7 100       36931 if ($res->{success}) {
186 3         8 $self->_set_xml($res->{content});
187 3         4 $self->{xml_hash} = xml2hash( $self->_get_xml );
188             }
189             else {
190             croak sprintf "Error while connecting to %s !\n" .
191             "Status: %s\nReason: %s\nContent: %s\n",
192 4   50     531 $self->{status_url}, $res->{status}, $res->{reason}, $res->{content} || 'NIL';
193             }
194              
195 3         646 return 1
196             }
197              
198              
199             sub get_services {
200 5     5 1 5342 my ($self, $type) = @_;
201 5         16 my @services;
202 5   50     23 $type ||= '-1';
203              
204             croak "Don't understand this service type!\n"
205 5 50 33     19 unless $type == -1 or grep {$_ == $type} keys %{MONIT_TYPES()};
  0         0  
  0         0  
206              
207 5         15 $self->_fetch_info;
208              
209 1         2 for my $s (@{$self->{xml_hash}->{monit}->{service}}) {
  1         14  
210 2 50 33     24 if ($type == -1 or $s->{'-type'} == $type) {
211 2         5 push @services, $s->{name};
212             }
213             }
214 1         4 return @services;
215             }
216              
217              
218             sub _set_xml {
219 3     3   6 my ($self, $xml) = @_;
220 3         6 $self->{status_raw_content} = $xml;
221             }
222              
223              
224             sub _get_xml {
225 4     4   848 my ($self) = @_;
226 4         15 return $self->{status_raw_content};
227             }
228              
229              
230             sub service_status {
231 2     2 1 930 my ($self, $service) = @_;
232 2         5 my $status_href = {};
233              
234 2         5 $self->_fetch_info;
235              
236 2         3 for my $s (@{$self->{xml_hash}->{monit}->{service}}) {
  2         5  
237 4 100       11 if ($s->{name} eq $service) {
238              
239 2         5 $status_href->{host} = $self->{hostname};
240              
241             $status_href->{'type'} = $s->{'-type'}
242 2 50       6 if exists $s->{'-type'};
243              
244 2         7 for my $thing (qw/
245             children
246             collected_sec
247             collected_usec
248             euid
249             gid
250             group
251             monitor
252             monitormode
253             pid
254             ppid
255             name
256             pendingaction
257             status
258             status_hint
259             uid
260             uptime
261             /) {
262              
263             $status_href->{$thing} = $s->{$thing}
264 32 100       67 if exists $s->{$thing};
265              
266             } # main stuff loop
267              
268             # the 'system' (type 5) service sticks these things in to ->{system}, others are top level
269 2 50 33     10 if (my $sys = $s->{system} || $s) {
270 2         4 for my $thing (qw/ kilobyte kilobytetotal percent percenttotal /) {
271             $status_href->{memory}->{$thing} = $sys->{memory}->{$thing}
272 8 100       19 if exists $sys->{memory}->{$thing};
273             } # memory loop
274              
275 2         4 for my $thing (qw/ kilobyte percent /) {
276             $status_href->{swap}->{$thing} = $sys->{swap}->{$thing}
277 4 50       8 if exists $sys->{swap}->{$thing};
278             } # swap loop
279              
280 2         4 for my $thing (qw/ percent percenttotal /) {
281             $status_href->{cpu}->{$thing} = $sys->{cpu}->{$thing}
282 4 100       9 if exists $sys->{cpu}->{$thing};
283             } # cpu loop
284              
285 2         3 for my $thing (qw/ avg01 avg05 avg15 /) {
286             $status_href->{load}->{$thing} = $sys->{load}->{$thing}
287 6 100       15 if exists $sys->{load}->{$thing};
288             } # load loop
289              
290             }
291             }
292             }
293              
294 2 50       7 croak "Service $service does not exist\n"
295             unless scalar keys %$status_href;
296              
297 2         6 return $status_href
298              
299             }
300              
301              
302             sub command_run {
303 0     0 1   my ($self, $service, $command) = @_;
304              
305             croak "Don't understand this action\n"
306 0 0         unless grep { $command eq $_ } keys %{MONIT_ACTIONS()};
  0            
  0            
307              
308 0 0         if(not defined $service) {
309 0           $self->{is_success} = 0;
310 0           croak "Service not specified\n";
311             }
312              
313             # if services does not exist throw error
314              
315 0           my $url = 'http://'.$self->{hostname}.':'.$self->{port}.'/'.$service;
316              
317 0           my $res = $self->{ua}->post_form($url, { action => $command });
318             croak $res->{status}
319 0 0         unless $res->{success};
320              
321 0           return 1
322             }
323              
324             1; # End of Monit::HTTP
325              
326             __END__