line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mnet; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# version number used by Makefile.PL |
4
|
|
|
|
|
|
|
# these should be set to "dev", expect when creating a new release |
5
|
|
|
|
|
|
|
# refer to developer build notes in Makefile.PL for more info |
6
|
|
|
|
|
|
|
our $VERSION = "5.23-TRIAL03"; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 NAME |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
Mnet - Testable network automation and reporting |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 SYNOPSIS |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# sample script to report Loopback0 ip on cisco devices |
15
|
|
|
|
|
|
|
# |
16
|
|
|
|
|
|
|
# demonstrates typical use of all major Mnet modules |
17
|
|
|
|
|
|
|
# |
18
|
|
|
|
|
|
|
# --help to list all options, also --help |
19
|
|
|
|
|
|
|
# --device to connect to device with logging |
20
|
|
|
|
|
|
|
# --username and --password should be set if necessary |
21
|
|
|
|
|
|
|
# --debug to generate extra detailed logging outputs |
22
|
|
|
|
|
|
|
# --batch to process multiple --device lines |
23
|
|
|
|
|
|
|
# --report csv: to create an output csv file |
24
|
|
|
|
|
|
|
# --record to create replayable test file |
25
|
|
|
|
|
|
|
# --test --replay for regression test output |
26
|
|
|
|
|
|
|
# |
27
|
|
|
|
|
|
|
# refer to various Mnet modules' perldoc for more info |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# load modules |
30
|
|
|
|
|
|
|
use warnings; |
31
|
|
|
|
|
|
|
use strict; |
32
|
|
|
|
|
|
|
use Mnet::Batch; |
33
|
|
|
|
|
|
|
use Mnet::Expect::Cli::Ios; |
34
|
|
|
|
|
|
|
use Mnet::Log qw(DEBUG INFO WARN FATAL); |
35
|
|
|
|
|
|
|
use Mnet::Opts::Cli; |
36
|
|
|
|
|
|
|
use Mnet::Report::Table; |
37
|
|
|
|
|
|
|
use Mnet::Stanza; |
38
|
|
|
|
|
|
|
use Mnet::Test; |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# define --device, --username, --password, and --report cli options |
41
|
|
|
|
|
|
|
# record, redact, default, and help option attributes are shown |
42
|
|
|
|
|
|
|
Mnet::Opts::Cli::define({ getopt => "device=s", record => 1 }); |
43
|
|
|
|
|
|
|
Mnet::Opts::Cli::define({ getopt => "username=s" }); |
44
|
|
|
|
|
|
|
Mnet::Opts::Cli::define({ getopt => "password=s", redact => 1 }); |
45
|
|
|
|
|
|
|
Mnet::Opts::Cli::define({ getopt => "report=s", default => undef, |
46
|
|
|
|
|
|
|
help_tip => "specify report output, csv, json, sql, etc", |
47
|
|
|
|
|
|
|
help_text => "perldoc Mnet::Report::Table for more info", |
48
|
|
|
|
|
|
|
}); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# create object to access command line options and Mnet env variable |
51
|
|
|
|
|
|
|
# export Mnet="--password ''" env var from secure file |
52
|
|
|
|
|
|
|
my $cli = Mnet::Opts::Cli->new("Mnet"); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# define output --report table, will include first of any errors |
55
|
|
|
|
|
|
|
# use --report cli opt to output data as csv, json, or sql, etc |
56
|
|
|
|
|
|
|
my $report = Mnet::Report::Table->new({ |
57
|
|
|
|
|
|
|
columns => [ |
58
|
|
|
|
|
|
|
device => "string", |
59
|
|
|
|
|
|
|
error => "error", |
60
|
|
|
|
|
|
|
ip => "string", |
61
|
|
|
|
|
|
|
], |
62
|
|
|
|
|
|
|
output => $cli->report, |
63
|
|
|
|
|
|
|
}); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# fork children if in --batch mode, cli opts set for current child |
66
|
|
|
|
|
|
|
# process one device or ten thousand devices with the same script |
67
|
|
|
|
|
|
|
# exit --batch parent process here when finished forking children |
68
|
|
|
|
|
|
|
$cli = Mnet::Batch::fork($cli); |
69
|
|
|
|
|
|
|
exit if not $cli; |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# output report row for device error if script dies before finishing |
72
|
|
|
|
|
|
|
$report->row_on_error({ device => $cli->device }); |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# call logging function, also create log object for current --device |
75
|
|
|
|
|
|
|
FATAL("missing --device") if not $cli->device; |
76
|
|
|
|
|
|
|
my $log = Mnet::Log->new({ log_id => $cli->device }); |
77
|
|
|
|
|
|
|
$log->info("processing device"); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# uncomment the push commands below to skip ssh host key checks |
80
|
|
|
|
|
|
|
# ideally host keys are already accepted, perhaps via manual ssh |
81
|
|
|
|
|
|
|
my @ssh = qw(ssh); |
82
|
|
|
|
|
|
|
#push @ssh, qw(-o StrictHostKeyChecking=no); |
83
|
|
|
|
|
|
|
#push @ssh, qw(-o UserKnownHostsFile=/dev/null); |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# create an expect ssh session to current --device |
86
|
|
|
|
|
|
|
# log ssh login/auth prompts as info, instead of default debug |
87
|
|
|
|
|
|
|
# password_in set to prompt for password if --password opt not set |
88
|
|
|
|
|
|
|
# for non-ios devices refer to perldoc Mnet::Expect::Cli |
89
|
|
|
|
|
|
|
my $ssh = Mnet::Expect::Cli::Ios->new({ |
90
|
|
|
|
|
|
|
spawn => [ @ssh, "$cli->{username}\@$cli->{device}" ], |
91
|
|
|
|
|
|
|
log_id => $cli->{device}, |
92
|
|
|
|
|
|
|
log_login => "info", |
93
|
|
|
|
|
|
|
password => $cli->password, |
94
|
|
|
|
|
|
|
password_in => 1, |
95
|
|
|
|
|
|
|
}); |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
# retrieve ios config using ssh command, warn otherwise |
98
|
|
|
|
|
|
|
my $config = $ssh->command("show running-config"); |
99
|
|
|
|
|
|
|
WARN("unable to read config") if not $config; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# parse interface loopack0 stanza from device config |
102
|
|
|
|
|
|
|
# returns int loop0 line and lines indented under int loop0 |
103
|
|
|
|
|
|
|
# see perldoc Mnet::Stanza for more ios config templating info |
104
|
|
|
|
|
|
|
my $loop = Mnet::Stanza::parse($config, qr/^interface Loopback0$/); |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
# parse primary ip address from loopback config stanza |
107
|
|
|
|
|
|
|
my $ip = undef; |
108
|
|
|
|
|
|
|
$ip = $1 if $loop and $loop =~ /^ ip address (\S+) \S+$/m; |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# report on parsed loopback0 interface ip addres |
111
|
|
|
|
|
|
|
$report->row({ device => $cli->device, ip => $ip }); |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# finished |
114
|
|
|
|
|
|
|
exit; |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=head1 DESCRIPTION |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
The L modules are for perl programmers who want to create testable |
119
|
|
|
|
|
|
|
network automation and/or reporting scripts as simply as possible. |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
The main features are: |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=over |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=item * |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
L module can record and replay L script options, connected |
128
|
|
|
|
|
|
|
expect sessions, and compare outputs, speeding development and allowing for |
129
|
|
|
|
|
|
|
integration and regression testing of complex automation scripts. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=item * |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
L and L modules for reliable |
134
|
|
|
|
|
|
|
automation of cisco ios and other command line sessions, including |
135
|
|
|
|
|
|
|
authentication and command prompt handling. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=item * |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
L module for templated config parsing and generation on cisco ios |
140
|
|
|
|
|
|
|
devices and other similar indented stanza text data. |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=item * |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
L can run automation scripts in batch mode to concurrently process |
145
|
|
|
|
|
|
|
a list of devices, using command line arguments and a device list file. |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=item * |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
L can facilitate easy log, debug, alert and error output from |
150
|
|
|
|
|
|
|
automation scripts, outputs can be redirected to per-device files. |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=item * |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
L module for config settings via command line, environment |
155
|
|
|
|
|
|
|
variable, and/or batch scripts, with help, tips, and password redaction. |
156
|
|
|
|
|
|
|
device list files. |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=item * |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
L module for aggregating report data from scripts, |
161
|
|
|
|
|
|
|
supporting output in formats such as csv, json, and sql. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=back |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
Most of the L sub-modules can be used independently of each other, |
166
|
|
|
|
|
|
|
unless otherwise noted. |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
Refer to the individual modules listed in the SEE ALSO section below |
169
|
|
|
|
|
|
|
for more detail. |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=head1 INSTALLATION |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
The L perl modules should work in just about any unix perl environment. |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
The latest release can be installed from CPAN |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
cpan install Mnet |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Or download and install from L |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
tar -xzf Mnet-X.y.tar.gz |
182
|
|
|
|
|
|
|
cd Mnet-X.y |
183
|
|
|
|
|
|
|
perl Makefile.PL # INSTALL_BASE=/specify/path |
184
|
|
|
|
|
|
|
make test |
185
|
|
|
|
|
|
|
make install |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
Check your PERL5LIB environment variable if INSTALL_BASE was used, or if you |
188
|
|
|
|
|
|
|
copied the lib/Mnet directory somewhere instead of using the included |
189
|
|
|
|
|
|
|
Makefile.PL script. Refer to L for more information |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head1 AUTHOR |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
The L perl distribution has been created and is maintained by Mike Menza. |
194
|
|
|
|
|
|
|
Feedback and bug reports are welcome, feel free to contact Mike via email |
195
|
|
|
|
|
|
|
at with any comments or questions. |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
Copyright 2006, 2013-2021 Michael J. Menza Jr. |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
L is free software: you can redistribute it and/or modify it under |
202
|
|
|
|
|
|
|
the terms of the GNU General Public License as published by the Free Software |
203
|
|
|
|
|
|
|
Foundation, either version 3 of the License, or (at your option) any later |
204
|
|
|
|
|
|
|
version. |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY |
207
|
|
|
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
208
|
|
|
|
|
|
|
PARTICULAR PURPOSE. See the GNU General Public License for more details. |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along with |
211
|
|
|
|
|
|
|
this program. If not, see L |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=head1 SEE ALSO |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
L |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
L |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
L |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
L |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
L |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
L |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
L |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
L |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=cut |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
# required modules |
234
|
|
|
|
|
|
|
# note that cpan complians if use strict is missing |
235
|
|
|
|
|
|
|
# perl 5.10 or higer required for all Mnet modules, they all use this module |
236
|
|
|
|
|
|
|
# perl 5.10 may be requried for tie to capture stdout and stderr |
237
|
|
|
|
|
|
|
# perl 5.8.9 warning: use of "shift" without parentheses is ambiguous |
238
|
34
|
|
|
34
|
|
237
|
use warnings; |
|
34
|
|
|
|
|
61
|
|
|
34
|
|
|
|
|
1197
|
|
239
|
34
|
|
|
34
|
|
169
|
use strict; |
|
34
|
|
|
|
|
65
|
|
|
34
|
|
|
|
|
716
|
|
240
|
34
|
|
|
34
|
|
748
|
use 5.010; |
|
34
|
|
|
|
|
118
|
|
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
# normal end of package |
243
|
|
|
|
|
|
|
1; |
244
|
|
|
|
|
|
|
|