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 output.
3              
4 1     1   2162 use 5.006;
  1         5  
5 1     1   9 use strict;
  1         3  
  1         30  
6 1     1   8 use warnings;
  1         3  
  1         52  
7 1     1   403 use Modern::Perl;
  1         7121  
  1         6  
8 1     1   985 use Parse::RecDescent;
  1         24941  
  1         8  
9 1     1   549 use Data::Dumper;
  1         4958  
  1         77  
10 1     1   359 use JSON;
  1         5487  
  1         5  
11              
12 1     1   137 use Exporter qw{import};
  1         2  
  1         415  
13              
14             our @EXPORT_OK = qw{get_parser get_output_drivers parse_config post_process};
15              
16              
17             sub get_parser {
18 1     1 1 527 return new Parse::RecDescent(q{
19            
20             startrule: config_line(s) { $item[1] }
21             config_line: ip_route(s) { { ip_route => $item{'ip_route(s)'} } } |
22             ifconfig(s) { { ifconfig => $item{'ifconfig(s)'} } } |
23             not_parsed { $item[1] }
24              
25             ip_route: destination nexthop_ip(?) device proto(?) scope(?) source(?) metric(?) {
26             {
27             destination => $item{destination},
28             next_hop => $item{'nexthop_ip(?)'},
29             device => $item{device},
30             proto => $item{proto},
31             scope => $item{'scope(?)'},
32             source => $item{'source(?)'},
33             metric => $item{'metric(?))'}
34             }
35             }
36            
37             destination: ipv4 cidr { { network => $item{ipv4}, cidr => $item{cidr} } } | 'default' { { network => '0.0.0.0', cidr => '0' } }
38             nexthop_ip: 'via' ipv4 { $item{ipv4} }
39             device: 'dev' m{[-\w]+} { $item{__PATTERN1__} }
40             proto: 'proto' m{\w+} { $item{__PATTERN1__} }
41             scope: 'scope' m{\w+} { $item{__PATTERN1__} }
42             source: 'src' ipv4 { $item{ipv4} }
43             metric: 'metric' m{\d+} { $item{__PATTERN1__} }
44              
45             # inet6(?)
46              
47             ifconfig: interface encap hw_addr(?) inet(?) inet6(s?) flag(s) mtu if_metric rx_stats tx_stats rx_bytes tx_bytes {
48             {
49             interface => $item{interface},
50             encapsulation => $item{encap},
51             hw_addr => $item{'hw_addr(?)'},
52             inet => $item{'inet(?)'},
53             inet6 => $item{'inet6(s?)'},
54             flags => $item{'flag(s)'},
55             mtu => $item{mtu},
56             metric => $item{if_metric},
57             rx_stats => $item{rx_stats},
58             tx_stats => $item{tx_stats},
59             rx_bytes => $item{rx_bytes},
60             tx_bytes => $item{tx_bytes},
61             }
62             }
63              
64             interface: m{[-\w]+} { $item{__PATTERN1__} }
65             encap: 'Link encap:' m{Ethernet|Local Loopback} { $item{__PATTERN1__} }
66             hw_addr: 'HWaddr' m{[0-9a-f:]+} { $item{__PATTERN1__} }
67             inet: inet_addr inet_bcast(?) inet_mask {
68             {
69             address => $item{inet_addr},
70             mask => $item{inet_mask},
71             broadcast => $item{'inet_bcast(?)'}
72             }
73             }
74             inet_addr: 'inet addr:' ipv4 { $item{ipv4} }
75             inet_bcast: 'Bcast:' ipv4 { $item{ipv4} }
76             inet_mask: 'Mask:' netmask { $item{netmask} }
77             inet6: inet6_addr inet6_mask inet6_scope {
78             {
79             address => $item{inet6_addr},
80             mask => $item{inet6_mask},
81             scope => $item{inet6_scope}
82             }
83             }
84             inet6_addr: 'inet6 addr:' ipv6 { $item{ipv6} }
85             inet6_mask: '/' m{\d{1,3}} { $item{__PATTERN1__} }
86             inet6_scope: 'Scope:' m{\w+} { $item{__PATTERN1__} }
87              
88             flag: m{UP|BROADCAST|RUNNING|MULTICAST|LOOPBACK} { $item{__PATTERN1__} }
89             mtu: 'MTU:' m{\d+} { $item{__PATTERN1__} }
90             if_metric: 'Metric:' m{\d+} { $item{__PATTERN1__} }
91             rx_stats: 'RX packets:' m{\d+} 'errors:' m{\d+} 'dropped:' m{\d+} 'overruns:' m{\d+} 'frame:' m{\d+} {
92             {
93             packets => $item{__PATTERN1__},
94             errors => $item{__PATTERN2__},
95             dropped => $item{__PATTERN3__},
96             overruns => $item{__PATTERN4__},
97             frame => $item{__PATTERN5__},
98             }
99             }
100             tx_stats: 'TX packets:' m{\d+} 'errors:' m{\d+} 'dropped:' m{\d+} 'overruns:' m{\d+} 'carrier:' m{\d+} 'collisions:' m{\d+} 'txqueuelen:' m{\d+}{
101             {
102             packets => $item{__PATTERN1__},
103             errors => $item{__PATTERN2__},
104             dropped => $item{__PATTERN3__},
105             overruns => $item{__PATTERN4__},
106             carrier => $item{__PATTERN5__},
107             collisions => $item{__PATTERN5__},
108             txqueuelen => $item{__PATTERN5__},
109             }
110             }
111             rx_bytes: 'RX bytes:' m{\d+} m{\(\d{1,}\.\d \w{1,2}\)} { $item{__PATTERN1__} }
112             tx_bytes: 'TX bytes:' m{\d+} m{\(\d{1,}\.\d \w{1,2}\)} { $item{__PATTERN1__} }
113              
114              
115             not_parsed: m{\N+} { { type => $item{__RULE__}, line => $item{__PATTERN1__} } }
116              
117              
118              
119             ipv4: m{\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}} { $item{__PATTERN1__} }
120             netmask: m{\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}} { $item{__PATTERN1__} }
121             ipv6: m{[0-9a-f:]+} { $item{__PATTERN1__} }
122             cidr: '/' m{\d{1,2}} { $item{__PATTERN1__} }
123             });
124             }
125              
126              
127              
128             sub parse_config {
129 0     0 1   my ($parser, $config_contents) = @_;
130              
131 0           my $parse_tree = $parser->startrule($config_contents);
132              
133 0           return $parse_tree;
134             }
135              
136              
137              
138             sub get_output_drivers {
139             return {
140 0     0 1   csv => \&csv_output_driver,
141             json => \&json_output_driver,
142             };
143             }
144              
145              
146             sub post_process {
147 0     0 1   my ($parsed_config) = @_;
148              
149 0           return $parsed_config;
150              
151             }
152              
153              
154              
155             sub csv_output_driver {
156 0     0 1   my ($fh, $filename, $parsed_config) = @_;
157 0           my $csv_type_driver = {
158             };
159              
160 0           say "=" x 16 . "BEGIN FILE $filename" . "=" x 16;
161              
162             TYPE:
163 0           for my $type (keys %{ $parsed_config }) {
  0            
164 0           say "-" x 8 . "BEGIN TYPE $type" . "-" x 8;
165              
166             defined $csv_type_driver->{$type} ?
167 0 0         $csv_type_driver->{$type}->($fh, $parsed_config->{$type}) :
    0          
168             warn "No CSV output driver for $type\n" and next TYPE;
169              
170 0           say "-" x 8 . "END TYPE $type" . "-" x 8;
171             }
172              
173 0           say "-" x 8 . "END FILE $filename" . "-" x 8;
174             }
175              
176             sub _csv_not_config_driver {
177 0     0     my ($fh, $not_config) = @_;
178              
179 0           for my $config_line (@{ $not_config }) {
  0            
180 0           print $fh "$config_line\n";
181             }
182             }
183              
184              
185              
186              
187              
188              
189             sub json_output_driver {
190 0     0 1   my ($fh, $filename, $parsed_config) = @_;
191              
192 0           print encode_json($parsed_config);
193             }
194              
195              
196             1; # End of Device::CheckPoint::ConfigParse
197              
198             __END__