File Coverage

blib/lib/Device/Network/ConfigParser/CheckPoint/Expert.pm
Criterion Covered Total %
statement 24 45 53.3
branch 0 4 0.0
condition n/a
subroutine 9 15 60.0
pod 6 6 100.0
total 39 70 55.7


line stmt bran cond sub pod time code
1             package Device::Network::ConfigParser::CheckPoint::Expert;
2             # ABSTRACT: Parse expert CheckPoint expert mode output.
3             our $VERSION = '0.005'; # VERSION
4              
5 1     1   1345 use 5.006;
  1         3  
6 1     1   4 use strict;
  1         2  
  1         17  
7 1     1   4 use warnings;
  1         2  
  1         44  
8 1     1   329 use Modern::Perl;
  1         6908  
  1         8  
9 1     1   1109 use Parse::RecDescent;
  1         30776  
  1         11  
10 1     1   639 use Data::Dumper;
  1         5452  
  1         75  
11 1     1   418 use JSON;
  1         8479  
  1         10  
12              
13 1     1   206 use Exporter qw{import};
  1         5  
  1         715  
14              
15             our @EXPORT_OK = qw{get_parser get_output_drivers parse_config post_process};
16              
17             =head1 NAME
18              
19             Device::Network::ConfigParser::CheckPoint::Expert - parse CheckPoint expert mode output.
20              
21             =head1 VERSION
22              
23             version 0.005
24              
25             =head1 SYNOPSIS
26              
27             This module is intended to be used in conjunction with L, however there's nothing stopping it being used on its own.
28              
29             The module provides subroutines to parse & post-process CheckPoint Expoert mode output.
30              
31             =head1 SUBROUTINES
32              
33             =head2 get_parser
34              
35             For more information on the subroutine, see L.
36              
37             Thos module currently recognised the following output:
38              
39             =over 4
40              
41             =item * 'ip route' output
42              
43             =item * 'ifconfig' output
44              
45             =back
46              
47             =cut
48              
49             sub get_parser {
50 1     1 1 757 return new Parse::RecDescent(q{
51            
52             startrule: config_line(s) { $item[1] }
53             config_line: ip_route(s) { { ip_route => $item{'ip_route(s)'} } } |
54             ifconfig(s) { { ifconfig => $item{'ifconfig(s)'} } } |
55             not_parsed { $item[1] }
56              
57             ip_route: destination nexthop_ip(?) device proto(?) scope(?) source(?) metric(?) {
58             {
59             destination => $item{destination},
60             next_hop => $item{'nexthop_ip(?)'},
61             device => $item{device},
62             proto => $item{proto},
63             scope => $item{'scope(?)'},
64             source => $item{'source(?)'},
65             metric => $item{'metric(?))'}
66             }
67             }
68            
69             destination: ipv4 cidr { { network => $item{ipv4}, cidr => $item{cidr} } } | 'default' { { network => '0.0.0.0', cidr => '0' } }
70             nexthop_ip: 'via' ipv4 { $item{ipv4} }
71             device: 'dev' m{[-\w]+} { $item{__PATTERN1__} }
72             proto: 'proto' m{\w+} { $item{__PATTERN1__} }
73             scope: 'scope' m{\w+} { $item{__PATTERN1__} }
74             source: 'src' ipv4 { $item{ipv4} }
75             metric: 'metric' m{\d+} { $item{__PATTERN1__} }
76              
77             # inet6(?)
78              
79             ifconfig: interface encap hw_addr(?) inet(?) inet6(s?) flag(s) mtu if_metric rx_stats tx_stats rx_bytes tx_bytes {
80             {
81             interface => $item{interface},
82             encapsulation => $item{encap},
83             hw_addr => $item{'hw_addr(?)'},
84             inet => $item{'inet(?)'},
85             inet6 => $item{'inet6(s?)'},
86             flags => $item{'flag(s)'},
87             mtu => $item{mtu},
88             metric => $item{if_metric},
89             rx_stats => $item{rx_stats},
90             tx_stats => $item{tx_stats},
91             rx_bytes => $item{rx_bytes},
92             tx_bytes => $item{tx_bytes},
93             }
94             }
95              
96             interface: m{[-\w]+} { $item{__PATTERN1__} }
97             encap: 'Link encap:' m{Ethernet|Local Loopback} { $item{__PATTERN1__} }
98             hw_addr: 'HWaddr' m{[0-9a-f:]+} { $item{__PATTERN1__} }
99             inet: inet_addr inet_bcast(?) inet_mask {
100             {
101             address => $item{inet_addr},
102             mask => $item{inet_mask},
103             broadcast => $item{'inet_bcast(?)'}
104             }
105             }
106             inet_addr: 'inet addr:' ipv4 { $item{ipv4} }
107             inet_bcast: 'Bcast:' ipv4 { $item{ipv4} }
108             inet_mask: 'Mask:' netmask { $item{netmask} }
109             inet6: inet6_addr inet6_mask inet6_scope {
110             {
111             address => $item{inet6_addr},
112             mask => $item{inet6_mask},
113             scope => $item{inet6_scope}
114             }
115             }
116             inet6_addr: 'inet6 addr:' ipv6 { $item{ipv6} }
117             inet6_mask: '/' m{\d{1,3}} { $item{__PATTERN1__} }
118             inet6_scope: 'Scope:' m{\w+} { $item{__PATTERN1__} }
119              
120             flag: m{UP|BROADCAST|RUNNING|MULTICAST|LOOPBACK} { $item{__PATTERN1__} }
121             mtu: 'MTU:' m{\d+} { $item{__PATTERN1__} }
122             if_metric: 'Metric:' m{\d+} { $item{__PATTERN1__} }
123             rx_stats: 'RX packets:' m{\d+} 'errors:' m{\d+} 'dropped:' m{\d+} 'overruns:' m{\d+} 'frame:' m{\d+} {
124             {
125             packets => $item{__PATTERN1__},
126             errors => $item{__PATTERN2__},
127             dropped => $item{__PATTERN3__},
128             overruns => $item{__PATTERN4__},
129             frame => $item{__PATTERN5__},
130             }
131             }
132             tx_stats: 'TX packets:' m{\d+} 'errors:' m{\d+} 'dropped:' m{\d+} 'overruns:' m{\d+} 'carrier:' m{\d+} 'collisions:' m{\d+} 'txqueuelen:' m{\d+}{
133             {
134             packets => $item{__PATTERN1__},
135             errors => $item{__PATTERN2__},
136             dropped => $item{__PATTERN3__},
137             overruns => $item{__PATTERN4__},
138             carrier => $item{__PATTERN5__},
139             collisions => $item{__PATTERN5__},
140             txqueuelen => $item{__PATTERN5__},
141             }
142             }
143             rx_bytes: 'RX bytes:' m{\d+} m{\(\d{1,}\.\d \w{1,2}\)} { $item{__PATTERN1__} }
144             tx_bytes: 'TX bytes:' m{\d+} m{\(\d{1,}\.\d \w{1,2}\)} { $item{__PATTERN1__} }
145              
146              
147             not_parsed: m{\N+} { { type => $item{__RULE__}, line => $item{__PATTERN1__} } }
148              
149              
150              
151             ipv4: m{\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}} { $item{__PATTERN1__} }
152             netmask: m{\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}} { $item{__PATTERN1__} }
153             ipv6: m{[0-9a-f:]+} { $item{__PATTERN1__} }
154             cidr: '/' m{\d{1,2}} { $item{__PATTERN1__} }
155             });
156             }
157              
158              
159             =head2 parse_config
160              
161             For more information on the subroutine, see L.
162              
163             =cut
164              
165             sub parse_config {
166 0     0 1   my ($parser, $config_contents) = @_;
167              
168 0           my $parse_tree = $parser->startrule($config_contents);
169              
170 0           return $parse_tree;
171             }
172              
173              
174              
175             =head2 post_process
176              
177             For more information on the subroutine, see L.
178              
179             This module does not post-process the data structure.
180              
181             =cut
182              
183             sub post_process {
184 0     0 1   my ($parsed_config) = @_;
185              
186 0           return $parsed_config;
187              
188             }
189              
190             =head2 get_output_drivers
191              
192             For more information on the subroutine, see L.
193              
194             This module supports the following output drivers:
195              
196             =over 4
197              
198             =item * csv - writes the parsed configuration out in CSV format.
199              
200             =item * json - writes the parsed configuration out as JSON.
201              
202             =back
203              
204             =cut
205              
206             sub get_output_drivers {
207             return {
208 0     0 1   csv => \&csv_output_driver,
209             json => \&json_output_driver,
210             };
211             }
212              
213              
214             =head2 csv_output_driver
215              
216             =cut
217              
218             sub csv_output_driver {
219 0     0 1   my ($fh, $filename, $parsed_config) = @_;
220 0           my $csv_type_driver = {
221             };
222              
223 0           say "=" x 16 . "BEGIN FILE $filename" . "=" x 16;
224              
225             TYPE:
226 0           for my $type (keys %{ $parsed_config }) {
  0            
227 0           say "-" x 8 . "BEGIN TYPE $type" . "-" x 8;
228              
229             defined $csv_type_driver->{$type} ?
230 0 0         $csv_type_driver->{$type}->($fh, $parsed_config->{$type}) :
    0          
231             warn "No CSV output driver for $type\n" and next TYPE;
232              
233 0           say "-" x 8 . "END TYPE $type" . "-" x 8;
234             }
235              
236 0           say "-" x 8 . "END FILE $filename" . "-" x 8;
237             }
238              
239             sub _csv_not_config_driver {
240 0     0     my ($fh, $not_config) = @_;
241              
242 0           for my $config_line (@{ $not_config }) {
  0            
243 0           print $fh "$config_line\n";
244             }
245             }
246              
247              
248              
249              
250              
251             =head2 json_output_driver
252              
253             =cut
254              
255             sub json_output_driver {
256 0     0 1   my ($fh, $filename, $parsed_config) = @_;
257              
258 0           print encode_json($parsed_config);
259             }
260              
261             =head1 AUTHOR
262              
263             Greg Foletta, C<< >>
264              
265             =head1 BUGS
266              
267             Please report any bugs or feature requests to C, or through
268             the web interface at L. I will be notified, and then you'll
269             automatically be notified of progress on your bug as I make changes.
270              
271              
272              
273              
274             =head1 SUPPORT
275              
276             You can find documentation for this module with the perldoc command.
277              
278             perldoc Device::CheckPoint::ConfigParse
279              
280              
281             You can also look for information at:
282              
283             =over 4
284              
285             =item * RT: CPAN's request tracker (report bugs here)
286              
287             L
288              
289             =item * AnnoCPAN: Annotated CPAN documentation
290              
291             L
292              
293             =item * CPAN Ratings
294              
295             L
296              
297             =item * Search CPAN
298              
299             L
300              
301             =back
302              
303              
304             =head1 ACKNOWLEDGEMENTS
305              
306              
307             =head1 LICENSE AND COPYRIGHT
308              
309             Copyright 2017 Greg Foletta.
310              
311             This program is free software; you can redistribute it and/or modify it
312             under the terms of the the Artistic License (2.0). You may obtain a
313             copy of the full license at:
314              
315             L
316              
317             Any use, modification, and distribution of the Standard or Modified
318             Versions is governed by this Artistic License. By using, modifying or
319             distributing the Package, you accept this license. Do not use, modify,
320             or distribute the Package, if you do not accept this license.
321              
322             If your Modified Version has been derived from a Modified Version made
323             by someone other than you, you are nevertheless required to ensure that
324             your Modified Version complies with the requirements of this license.
325              
326             This license does not grant you the right to use any trademark, service
327             mark, tradename, or logo of the Copyright Holder.
328              
329             This license includes the non-exclusive, worldwide, free-of-charge
330             patent license to make, have made, use, offer to sell, sell, import and
331             otherwise transfer the Package with respect to any patent claims
332             licensable by the Copyright Holder that are necessarily infringed by the
333             Package. If you institute patent litigation (including a cross-claim or
334             counterclaim) against any party alleging that the Package constitutes
335             direct or contributory patent infringement, then this Artistic License
336             to you shall terminate on the date that such litigation is filed.
337              
338             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
339             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
340             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
341             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
342             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
343             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
344             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
345             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
346              
347              
348             =cut
349              
350             1; # End of Device::CheckPoint::ConfigParse