File Coverage

blib/lib/Monit/HTTP.pm
Criterion Covered Total %
statement 98 122 80.3
branch 19 34 55.8
condition 12 32 37.5
subroutine 17 20 85.0
pod 8 8 100.0
total 154 216 71.3


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