File Coverage

blib/lib/Net/Checkpoint/Management/v1.pm
Criterion Covered Total %
statement 23 177 12.9
branch 0 54 0.0
condition 0 42 0.0
subroutine 8 22 36.3
pod 7 7 100.0
total 38 302 12.5


line stmt bran cond sub pod time code
1             package Net::Checkpoint::Management::v1;
2             $Net::Checkpoint::Management::v1::VERSION = '0.002000';
3             # ABSTRACT: Checkpoint Management API version 1.x client library
4              
5 1     1   242071 use 5.024;
  1         12  
6 1     1   564 use Moo;
  1         7410  
  1         5  
7 1     1   1489 use feature 'signatures';
  1         3  
  1         153  
8 1     1   665 use Types::Standard qw( ArrayRef Str );
  1         112298  
  1         10  
9 1     1   3107 use Carp::Clan qw(^Net::Checkpoint::Management::v1);
  1         1788  
  1         8  
10 1     1   551 use Clone qw( clone );
  1         2450  
  1         83  
11 1     1   537 use Net::Checkpoint::Management::v1::Role::ObjectMethods;
  1         3  
  1         35  
12              
13 1     1   7 no warnings "experimental::signatures";
  1         3  
  1         2161  
14              
15              
16             has 'user' => (
17             isa => Str,
18             is => 'rw',
19             );
20             has 'passwd' => (
21             isa => Str,
22             is => 'rw',
23             );
24              
25              
26             has 'api_versions' => (
27             is => 'lazy',
28             isa => ArrayRef[Str],
29             );
30              
31 0     0     sub _build_api_versions ($self) {
  0            
  0            
32 0           my $res_versions = $self->post('/web_api/v1.1/show-api-versions', {});
33 0           return $res_versions->data->{'supported-versions'};
34             }
35              
36              
37             has 'api_version' => (
38             is => 'rw',
39             isa => Str,
40             );
41              
42             with 'Net::Checkpoint::Management::v1::Role::REST::Client';
43              
44 0     0     sub _error_handler ($self, $data) {
  0            
  0            
  0            
45 0           my $error_message;
46              
47 0 0         if (ref $data eq 'HASH' ) {
48 0 0 0       if (exists $data->{'blocking-errors'}
    0 0        
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
49             && ref $data->{'blocking-errors'} eq 'ARRAY'
50             && exists $data->{'blocking-errors'}->[0]
51             && exists $data->{'blocking-errors'}->[0]->{message}) {
52 0           $error_message = $data->{'blocking-errors'}->[0]->{message};
53             }
54             elsif (exists $data->{errors}
55             && ref $data->{errors} eq 'ARRAY'
56             && exists $data->{errors}->[0]
57             && exists $data->{errors}->[0]->{message}) {
58 0           $error_message = $data->{errors}->[0]->{message};
59             }
60             # when ignore-warnings isn't passed to the API call, a response with only
61             # warnings is also considered an error because its changes aren't saved
62             # when passing ignore-warnings the error handler isn't called because the
63             # http response code is 200
64             elsif (exists $data->{warnings}
65             && ref $data->{warnings} eq 'ARRAY'
66             && exists $data->{warnings}->[0]
67             && exists $data->{warnings}->[0]->{message}) {
68 0           $error_message = $data->{warnings}->[0]->{message};
69             }
70             else {
71 0           $error_message = $data->{message};
72             }
73             }
74             # underlying exception like Could not connect to 'cpmanager.example.org'
75             else {
76 0           $error_message = $data;
77             }
78 0           croak($error_message);
79             }
80              
81 0     0     sub _create ($self, $url, $object_data, $query_params = {}) {
  0            
  0            
  0            
  0            
  0            
82 0           my $params = $self->user_agent->www_form_urlencode( $query_params );
83 0           my $res = $self->post("$url?$params", $object_data);
84 0           my $code = $res->code;
85 0           my $data = $res->data;
86              
87 0 0         $self->_error_handler($data)
88             unless $code == 200;
89 0           return $data;
90             }
91              
92 0     0     sub _list ($self, $url, $list_key, $query_params = {}) {
  0            
  0            
  0            
  0            
  0            
93             # the API only allows 500 objects at a time
94             # work around that by making multiple API calls
95 0           my $offset = 0;
96             my $limit = exists $query_params->{limit}
97             ? $query_params->{limit}
98 0 0         : 500;
99 0           my $more_data_available = 1;
100 0           my $response;
101 0           while ($more_data_available) {
102 0           my $res = $self->post($url, {
103             offset => $offset,
104             limit => $limit,
105             %$query_params,
106             });
107 0           my $code = $res->code;
108 0           my $data = $res->data;
109 0 0         $self->_error_handler($data)
110             unless $code == 200;
111              
112             # use first response for base structure of response
113 0 0         if ($offset == 0) {
114 0           $response = clone($data);
115 0           delete $response->{from};
116 0           delete $response->{to};
117             }
118             else {
119             push $response->{$list_key}->@*, $data->{$list_key}->@*
120 0 0 0       if exists $data->{$list_key} && ref $data->{$list_key} eq 'ARRAY';
121             }
122              
123             # check if more data is available
124 0 0         if ($offset + $limit < $data->{total}) {
125 0           $more_data_available = 1;
126 0           $offset += $limit;
127             }
128             else {
129 0           $more_data_available = 0;
130             }
131             }
132              
133             # return response similar to Checkpoint API
134 0           return $response;
135             }
136              
137 0     0     sub _get ($self, $url, $query_params = {}) {
  0            
  0            
  0            
  0            
138 0           my $res = $self->post($url, $query_params);
139 0           my $code = $res->code;
140 0           my $data = $res->data;
141              
142 0 0         $self->_error_handler($data)
143             unless $code == 200;
144              
145 0           return $data;
146             }
147              
148 0     0     sub _update ($self, $url, $object_data) {
  0            
  0            
  0            
  0            
149 0           my $res = $self->post($url, $object_data);
150 0           my $code = $res->code;
151 0           my $data = $res->data;
152 0 0         $self->_error_handler($data)
153             unless $code == 200;
154              
155 0           return $data;
156             }
157              
158 0     0     sub _delete ($self, $url, $object) {
  0            
  0            
  0            
  0            
159 0           my $res = $self->post($url, $object);
160 0           my $code = $res->code;
161 0           my $data = $res->data;
162 0 0         $self->_error_handler($data)
163             unless $code == 200;
164              
165 0           return 1;
166             }
167              
168             Net::Checkpoint::Management::v1::Role::ObjectMethods->apply([
169             {
170             object => 'packages',
171             singular => 'package',
172             create => 'add-package',
173             list => 'show-packages',
174             get => 'show-package',
175             update => 'set-package',
176             delete => 'delete-package',
177             list_key => 'packages',
178             id_keys => [qw( uid name )],
179             },
180             {
181             object => 'accessrules',
182             singular => 'accessrule',
183             create => 'add-access-rule',
184             list => 'show-access-rulebase',
185             get => 'show-access-rule',
186             update => 'set-access-rule',
187             delete => 'delete-access-rule',
188             list_key => 'rulebase',
189             id_keys => ['uid', 'name', 'rule-number'],
190             },
191             {
192             object => 'networks',
193             singular => 'network',
194             create => 'add-network',
195             list => 'show-networks',
196             get => 'show-network',
197             update => 'set-network',
198             delete => 'delete-network',
199             list_key => 'objects',
200             id_keys => [qw( uid name )],
201             },
202             {
203             object => 'hosts',
204             singular => 'host',
205             create => 'add-host',
206             list => 'show-hosts',
207             get => 'show-host',
208             update => 'set-host',
209             delete => 'delete-host',
210             list_key => 'objects',
211             id_keys => [qw( uid name )],
212             },
213             {
214             object => 'address_ranges',
215             singular => 'address_range',
216             create => 'add-address-range',
217             list => 'show-address-ranges',
218             get => 'show-address-range',
219             update => 'set-address-range',
220             delete => 'delete-address-range',
221             list_key => 'objects',
222             id_keys => [qw( uid name )],
223             },
224             {
225             object => 'dns_domains',
226             singular => 'dns_domain',
227             create => 'add-dns-domain',
228             list => 'show-dns-domains',
229             get => 'show-dns-domain',
230             update => 'set-dns-domain',
231             delete => 'delete-dns-domain',
232             list_key => 'objects',
233             id_keys => [qw( uid name )],
234             },
235             {
236             object => 'groups',
237             singular => 'group',
238             create => 'add-group',
239             list => 'show-groups',
240             get => 'show-group',
241             update => 'set-group',
242             delete => 'delete-group',
243             list_key => 'objects',
244             id_keys => [qw( uid name )],
245             },
246             {
247             object => 'access_roles',
248             singular => 'access_role',
249             create => 'add-access-role',
250             list => 'show-access-roles',
251             get => 'show-access-role',
252             update => 'set-access-role',
253             delete => 'delete-access-role',
254             list_key => 'objects',
255             id_keys => [qw( uid name )],
256             },
257             {
258             object => 'services_tcp',
259             singular => 'service_tcp',
260             create => 'add-service-tcp',
261             list => 'show-services-tcp',
262             get => 'show-service-tcp',
263             update => 'set-service-tcp',
264             delete => 'delete-service-tcp',
265             list_key => 'objects',
266             id_keys => [qw( uid name )],
267             },
268             {
269             object => 'services_udp',
270             singular => 'service_udp',
271             create => 'add-service-udp',
272             list => 'show-services-udp',
273             get => 'show-service-udp',
274             update => 'set-service-udp',
275             delete => 'delete-service-udp',
276             list_key => 'objects',
277             id_keys => [qw( uid name )],
278             },
279             {
280             object => 'services_icmp',
281             singular => 'service_icmp',
282             create => 'add-service-icmp',
283             list => 'show-services-icmp',
284             get => 'show-service-icmp',
285             update => 'set-service-icmp',
286             delete => 'delete-service-icmp',
287             list_key => 'objects',
288             id_keys => [qw( uid name )],
289             },
290             {
291             object => 'services_icmpv6',
292             singular => 'service_icmpv6',
293             create => 'add-service-icmp6',
294             list => 'show-services-icmp6',
295             get => 'show-service-icmp6',
296             update => 'set-service-icmp6',
297             delete => 'delete-service-icmp6',
298             list_key => 'objects',
299             id_keys => [qw( uid name )],
300             },
301             {
302             object => 'services_other',
303             singular => 'service_other',
304             create => 'add-service-other',
305             list => 'show-services-other',
306             get => 'show-service-other',
307             update => 'set-service-other',
308             delete => 'delete-service-other',
309             list_key => 'objects',
310             id_keys => [qw( uid name )],
311             },
312             {
313             object => 'service_groups',
314             singular => 'service_group',
315             create => 'add-service-group',
316             list => 'show-service-groups',
317             get => 'show-service-group',
318             update => 'set-service-group',
319             delete => 'delete-service-group',
320             list_key => 'objects',
321             id_keys => [qw( uid name )],
322             },
323             {
324             object => 'sessions',
325             singular => 'session',
326             list => 'show-sessions',
327             get => 'show-session',
328             update => 'set-session',
329             list_key => 'objects',
330             },
331             {
332             object => 'tasks',
333             singular => 'task',
334             list => 'show-tasks',
335             get => 'show-task',
336             list_key => 'tasks',
337             },
338             ]);
339              
340              
341 0     0 1   sub login($self) {
  0            
  0            
342 0           my $res = $self->post('/web_api/v1/login', {
343             user => $self->user,
344             password => $self->passwd,
345             });
346 0 0         if ($res->code == 200) {
347 0           my $api_version = $res->data->{'api-server-version'};
348 0           $self->api_version($api_version);
349             $self->set_persistent_header('X-chkp-sid',
350 0           $res->data->{sid});
351             }
352             else {
353 0           $self->_error_handler($res->data);
354             }
355             }
356              
357              
358 0     0 1   sub logout($self) {
  0            
  0            
359 0           my $res = $self->post('/web_api/v1/logout', {});
360 0           my $code = $res->code;
361 0           my $data = $res->data;
362 0 0         $self->_error_handler($data)
363             unless $code == 200;
364             }
365              
366              
367 0     0 1   sub publish($self) {
  0            
  0            
368 0           my $res = $self->post('/web_api/v' . $self->api_version . '/publish', {});
369 0           my $code = $res->code;
370 0           my $data = $res->data;
371 0 0         $self->_error_handler($data)
372             unless $code == 200;
373              
374 0           return $data->{'task-id'};
375             }
376              
377              
378 0     0 1   sub discard($self) {
  0            
  0            
379 0           my $res = $self->post('/web_api/v' . $self->api_version . '/discard', {});
380 0           my $code = $res->code;
381 0           my $data = $res->data;
382 0 0         $self->_error_handler($data)
383             unless $code == 200;
384              
385 0           return $data;
386             }
387              
388              
389 0     0 1   sub verify_policy($self, $policyname) {
  0            
  0            
  0            
390 0 0         croak "policy name missing"
391             unless defined $policyname;
392              
393 0           my $res = $self->post('/web_api/v' . $self->api_version .
394             '/verify-policy', {
395             'policy-package' => $policyname,
396             });
397 0           my $code = $res->code;
398 0           my $data = $res->data;
399 0 0         $self->_error_handler($data)
400             unless $code == 200;
401              
402 0           return $data->{'task-id'};
403             }
404              
405              
406 0     0 1   sub install_policy($self, $policyname, $targets, $params={}) {
  0            
  0            
  0            
  0            
  0            
407 0 0         croak "policy name missing"
408             unless defined $policyname;
409 0 0         croak "target(s) missing"
410             unless defined $targets;
411 0 0 0       croak "target(s) must be a single name or uid or a list of names or uids"
412             unless ref $targets eq ''
413             || ref $targets eq 'ARRAY';
414 0 0 0       croak "parameters needs to be a hashref"
415             if defined $params && ref $params ne 'HASH';
416              
417 0           my $res = $self->post('/web_api/v' . $self->api_version .
418             '/install-policy', {
419             $params->%*,
420             'policy-package' => $policyname,
421             targets => $targets,
422             });
423 0           my $code = $res->code;
424 0           my $data = $res->data;
425 0 0         $self->_error_handler($data)
426             unless $code == 200;
427              
428 0           return $data->{'task-id'};
429             }
430              
431              
432 0     0 1   sub wait_for_task($self, $taskid, $callback) {
  0            
  0            
  0            
  0            
433 0 0         croak "task-id missing"
434             unless defined $taskid;
435 0 0 0       croak "callback must be a coderef"
436             if defined $callback && ref $callback ne 'CODE';
437              
438 0           my $task;
439 0   0       while (($task = $self->get_task({'task-id' => $taskid})->{tasks}[0])
440             && $task->{status} eq 'in progress') {
441 0 0         &$callback($task)
442             if defined $callback;
443 0           sleep 1;
444             }
445 0           return $task;
446             }
447              
448             1;
449              
450             __END__
451              
452             =pod
453              
454             =encoding UTF-8
455              
456             =head1 NAME
457              
458             Net::Checkpoint::Management::v1 - Checkpoint Management API version 1.x client library
459              
460             =head1 VERSION
461              
462             version 0.002000
463              
464             =head1 SYNOPSIS
465              
466             use strict;
467             use warnings;
468             use Net::Checkpoint::Management::v1;
469              
470             my $cpmgmt = Net::Checkpoint::Management::v1->new(
471             server => 'https://cpmgmt.example.com',
472             user => 'username',
473             passwd => '$password',
474             clientattrs => { timeout => 30 },
475             );
476              
477             $cpmgmt->login;
478              
479             =head1 DESCRIPTION
480              
481             This module is a client library for the Checkpoint Management API version 1.x.
482             Currently it is developed and tested against version R80.40.
483              
484             =head1 ATTRIBUTES
485              
486             =head2 api_versions
487              
488             Returns a list of all available API versions which gets populated on the first
489             call.
490             Only works on API version 1.1 and higher.
491              
492             =head2 api_version
493              
494             The API version used by all methods. Is automatically set to the highest
495             version available by the L</login> method.
496              
497             =head1 METHODS
498              
499             =head2 login
500              
501             Logs into the Checkpoint Manager API using version 1.
502              
503             =head2 logout
504              
505             Logs out of the Checkpoint Manager API using version 1.
506              
507             =head2 publish
508              
509             Publishes all previously submitted changes.
510             Returns the task id on success.
511              
512             =head2 discard
513              
514             Discards all previously submitted changes.
515             Returns a hashref containing the operation status message and the number of
516             discarded changes.
517              
518             =head2 verify_policy
519              
520             Verifies the policy of the given package.
521              
522             Takes a policy name.
523              
524             Returns the task id on success.
525              
526             =head2 install_policy
527              
528             Installs the policy of the given package onto the given target(s).
529              
530             Takes a policy name, target(s) and an optional hashref of additional
531             parameters.
532             The target(s) can be a single name or uid or a list of names or uids.
533              
534             Returns the task id on success.
535              
536             =head2 wait_for_task
537              
538             Takes a task id and checks its status every second until it isn't
539             'in progress' any more and return the status.
540             Takes an optional callback coderef which is called for every check with the
541             task as argument.
542              
543             =head1 AUTHOR
544              
545             Alexander Hartmaier <abraxxa@cpan.org>
546              
547             =head1 COPYRIGHT AND LICENSE
548              
549             This software is copyright (c) 2022 by Alexander Hartmaier.
550              
551             This is free software; you can redistribute it and/or modify it under
552             the same terms as the Perl 5 programming language system itself.
553              
554             =cut