File Coverage

blib/lib/Mojo/Zabbix.pm
Criterion Covered Total %
statement 24 110 21.8
branch 0 48 0.0
condition 0 15 0.0
subroutine 8 25 32.0
pod 0 15 0.0
total 32 213 15.0


line stmt bran cond sub pod time code
1             package Mojo::Zabbix;
2              
3 1     1   14243 use strict;
  1         3  
  1         24  
4 1     1   4 use warnings;
  1         2  
  1         22  
5              
6 1     1   442 use Mojo::UserAgent;
  1         282253  
  1         8  
7 1     1   39 use Scalar::Util qw(reftype refaddr);
  1         2  
  1         69  
8 1     1   6 use Carp;
  1         2  
  1         47  
9 1     1   5 use Time::HiRes qw(gettimeofday tv_interval);
  1         3  
  1         8  
10 1     1   120 use POSIX qw(strftime);
  1         2  
  1         7  
11              
12             =encoding utf8
13              
14             =head1 Mojo::Zabbix - Mojo::Zabbix is a simple perl wrapper of Zabbix API.
15              
16             Mojo::Zabix - 是对zabbix api函数的简单打包,以便更易于用perl脚本进行
17             访问操作zabbix。目前仅支持认证和请求方法,可以用其进行create/get
18             /update/delete/exists方法调用,见例子。本模块基于Mojo::useragent,结果
19             可以用Mojo:DOM进行处理和内容提取。
20            
21             =head1 VERSION
22            
23             Version 0.10
24              
25             merge Mojo-Zabbix—APP to this repos.
26            
27             =cut
28              
29             our $VERSION = '0.10';
30              
31             =head1 SYNOPSIS
32              
33             use Mojo::Zabbix;
34            
35             my $z = Net::Zabbix->new(
36             url => "https://server/zabbix/",
37             username => 'user',
38             password => 'pass',
39             debug => 1,
40             trace => 0,
41             );
42            
43             my $r = $z->get("host", {
44             filter => undef,
45             search => {
46             host => "test",
47             },
48             }
49             );
50            
51             =cut
52              
53             # useful defaults Zabbix Constant list:
54              
55             use constant {
56 1         1739 Z_AGENT_PORT => 10050,
57             Z_SERVER_PORT => 10051,
58             Z_SNMP_PORT => 161,
59              
60             # zabbix api constants definitions
61              
62             OUTPUT_EXTEND => 'extend',
63             OUTPUT_REFER => 'refer',
64             OUTPUT_SHORTEN => 'shorten',
65             HOST_INTERFACE_SECONDARY => 0,
66             HOST_INTERFACE_PRIMARY => 1,
67             HOST_INTERFACE_TYPE_UNKNOWN => 0,
68             HOST_INTERFACE_TYPE_AGENT => 1,
69             HOST_INTERFACE_TYPE_SNMP => 2,
70             HOST_INTERFACE_TYPE_IPMI => 3,
71             HOST_INTERFACE_TYPE_JMX => 4,
72             HOST_USE_DNS => 0,
73             HOST_USE_IP => 1,
74             HOST_STATUS_ON => 0,
75             HOST_STATUS_OFF => 1,
76             ITEM_TYPE_AGENT => 0,
77             ITEM_TYPE_SNMP1 => 1,
78             ITEM_TYPE_TRAPPER => 2,
79             ITEM_TYPE_SIMPLE => 3,
80             ITEM_TYPE_SNMP2 => 4,
81             ITEM_TYPE_INTERN => 5,
82             ITEM_TYPE_SNMP3 => 6,
83             ITEM_TYPE_AAGENT => 7,
84              
85             # zabbix agent (active)
86              
87             ITEM_TYPE_AGGR => 8,
88             ITEM_TYPE_HTTP => 9,
89             ITEM_TYPE_EXTERN => 10,
90             ITEM_TYPE_DBMON => 11,
91             ITEM_TYPE_IPMI => 12,
92             ITEM_TYPE_SSH => 13,
93             ITEM_TYPE_TELNET => 14,
94             ITEM_TYPE_CALC => 15,
95             ITEM_TYPE_JMX => 16,
96             ITEM_TYPE_SNMPT => 17,
97             ITEM_STATUS_ACTIVE => 0,
98             ITEM_STATUS_DISABLED => 1,
99             ITEM_STATUS_NOT_SUP => 3,
100             ITEM_VALUE_FLOAT => 0,
101             ITEM_VALUE_CHAR => 1,
102             ITEM_VALUE_LOG => 2,
103             ITEM_VALUE_UINT => 3,
104             ITEM_VALUE_TEXT => 4,
105             ITEM_DATA_DEC => 0,
106             ITEM_DATA_OCT => 1,
107             ITEM_DATA_HEX => 2,
108             ITEM_DATA_BIN => 3, # same as BOOL-ean
109             ITEM_DATA_BOOL => 3,
110             ITEM_DELTA_ASIS => 0,
111             ITEM_DELTA_PERSEC => 1,
112             ITEM_DELTA_CHANGE => 2,
113             ITEM_SSH_AUTH_PASSWORD => 0,
114             ITEM_SSH_AUTH_PUBKEY => 1,
115             ITEM_FLAG_PLAIN => 0,
116             ITEM_FLAG_DISCOVERED => 4,
117             ITEM_SNMP_PRIV_NANP => 0,
118             ITEM_SNMP_PRIV_ANP => 1,
119             ITEM_SNMP_PRIV_AP => 2,
120             TRIGGER_STATUS_ACTIVE => 0,
121             TRIGGER_STATUS_DISABLED => 1,
122             TRIGGER_VALUE_OK => 2,
123             TRIGGER_VALUE_PROBLEM => 3,
124             TRIGGER_VALUE_ON => 4,
125             TRIGGER_SEVERITY_UNKN => 0,
126             TRIGGER_SEVERITY_INFO => 1,
127             TRIGGER_SEVERITY_WARN => 2,
128             TRIGGER_SEVERITY_AVRG => 3,
129             TRIGGER_SEVERITY_HIGH => 4,
130             TRIGGER_SEVERITY_DISA => 5,
131             TRIGGER_TYPE_NORMAL => 0,
132             TRIGGER_TYPE_MULTI => 1,
133             TRIGGER_FLAG_GOOD => 0,
134             TRIGGER_FLAG_UNCERTAIN => 1,
135             TRIGGER_STATUS_ICMPPING_FAIL => 0,
136             TRIGGER_STATUS_ICMPPING_SUCCESS => 1,
137              
138             # http://www.zabbix.com/documentation/2.0/manual/appendix/api/user/definitions
139             USER_TYPE_USER => 1,
140             USER_TYPE_ADMIN => 2,
141             USER_TYPE_SUPERADMIN => 3,
142             USER_TYPE_ROOT => 3, # same as Super Admin
143             USER_THEME_1 => 'originalblue',
144             USER_THEME_2 => 'darkblue',
145             USER_THEME_3 => 'darkorange',
146              
147             # 0 seconds means disabled
148             USER_AUTOLOGIN_DISABLE => 0,
149              
150             # http://www.zabbix.com/documentation/2.0/manual/appendix/api/usergroup/definitions
151             GROUP_ACCESS_DEFAULT => 0,
152             GROUP_ACCESS_INTERNAL => 1,
153             GROUP_ACCESS_DISABLED => 2,
154             GROUP_STATUS_ENABLED => 0,
155             GROUP_STATUS_DISABLED => 1,
156             GROUP_DEBUG_ENABLED => 1,
157             GROUP_DEBUG_DISABLED => 0,
158 1     1   169 };
  1         3  
159              
160             sub new {
161 0     0 0   my $class = shift;
162 0           my $required = 1;
163 0           my $args = {
164             url => \$required,
165             trace => 0,
166             debug => 0,
167             username => \$required,
168             password => \$required,
169             @_,
170             };
171              
172 0           for my $k ( keys %$args ) {
173 0 0 0       if ( ref $args->{$k}
174             && refaddr( $args->{$k} ) == refaddr( \$required ) )
175             {
176 0           die "Missing value for $k";
177             }
178             }
179              
180 0           $args->{url} =~ s,/+$,,g;
181              
182             my $self = bless {
183             UserAgent => undef,
184             Request => undef,
185             Count => 1,
186             Auth => undef,
187             API_URL => $args->{url},
188             Output => OUTPUT_EXTEND,
189             Debug => $args->{debug} ? 1 : 0,
190             Trace => $args->{trace} ? 1 : 0,
191             User => $args->{username},
192             Password => $args->{password},
193 0 0         _call_start => 0,
    0          
194             }, $class;
195              
196             # init json object
197 0           $self->_json;
198              
199             # init useragent
200 0           $self->ua;
201              
202             # authenticate
203 0           $self->auth;
204 0           return $self;
205             }
206              
207             sub output {
208 0     0 0   my $self = shift;
209              
210 0 0         $self->{Output} = $_[0]
211             if (@_);
212              
213 0           return $self->{Output};
214             }
215              
216             sub ua {
217 0     0 0   my $self = shift;
218              
219 0 0         unless ( $self->{UserAgent} ) {
220              
221 0           $self->{UserAgent} = Mojo::UserAgent->new;
222 0           $self->{UserAgent}->transactor->name("Mojo::Zabbix");
223 0           $self->{UserAgent}->inactivity_timeout(10);
224             }
225              
226 0           return $self->{UserAgent};
227             }
228              
229             sub _json {
230 0     0     my $self = shift;
231              
232 0 0         unless ( defined $self->{JSON} ) {
233 0           $self->{JSON} = JSON::PP->new;
234             $self->{JSON}->ascii->pretty->allow_nonref->allow_blessed
235 0           ->allow_bignum;
236             }
237 0           return $self->{JSON};
238             }
239              
240             sub trace {
241 0     0 0   my $self = shift;
242              
243 0 0         $self->{Trace} = $_[0]
244             if (@_);
245              
246 0           return $self->{Trace};
247             }
248              
249             sub debug {
250 0     0 0   my $self = shift;
251              
252 0 0         $self->{Debug} = $_[0]
253             if (@_);
254              
255 0           return $self->{Debug};
256             }
257              
258             sub auth {
259 0     0 0   my $self = shift;
260              
261 0 0         if ( not defined $self->{Auth} ) {
    0          
262 0           $self->{Auth} = '';
263             my $res = $self->http_request(
264             'user', 'login',
265             {
266             user => $self->{User},
267             password => $self->{Password},
268             }
269 0           );
270              
271             #confess $res->{error}->{data}
272             warn "$res->{error}->{data}\nError Code: $res->{error}->{code}
273             \nResponse: $res->{error}->{message}"
274 0 0         if defined $res->{error};
275              
276             #print "$res->{error}";
277 0           $self->{Password} = '***';
278 0           $self->{Auth} = $res->{result};
279             }
280             elsif ( $self->{Auth} eq '' ) {
281 0           return (); # empty for first auth call
282             }
283              
284 0 0         return $self->{Auth} unless defined wantarray;
285 0           return ( auth => $self->{Auth} );
286             }
287              
288             sub next_id {
289 0     0 0   return ++shift->{'Count'};
290             }
291              
292             sub int_debug {
293 0     0 0   my ( $self, $data ) = @_;
294 0           my $tempass;
295 0 0 0       if ( defined $data->{'params'}
      0        
296             and ref( $data->{'params'} ) eq 'HASH'
297             and exists $data->{'params'}->{'password'} )
298             {
299 0           $tempass = $data->{'params'}->{'password'};
300 0           $data->{'params'}->{'password'} = '******';
301             }
302 0           my $json = $self->{JSON}->encode($data);
303              
304             $self->_dbgmsg( "TX: " . $json )
305 0 0         if $self->{Debug};
306             $data->{'params'}->{'password'} = $tempass
307             if ( ref( $data->{'params'} ) eq 'HASH'
308 0 0 0       and exists $data->{'params'}->{'password'} );
309              
310             }
311              
312             sub out_debug {
313 0     0 0   my ( $self, $data ) = @_;
314 0           my $json = $self->{JSON}->encode($data);
315             $self->_dbgmsg( "RX: " . $json )
316 0 0         if $self->{Debug};
317              
318             }
319              
320             sub get {
321 0     0 0   my ( $self, $object, $params ) = @_;
322 0           return $self->http_request( $object, "get", $params );
323             }
324              
325             sub update {
326 0     0 0   my ( $self, $object, $params ) = @_;
327 0           return $self->http_request( $object, "update", $params );
328             }
329              
330             sub delete {
331 0     0 0   my ( $self, $object, $params ) = @_;
332 0           return $self->http_request( $object, "delete", $params );
333             }
334              
335             sub create {
336 0     0 0   my ( $self, $object, $params ) = @_;
337 0           return $self->http_request( $object, "create", $params );
338             }
339              
340             sub exists {
341 0     0 0   my ( $self, $object, $params ) = @_;
342 0           return $self->http_request( $object, "exists", $params );
343             }
344              
345             sub http_request {
346 0     0 0   my ( $self, $object, $op, $params ) = @_;
347              
348 0 0         if ( $self->{Trace} ) {
349 0           $self->{_call_start} = [gettimeofday];
350 0           $self->_dbgmsg("Starting method $object.$op");
351             }
352              
353 0 0         if ($params) {
354             $params->{output} = $self->{Output}
355 0 0 0       if ( reftype($params) eq 'HASH' and not defined $params->{output} );
356             }
357             else {
358 0           $params = [];
359             }
360 0           my $zrurl = "$self->{API_URL}/api_jsonrpc.php";
361 0           my $myjson = {
362             jsonrpc => "2.0",
363             method => "$object.$op",
364             params => $params,
365             id => $self->next_id,
366             ( $self->auth ),
367             };
368 0 0         $self->int_debug($myjson) if $self->{Debug};
369              
370 0           my $res = $self->ua->post( $zrurl, json => $myjson );
371              
372 0 0         unless ( $res->success ) {
373 0           my $err = $res->error;
374 0 0         warn "$err->{code} response: $err->{message}" if $err->{code};
375 0           warn "Connection error: $err->{message}";
376              
377             }
378              
379 0 0         if ( $self->{Trace} ) {
380 0           $self->_dbgmsg("Finished method $object.$op");
381             $self->_dbgmsg( "Spent "
382             . tv_interval( $self->{_call_start} )
383 0           . "s on $object.$op" );
384             }
385 0 0         $self->out_debug( $res->res->json ) if $self->{Debug};
386 0           return $res->res->json;
387             }
388              
389             sub _dbgmsg {
390 0     0     my $self = shift;
391             warn strftime( '[%F %T]', localtime ) . ' '
392             . __PACKAGE__ . ' @ #'
393 0           . $self->{Count} . ' '
394             . join( ', ', @_ ) . "\n";
395             }
396              
397             =head1 AUTHOR
398            
399             orange, C<< >>
400            
401             =head1 BUGS
402            
403             Please report any bugs or feature requests to C, or through
404             the web interface at L. I will be notified, and then you'll
405             automatically be notified of progress on your bug as I make changes.
406            
407             =head1 SUPPORT
408            
409             You can find documentation for this module with the perldoc command.
410            
411             perldoc Mojo-Zabbix
412            
413            
414             You can also look for information at:
415            
416             =over 4
417            
418             =item * RT: CPAN's request tracker (report bugs here)
419            
420             L
421            
422             =item * AnnoCPAN: Annotated CPAN documentation
423            
424             L
425            
426             =item * CPAN Ratings
427            
428             L
429            
430             =item * Search CPAN
431            
432             L
433            
434             =back
435            
436             =head1 Git repo
437            
438             L
439             L
440             =head1 ACKNOWLEDGEMENTS
441            
442            
443             =head1 LICENSE AND COPYRIGHT
444            
445             Copyright 2016 orange.
446            
447             This is free software; you can redistribute it and/or modify
448             it under the same terms as the Perl 5 programming language system itself.
449              
450             =cut
451              
452             1;