line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::Intermapper; |
2
|
1
|
|
|
1
|
|
15052
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
26
|
|
3
|
1
|
|
|
1
|
|
480
|
use Moose; |
|
1
|
|
|
|
|
600999
|
|
|
1
|
|
|
|
|
12
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
# REST IO stuff here |
6
|
1
|
|
|
1
|
|
9204
|
use IO::Socket::SSL qw( SSL_VERIFY_NONE ); |
|
1
|
|
|
|
|
74628
|
|
|
1
|
|
|
|
|
8
|
|
7
|
1
|
|
|
1
|
|
715
|
use LWP::UserAgent; |
|
1
|
|
|
|
|
36392
|
|
|
1
|
|
|
|
|
37
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
# Generics |
10
|
1
|
|
|
1
|
|
36
|
use File::Path; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
233
|
|
11
|
1
|
|
|
1
|
|
5
|
use URI::Escape; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
59
|
|
12
|
1
|
|
|
1
|
|
852
|
use Text::CSV_XS; |
|
1
|
|
|
|
|
7420
|
|
|
1
|
|
|
|
|
90
|
|
13
|
1
|
|
|
1
|
|
649
|
use Data::Dumper; |
|
1
|
|
|
|
|
6291
|
|
|
1
|
|
|
|
|
108
|
|
14
|
1
|
|
|
1
|
|
1087
|
use XML::Simple; |
|
1
|
|
|
|
|
10709
|
|
|
1
|
|
|
|
|
11
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
# Net::Intermapper::* |
17
|
1
|
|
|
1
|
|
874
|
use Net::Intermapper::User; |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
91
|
|
18
|
1
|
|
|
1
|
|
756
|
use Net::Intermapper::Device; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
89
|
|
19
|
1
|
|
|
1
|
|
495
|
use Net::Intermapper::Interface; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
70
|
|
20
|
1
|
|
|
1
|
|
513
|
use Net::Intermapper::Map; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
60
|
|
21
|
1
|
|
|
1
|
|
468
|
use Net::Intermapper::Vertice; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
64
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
BEGIN { |
24
|
1
|
|
|
1
|
|
6
|
use Exporter (); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
19
|
|
25
|
1
|
|
|
1
|
|
3
|
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $ERROR %_CHANGED); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
101
|
|
26
|
1
|
|
|
1
|
|
1
|
$VERSION = '0.04'; |
27
|
1
|
|
|
|
|
17
|
@ISA = qw(Exporter); |
28
|
1
|
|
|
|
|
2
|
@EXPORT = qw(); |
29
|
1
|
|
|
|
|
2
|
@EXPORT_OK = qw(); |
30
|
1
|
|
|
|
|
2
|
%EXPORT_TAGS = (); |
31
|
1
|
|
|
|
|
1
|
%_CHANGED = (); |
32
|
1
|
|
|
|
|
2039
|
$ERROR = ""; # TODO: Document error properly! |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Moose! |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
has 'ssl_options' => ( |
38
|
|
|
|
|
|
|
is => 'rw', |
39
|
|
|
|
|
|
|
isa => 'HashRef', |
40
|
|
|
|
|
|
|
default => sub { { 'SSL_verify_mode' => SSL_VERIFY_NONE, 'verify_hostname' => '0' } } |
41
|
|
|
|
|
|
|
); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
has 'ssl' => ( |
44
|
|
|
|
|
|
|
is => 'rw', |
45
|
|
|
|
|
|
|
isa => 'Str', |
46
|
|
|
|
|
|
|
default => '1', |
47
|
|
|
|
|
|
|
); |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
has 'hostname' => ( |
50
|
|
|
|
|
|
|
is => 'rw', |
51
|
|
|
|
|
|
|
isa => 'Str', |
52
|
|
|
|
|
|
|
required => '1', |
53
|
|
|
|
|
|
|
); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
has 'port' => ( |
56
|
|
|
|
|
|
|
is => 'rw', |
57
|
|
|
|
|
|
|
isa => 'Int', |
58
|
|
|
|
|
|
|
default => sub { 8181 }, |
59
|
|
|
|
|
|
|
); |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
has 'modifyport' => ( |
62
|
|
|
|
|
|
|
is => 'rw', |
63
|
|
|
|
|
|
|
isa => 'Int', |
64
|
|
|
|
|
|
|
default => sub { 443 }, |
65
|
|
|
|
|
|
|
); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
has 'username' => ( |
68
|
|
|
|
|
|
|
is => 'rw', |
69
|
|
|
|
|
|
|
isa => 'Str', |
70
|
|
|
|
|
|
|
default => sub { "admin" }, |
71
|
|
|
|
|
|
|
); |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
has 'password' => ( |
74
|
|
|
|
|
|
|
is => 'rw', |
75
|
|
|
|
|
|
|
isa => 'Str', |
76
|
|
|
|
|
|
|
default => sub { "nmsadmin" }, |
77
|
|
|
|
|
|
|
); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
has 'format' => ( |
80
|
|
|
|
|
|
|
is => 'rw', |
81
|
|
|
|
|
|
|
isa => 'Str', |
82
|
|
|
|
|
|
|
default => sub { "csv" }, |
83
|
|
|
|
|
|
|
); |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
has 'cache' => ( |
86
|
|
|
|
|
|
|
is => 'rw', |
87
|
|
|
|
|
|
|
isa => 'Int', |
88
|
|
|
|
|
|
|
default => sub { "1" }, # Cache any request |
89
|
|
|
|
|
|
|
); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
has 'mock' => ( |
92
|
|
|
|
|
|
|
is => 'rw', |
93
|
|
|
|
|
|
|
isa => 'Int', |
94
|
|
|
|
|
|
|
default => sub { "0" }, |
95
|
|
|
|
|
|
|
); |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub users # No Moose here :( |
98
|
0
|
|
|
0
|
1
|
|
{ my $self = shift; |
99
|
0
|
|
|
|
|
|
$ERROR = ""; |
100
|
0
|
0
|
|
|
|
|
$_CHANGED{"users"} = !$self->{"Users"} ? 1 : $_CHANGED{"users"}; |
101
|
0
|
0
|
|
|
|
|
if (@_) |
102
|
|
|
|
|
|
|
{ #my %args = @_; |
103
|
|
|
|
|
|
|
#$self->{"Users"} = $args{"users"}; |
104
|
0
|
|
|
|
|
|
$self->{"Users"} = $_[0]; # Expect a hash ref to be passed |
105
|
|
|
|
|
|
|
# Yes, this code is slightly based of the Net::Cisco::ACS code so may be some of it is weird |
106
|
|
|
|
|
|
|
# Are you really reading the comments now? |
107
|
0
|
0
|
|
|
|
|
if ($self->mock()) |
108
|
0
|
|
|
|
|
|
{ return $self->{"Users"}; } |
109
|
|
|
|
|
|
|
} else |
110
|
0
|
0
|
|
|
|
|
{ if (!$self->cache) # No caching? Always reload |
111
|
0
|
0
|
|
|
|
|
{ $self->{"Users"} = $self->query("users") unless $self->mock; } |
112
|
|
|
|
|
|
|
else |
113
|
0
|
0
|
|
|
|
|
{ if (!$self->mock) |
114
|
0
|
0
|
|
|
|
|
{ $self->{"Users"} = $self->query("users") if $_CHANGED{"users"}; } # Only reload if changed |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
} |
117
|
0
|
0
|
|
|
|
|
return wantarray ? % { $self->{"Users"} } : $self->{"Users"}; |
|
0
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub devices # No Moose here :( |
121
|
0
|
|
|
0
|
1
|
|
{ my $self = shift; |
122
|
0
|
|
|
|
|
|
$ERROR = ""; |
123
|
0
|
0
|
|
|
|
|
$_CHANGED{"devices"} = !$self->{"Devices"} ? 1 : $_CHANGED{"devices"}; |
124
|
0
|
0
|
|
|
|
|
if (@_) |
125
|
|
|
|
|
|
|
{ #my %args = @_; |
126
|
|
|
|
|
|
|
#$self->{"Devices"} = $args{"devices"}; |
127
|
0
|
|
|
|
|
|
$self->{"Devices"} = $_[0]; # Expect a hash ref to be passed |
128
|
|
|
|
|
|
|
} else |
129
|
0
|
0
|
|
|
|
|
{ if (!$self->cache) # No caching? Always reload |
130
|
0
|
|
|
|
|
|
{ $self->{"Devices"} = $self->query("devices"); } |
131
|
|
|
|
|
|
|
else |
132
|
0
|
0
|
|
|
|
|
{ $self->{"Devices"} = $self->query("devices") if $_CHANGED{"devices"}; # Only reload if changed |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
} |
135
|
0
|
0
|
|
|
|
|
return wantarray ? % { $self->{"Devices"} } : $self->{"Devices"}; |
|
0
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub interfaces # No Moose here :( |
139
|
0
|
|
|
0
|
1
|
|
{ my $self = shift; |
140
|
0
|
|
|
|
|
|
$ERROR = ""; |
141
|
0
|
0
|
|
|
|
|
$_CHANGED{"interfaces"} = !$self->{"Interfaces"} ? 1 : $_CHANGED{"interfaces"}; |
142
|
0
|
0
|
|
|
|
|
if (@_) |
143
|
|
|
|
|
|
|
{ #my %args = @_; |
144
|
|
|
|
|
|
|
#$self->{"Interfaces"} = $args{"interfaces"}; |
145
|
0
|
|
|
|
|
|
$self->{"Interfaces"} = $_[0]; # Expect a hash ref to be passed |
146
|
|
|
|
|
|
|
} else |
147
|
0
|
0
|
|
|
|
|
{ if (!$self->cache) # No caching? Always reload |
148
|
0
|
|
|
|
|
|
{ $self->{"Interfaces"} = $self->query("interfaces"); } |
149
|
|
|
|
|
|
|
else |
150
|
0
|
0
|
|
|
|
|
{ $self->{"Interfaces"} = $self->query("interfaces") if $_CHANGED{"interfaces"}; # Only reload if changed |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
} |
153
|
0
|
0
|
|
|
|
|
return wantarray ? % { $self->{"Interfaces"} } : $self->{"Interfaces"}; |
|
0
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub maps # No Moose here :( |
157
|
0
|
|
|
0
|
1
|
|
{ my $self = shift; |
158
|
0
|
|
|
|
|
|
$ERROR = ""; |
159
|
0
|
0
|
|
|
|
|
$_CHANGED{"maps"} = !$self->{"Maps"} ? 1 : $_CHANGED{"maps"}; |
160
|
0
|
0
|
|
|
|
|
if (@_) |
161
|
|
|
|
|
|
|
{ #my %args = @_; |
162
|
|
|
|
|
|
|
#$self->{"Maps"} = $args{"maps"}; |
163
|
0
|
|
|
|
|
|
$self->{"Maps"} = $_[0]; # Expect a hash ref to be passed |
164
|
|
|
|
|
|
|
} else |
165
|
0
|
0
|
|
|
|
|
{ if (!$self->cache) # No caching? Always reload |
166
|
0
|
|
|
|
|
|
{ $self->{"Maps"} = $self->query("maps"); } |
167
|
|
|
|
|
|
|
else |
168
|
0
|
0
|
|
|
|
|
{ $self->{"Maps"} = $self->query("maps") if $_CHANGED{"maps"}; # Only reload if changed |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
} |
171
|
0
|
0
|
|
|
|
|
return wantarray ? % { $self->{"Maps"} } : $self->{"Maps"}; |
|
0
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub vertices # No Moose here :( |
175
|
0
|
|
|
0
|
1
|
|
{ my $self = shift; |
176
|
0
|
|
|
|
|
|
$ERROR = ""; |
177
|
0
|
0
|
|
|
|
|
$_CHANGED{"vertices"} = !$self->{"Vertices"} ? 1 : $_CHANGED{"vertices"}; |
178
|
0
|
0
|
|
|
|
|
if (@_) |
179
|
|
|
|
|
|
|
{ #my %args = @_; |
180
|
|
|
|
|
|
|
#$self->{"Vertices"} = $args{"vertices"}; |
181
|
0
|
|
|
|
|
|
$self->{"Vertices"} = $_[0]; # Expect a hash ref to be passed |
182
|
|
|
|
|
|
|
} else |
183
|
0
|
0
|
|
|
|
|
{ if (!$self->cache) # No caching? Always reload |
184
|
0
|
|
|
|
|
|
{ $self->{"Vertices"} = $self->query("vertices"); } |
185
|
|
|
|
|
|
|
else |
186
|
0
|
0
|
|
|
|
|
{ $self->{"Vertices"} = $self->query("vertices") if $_CHANGED{"vertices"}; # Only reload if changed |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
} |
189
|
0
|
0
|
|
|
|
|
return wantarray ? % { $self->{"Vertices"} } : $self->{"Vertices"}; |
|
0
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub query |
193
|
0
|
|
|
0
|
0
|
|
{ my ($self, $type) = @_; |
194
|
0
|
|
|
|
|
|
my $hostname = $self->hostname; |
195
|
0
|
|
|
|
|
|
my $username = $self->username; |
196
|
0
|
|
|
|
|
|
my $password = $self->password; |
197
|
0
|
|
|
|
|
|
my $port = $self->port; |
198
|
0
|
|
|
|
|
|
my $format = $self->format; |
199
|
0
|
0
|
|
|
|
|
if ($self->ssl) |
200
|
0
|
|
|
|
|
|
{ $hostname = "https://$username:$password\@$hostname:$port"; } else |
201
|
0
|
|
|
|
|
|
{ $hostname = "http://$username:$password\@$hostname:$port"; } |
202
|
0
|
|
|
|
|
|
$hostname .= "/~export/$type.$format"; |
203
|
0
|
|
|
|
|
|
my $request = HTTP::Request->new("GET" => $hostname); |
204
|
0
|
|
|
|
|
|
my $useragent = LWP::UserAgent->new (ssl_opts => $self->ssl_options); |
205
|
0
|
|
|
|
|
|
my $result = $useragent->request($request); |
206
|
0
|
0
|
|
|
|
|
if ($result->code eq "400") { $ERROR = "Bad Request - HTTP Status: 400"; } |
|
0
|
|
|
|
|
|
|
207
|
0
|
0
|
|
|
|
|
if ($result->code eq "410") { $ERROR = "Unknown $type queried by name or ID - HTTP Status: 410"; } |
|
0
|
|
|
|
|
|
|
208
|
0
|
0
|
|
|
|
|
if ($self->format eq "csv") |
209
|
0
|
|
|
|
|
|
{ $self->parse_csv($type, $result->decoded_content); |
210
|
|
|
|
|
|
|
} |
211
|
0
|
0
|
|
|
|
|
if ($self->format eq "tab") |
212
|
0
|
|
|
|
|
|
{ $self->parse_tab($type, $result->decoded_content); |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
|
215
|
0
|
0
|
|
|
|
|
if ($self->format eq "xml") |
216
|
|
|
|
|
|
|
{ #$self->parse_xml($type, $result->content); # XML seems to be broken?!? |
217
|
|
|
|
|
|
|
#warn Dumper $result->content; |
218
|
|
|
|
|
|
|
#This needs work!! |
219
|
|
|
|
|
|
|
} |
220
|
0
|
|
|
|
|
|
$_CHANGED{$type} = 0; |
221
|
0
|
0
|
|
|
|
|
return $self->{"Users"} if $type eq "users"; |
222
|
0
|
0
|
|
|
|
|
return $self->{"Devices"} if $type eq "devices"; |
223
|
0
|
0
|
|
|
|
|
return $self->{"Interfaces"} if $type eq "interfaces"; |
224
|
0
|
0
|
|
|
|
|
return $self->{"Maps"} if $type eq "maps"; |
225
|
0
|
0
|
|
|
|
|
return $self->{"Vertices"} if $type eq "vertices"; |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
# It seems that Maps and Interfaces cannot be created? |
229
|
|
|
|
|
|
|
sub create |
230
|
0
|
|
|
0
|
1
|
|
{ my $self = shift; |
231
|
0
|
|
|
|
|
|
my @entries = @_; |
232
|
0
|
0
|
|
|
|
|
return unless @entries; |
233
|
0
|
|
|
|
|
|
my $username = $self->username; |
234
|
0
|
|
|
|
|
|
my $password = $self->password; |
235
|
0
|
|
|
|
|
|
my $format = $self->format; # csv or xml (unsupported at this point) |
236
|
0
|
|
|
|
|
|
my $type = ""; |
237
|
|
|
|
|
|
|
|
238
|
0
|
|
|
|
|
|
my $hostname = $self->hostname; |
239
|
0
|
|
|
|
|
|
my $port = $self->modifyport; |
240
|
0
|
0
|
|
|
|
|
if ($port ne "") { $port = ":$port"; } |
|
0
|
|
|
|
|
|
|
241
|
0
|
0
|
|
|
|
|
if ($self->ssl) |
242
|
0
|
|
|
|
|
|
{ $hostname = "https://$username:$password\@$hostname$port/~import/file"; } else |
243
|
0
|
|
|
|
|
|
{ $hostname = "http://$username:$password\@$hostname$port/~import/file"; } |
244
|
|
|
|
|
|
|
|
245
|
0
|
|
|
|
|
|
my $data = $entries[0]->header($format); |
246
|
0
|
|
|
|
|
|
$type = lc(ref($entries[0])); |
247
|
0
|
|
|
|
|
|
$type =~ s/^net\:\:intermapper\:\://; # Needed for the change flags@ |
248
|
0
|
|
|
|
|
|
while(@entries) |
249
|
0
|
|
|
|
|
|
{ my $entry = shift @entries; |
250
|
0
|
0
|
|
|
|
|
if ($format eq "csv") |
251
|
0
|
|
|
|
|
|
{ $data .= $entry->toCSV; } |
252
|
0
|
0
|
|
|
|
|
if ($format eq "tab") |
253
|
0
|
|
|
|
|
|
{ $data .= $entry->toTAB; } |
254
|
0
|
|
|
|
|
|
$data =~ s/^\s*//g; |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
0
|
|
|
|
|
|
my $request = HTTP::Request->new(POST => "$hostname"); |
258
|
0
|
|
|
|
|
|
my $useragent = LWP::UserAgent->new("ssl_opts" => $self->ssl_options); |
259
|
|
|
|
|
|
|
|
260
|
0
|
|
|
|
|
|
$request->content_type('application/x-www-form-urlencoded'); |
261
|
0
|
|
|
|
|
|
$request->content($data); |
262
|
0
|
|
|
|
|
|
$request->header('Accept' => 'text/html'); |
263
|
0
|
|
|
|
|
|
my $result = $useragent->request($request); |
264
|
0
|
|
|
|
|
|
$_CHANGED{$type} = 0; # Flag smart caching to force reload |
265
|
0
|
|
|
|
|
|
return $result; |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
# This SHOULD be sufficient? |
269
|
|
|
|
|
|
|
sub update |
270
|
0
|
|
|
0
|
1
|
|
{ my $self = shift; |
271
|
0
|
|
|
|
|
|
my $entry = shift; |
272
|
0
|
|
|
|
|
|
$entry->mode("update"); |
273
|
0
|
|
|
|
|
|
return $self->create($entry); |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
# This SHOULD be sufficient? |
277
|
|
|
|
|
|
|
sub delete |
278
|
0
|
|
|
0
|
1
|
|
{ my $self = shift; |
279
|
0
|
|
|
|
|
|
my $entry = shift; |
280
|
0
|
|
|
|
|
|
$entry->mode("delete"); |
281
|
0
|
|
|
|
|
|
return $self->create($entry); |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub parse_xml # Broken! |
285
|
0
|
|
|
0
|
0
|
|
{ my $self = shift; |
286
|
0
|
|
|
|
|
|
my $type = shift; |
287
|
0
|
|
|
|
|
|
my $xml_ref = shift; |
288
|
0
|
|
|
|
|
|
my $xmlsimple = XML::Simple->new(); |
289
|
0
|
|
|
|
|
|
my $xmlout = $xmlsimple->XMLin($xml_ref); |
290
|
0
|
0
|
|
|
|
|
if ($type eq "users") |
291
|
0
|
|
|
|
|
|
{ my $users_ref = $xmlout->{"users"}; |
292
|
0
|
|
|
|
|
|
my %users = (); |
293
|
0
|
|
|
|
|
|
for my $key (@ {$users_ref}) |
|
0
|
|
|
|
|
|
|
294
|
0
|
|
|
|
|
|
{ my $user = Net::Intermapper::User->new( @{ $key } ); |
|
0
|
|
|
|
|
|
|
295
|
0
|
|
|
|
|
|
$users{$key} = $user; |
296
|
|
|
|
|
|
|
} |
297
|
0
|
|
|
|
|
|
$self->{"Users"} = \%users; #Not sure if this works with the |
298
|
0
|
|
|
|
|
|
return $self->{"Users"}; |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
|
301
|
0
|
0
|
|
|
|
|
if ($type eq "devices") |
302
|
0
|
|
|
|
|
|
{ my $devices_ref = $xmlout->{"devices"}; |
303
|
0
|
|
|
|
|
|
my %devices = (); |
304
|
0
|
|
|
|
|
|
for my $key (@ {$devices_ref}) |
|
0
|
|
|
|
|
|
|
305
|
0
|
|
|
|
|
|
{ my $device = Net::Intermapper::Device->new( @{ $key } ); |
|
0
|
|
|
|
|
|
|
306
|
0
|
|
|
|
|
|
$devices{$key} = $device; |
307
|
|
|
|
|
|
|
} |
308
|
0
|
|
|
|
|
|
$self->{"Devices"} = \%devices; |
309
|
0
|
|
|
|
|
|
return $self->{"Devices"}; |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
|
312
|
0
|
0
|
|
|
|
|
if ($type eq "interfaces") |
313
|
0
|
|
|
|
|
|
{ my $interfaces_ref = $xmlout->{"interfaces"}; |
314
|
0
|
|
|
|
|
|
my %interfaces = (); |
315
|
0
|
|
|
|
|
|
for my $key (@ {$interfaces_ref}) |
|
0
|
|
|
|
|
|
|
316
|
0
|
|
|
|
|
|
{ my $interface = Net::Intermapper::Interface->new( @{ $key } ); |
|
0
|
|
|
|
|
|
|
317
|
0
|
|
|
|
|
|
$interfaces{$key} = $interface; |
318
|
|
|
|
|
|
|
} |
319
|
0
|
|
|
|
|
|
$self->{"Interfaces"} = \%interfaces; |
320
|
0
|
|
|
|
|
|
return $self->{"Interfaces"}; |
321
|
|
|
|
|
|
|
} |
322
|
|
|
|
|
|
|
|
323
|
0
|
0
|
|
|
|
|
if ($type eq "maps") |
324
|
0
|
|
|
|
|
|
{ my $maps_ref = $xmlout->{"maps"}; |
325
|
0
|
|
|
|
|
|
my %maps = (); |
326
|
0
|
|
|
|
|
|
for my $key (@ {$maps_ref}) |
|
0
|
|
|
|
|
|
|
327
|
0
|
|
|
|
|
|
{ my $map = Net::Intermapper::Map->new( @{ $key } ); |
|
0
|
|
|
|
|
|
|
328
|
0
|
|
|
|
|
|
$maps{$key} = $map; |
329
|
|
|
|
|
|
|
} |
330
|
0
|
|
|
|
|
|
$self->{"Maps"} = \%maps; |
331
|
0
|
|
|
|
|
|
return $self->{"Maps"}; |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
|
334
|
0
|
0
|
|
|
|
|
if ($type eq "vertices") |
335
|
0
|
|
|
|
|
|
{ my $vertices_ref = $xmlout->{"vertices"}; |
336
|
0
|
|
|
|
|
|
my %vertices = (); |
337
|
0
|
|
|
|
|
|
for my $key (@ {$vertices_ref}) |
|
0
|
|
|
|
|
|
|
338
|
0
|
|
|
|
|
|
{ my $vertice = Net::Intermapper::Vertice->new( @{ $key } ); |
|
0
|
|
|
|
|
|
|
339
|
0
|
|
|
|
|
|
$vertices{$key} = $vertice; |
340
|
|
|
|
|
|
|
} |
341
|
0
|
|
|
|
|
|
$self->{"Vertices"} = \%vertices; |
342
|
0
|
|
|
|
|
|
return $self->{"Vertices"}; |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
sub parse_csv |
348
|
0
|
|
|
0
|
0
|
|
{ my $self = shift; |
349
|
0
|
|
|
|
|
|
my $type = shift; |
350
|
0
|
|
|
|
|
|
my $csv_ref = shift; |
351
|
0
|
|
|
|
|
|
my @header = (); |
352
|
0
|
|
|
|
|
|
my %data = (); |
353
|
0
|
0
|
|
|
|
|
if ($type eq "users") |
354
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::User::HEADERS; } |
355
|
0
|
0
|
|
|
|
|
if ($type eq "devices") |
356
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::Device::HEADERS; } |
357
|
0
|
0
|
|
|
|
|
if ($type eq "interfaces") |
358
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::Interface::HEADERS; } |
359
|
0
|
0
|
|
|
|
|
if ($type eq "maps") |
360
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::Map::HEADERS; } |
361
|
0
|
0
|
|
|
|
|
if ($type eq "vertices") |
362
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::Vertice::HEADERS; } |
363
|
|
|
|
|
|
|
|
364
|
0
|
|
|
|
|
|
my @lines = split(/\r\n/,$csv_ref); |
365
|
0
|
|
|
|
|
|
my $csv = Text::CSV_XS->new ({ "auto_diag" => "1", "binary" => "1" }); |
366
|
0
|
|
|
|
|
|
for my $line (@lines) |
367
|
0
|
|
|
|
|
|
{ my $i = 0; |
368
|
0
|
|
|
|
|
|
my %fields = (); |
369
|
0
|
0
|
|
|
|
|
if ($csv->parse ($line)) |
370
|
0
|
|
|
|
|
|
{ my @fields = $csv->fields; |
371
|
0
|
|
|
|
|
|
for my $field (@fields) |
372
|
0
|
|
|
|
|
|
{ $fields{$header[$i]} = $field; |
373
|
0
|
|
|
|
|
|
$i++; |
374
|
|
|
|
|
|
|
} |
375
|
0
|
0
|
|
|
|
|
if ($type eq "users") |
376
|
0
|
|
|
|
|
|
{ my $user = Net::Intermapper::User->new( %fields ); |
377
|
0
|
|
|
|
|
|
$data{$user->Name} = $user; |
378
|
|
|
|
|
|
|
} |
379
|
0
|
0
|
|
|
|
|
if ($type eq "devices") |
380
|
0
|
|
|
|
|
|
{ my $device = Net::Intermapper::Device->new( %fields ); |
381
|
0
|
|
|
|
|
|
$data{$device->Id} = $device; |
382
|
|
|
|
|
|
|
} |
383
|
0
|
0
|
|
|
|
|
if ($type eq "interfaces") |
384
|
0
|
|
|
|
|
|
{ my $interface = Net::Intermapper::Interface->new( %fields ); |
385
|
0
|
|
|
|
|
|
$data{$interface->InterfaceID} = $interface; |
386
|
|
|
|
|
|
|
} |
387
|
0
|
0
|
|
|
|
|
if ($type eq "maps") |
388
|
0
|
|
|
|
|
|
{ my $map = Net::Intermapper::Map->new( %fields ); |
389
|
0
|
|
|
|
|
|
$data{$map->MapName} = $map; |
390
|
|
|
|
|
|
|
} |
391
|
0
|
0
|
|
|
|
|
if ($type eq "vertices") |
392
|
0
|
|
|
|
|
|
{ my $vertice = Net::Intermapper::Vertice->new( %fields ); |
393
|
0
|
|
|
|
|
|
$data{$vertice->Id} = $vertice; |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
} |
398
|
0
|
0
|
|
|
|
|
if ($type eq "users") |
399
|
0
|
|
|
|
|
|
{ $self->{"Users"} = \%data; |
400
|
0
|
|
|
|
|
|
return $self->{"Users"}; |
401
|
|
|
|
|
|
|
} |
402
|
0
|
0
|
|
|
|
|
if ($type eq "devices") |
403
|
0
|
|
|
|
|
|
{ $self->{"Devices"} = \%data; |
404
|
0
|
|
|
|
|
|
return $self->{"Devices"}; |
405
|
|
|
|
|
|
|
} |
406
|
0
|
0
|
|
|
|
|
if ($type eq "interfaces") |
407
|
0
|
|
|
|
|
|
{ $self->{"Interfaces"} = \%data; |
408
|
0
|
|
|
|
|
|
return $self->{"Interfaces"}; |
409
|
|
|
|
|
|
|
} |
410
|
0
|
0
|
|
|
|
|
if ($type eq "maps") |
411
|
0
|
|
|
|
|
|
{ $self->{"Maps"} = \%data; |
412
|
0
|
|
|
|
|
|
return $self->{"Maps"}; |
413
|
|
|
|
|
|
|
} |
414
|
0
|
0
|
|
|
|
|
if ($type eq "vertices") |
415
|
0
|
|
|
|
|
|
{ $self->{"Vertices"} = \%data; |
416
|
0
|
|
|
|
|
|
return $self->{"Vertices"}; |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
sub parse_tab |
422
|
0
|
|
|
0
|
0
|
|
{ my $self = shift; |
423
|
0
|
|
|
|
|
|
my $type = shift; |
424
|
0
|
|
|
|
|
|
my $tab_ref = shift; |
425
|
0
|
|
|
|
|
|
my @header = (); |
426
|
0
|
|
|
|
|
|
my %data = (); |
427
|
0
|
0
|
|
|
|
|
if ($type eq "users") |
428
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::User::HEADERS; } |
429
|
0
|
0
|
|
|
|
|
if ($type eq "devices") |
430
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::Device::HEADERS; } |
431
|
0
|
0
|
|
|
|
|
if ($type eq "interfaces") |
432
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::Interface::HEADERS; } |
433
|
0
|
0
|
|
|
|
|
if ($type eq "maps") |
434
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::Map::HEADERS; } |
435
|
0
|
0
|
|
|
|
|
if ($type eq "vertices") |
436
|
0
|
|
|
|
|
|
{ @header = @Net::Intermapper::Vertice::HEADERS; } |
437
|
0
|
|
|
|
|
|
my $linecount = 0; |
438
|
0
|
|
|
|
|
|
my @lines = split(/[\r\n]{1,2}/,$tab_ref); |
439
|
0
|
|
|
|
|
|
for my $line (@lines) |
440
|
0
|
|
|
|
|
|
{ my $i = 0; |
441
|
0
|
|
|
|
|
|
my %fields = (); |
442
|
0
|
|
|
|
|
|
my @fields = split(/\t/,$line); |
443
|
0
|
0
|
|
|
|
|
if (!$linecount) { $linecount++; next; } # Skip header line - KNOWN VALUES |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
444
|
0
|
|
|
|
|
|
for my $field (@fields) |
445
|
0
|
|
|
|
|
|
{ $fields{$header[$i]} = $field; |
446
|
0
|
|
|
|
|
|
$i++; |
447
|
|
|
|
|
|
|
} |
448
|
0
|
0
|
|
|
|
|
if ($type eq "users") |
449
|
0
|
|
|
|
|
|
{ my $user = Net::Intermapper::User->new( %fields ); |
450
|
0
|
|
|
|
|
|
$data{$user->Name} = $user; |
451
|
|
|
|
|
|
|
} |
452
|
0
|
0
|
|
|
|
|
if ($type eq "devices") |
453
|
0
|
|
|
|
|
|
{ my $device = Net::Intermapper::Device->new( %fields ); |
454
|
0
|
|
|
|
|
|
$data{$device->Id} = $device; |
455
|
|
|
|
|
|
|
} |
456
|
0
|
0
|
|
|
|
|
if ($type eq "interfaces") |
457
|
0
|
|
|
|
|
|
{ my $interface = Net::Intermapper::Interface->new( %fields ); |
458
|
0
|
|
|
|
|
|
$data{$interface->InterfaceID} = $interface; |
459
|
|
|
|
|
|
|
} |
460
|
0
|
0
|
|
|
|
|
if ($type eq "maps") |
461
|
0
|
|
|
|
|
|
{ my $map = Net::Intermapper::Map->new( %fields ); |
462
|
0
|
|
|
|
|
|
$data{$map->MapName} = $map; |
463
|
|
|
|
|
|
|
} |
464
|
0
|
0
|
|
|
|
|
if ($type eq "vertices") |
465
|
0
|
|
|
|
|
|
{ my $vertice = Net::Intermapper::Vertice->new( %fields ); |
466
|
0
|
|
|
|
|
|
$data{$vertice->Id} = $vertice; |
467
|
|
|
|
|
|
|
} |
468
|
|
|
|
|
|
|
} |
469
|
0
|
0
|
|
|
|
|
if ($type eq "users") |
470
|
0
|
|
|
|
|
|
{ $self->{"Users"} = \%data; |
471
|
0
|
|
|
|
|
|
return $self->{"Users"}; |
472
|
|
|
|
|
|
|
} |
473
|
0
|
0
|
|
|
|
|
if ($type eq "devices") |
474
|
0
|
|
|
|
|
|
{ $self->{"Devices"} = \%data; |
475
|
0
|
|
|
|
|
|
return $self->{"Devices"}; |
476
|
|
|
|
|
|
|
} |
477
|
0
|
0
|
|
|
|
|
if ($type eq "interfaces") |
478
|
0
|
|
|
|
|
|
{ $self->{"Interfaces"} = \%data; |
479
|
0
|
|
|
|
|
|
return $self->{"Interfaces"}; |
480
|
|
|
|
|
|
|
} |
481
|
0
|
0
|
|
|
|
|
if ($type eq "maps") |
482
|
0
|
|
|
|
|
|
{ $self->{"Maps"} = \%data; |
483
|
0
|
|
|
|
|
|
return $self->{"Maps"}; |
484
|
|
|
|
|
|
|
} |
485
|
0
|
0
|
|
|
|
|
if ($type eq "vertices") |
486
|
0
|
|
|
|
|
|
{ $self->{"Vertices"} = \%data; |
487
|
0
|
|
|
|
|
|
return $self->{"Vertices"}; |
488
|
|
|
|
|
|
|
} |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
=pod |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=head1 NAME |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Net::Intermapper - Interface with the HelpSystems Intermapper HTTP API |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
=head1 SYNOPSIS |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
use Net::Intermapper; |
501
|
|
|
|
|
|
|
my $intermapper = Net::Intermapper->new(hostname=>"10.0.0.1", username=>"admin", password=>"nmsadmin"); |
502
|
|
|
|
|
|
|
# Options: |
503
|
|
|
|
|
|
|
# hostname - IP or hostname of Intermapper 5.x and 6.x server |
504
|
|
|
|
|
|
|
# username - Username of Administrator user |
505
|
|
|
|
|
|
|
# password - Password of user |
506
|
|
|
|
|
|
|
# ssl - SSL enabled (1 - default) or disabled (0) |
507
|
|
|
|
|
|
|
# port - TCP port for querying information. Defaults to 8181 |
508
|
|
|
|
|
|
|
# modifyport - TCP port for modifying information. Default to 443 |
509
|
|
|
|
|
|
|
# cache - Boolean to enable smart caching or force network queries |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
my %users = $intermapper->users; |
512
|
|
|
|
|
|
|
my $users_ref = $intermapper->users; |
513
|
|
|
|
|
|
|
# Retrieve all users from Intermapper, Net::Intermapper::User instances |
514
|
|
|
|
|
|
|
# Returns hash or hashref, depending on context |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
my %devices = $intermapper->devices; |
517
|
|
|
|
|
|
|
my $devices_ref = $intermapper->devices; |
518
|
|
|
|
|
|
|
# Retrieve all devices from Intermapper, Net::Intermapper::Device instances |
519
|
|
|
|
|
|
|
# Returns hash or hashref, depending on context |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
my %maps = $intermapper->maps; |
522
|
|
|
|
|
|
|
my $maps_ref = $intermapper->maps; |
523
|
|
|
|
|
|
|
# Retrieve all maps from Intermapper, Net::Intermapper::Map instances |
524
|
|
|
|
|
|
|
# Returns hash or hashref, depending on context |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
my %interfaces = $intermapper->interfaces; |
527
|
|
|
|
|
|
|
my $interfaces_ref = $intermapper->interfaces; |
528
|
|
|
|
|
|
|
# Retrieve all interfaces from Intermapper, Net::Intermapper::Interface instances |
529
|
|
|
|
|
|
|
# Returns hash or hashref, depending on context |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
my %vertices = $intermapper->vertices; |
532
|
|
|
|
|
|
|
my $vertices_ref = $intermapper->vertices; |
533
|
|
|
|
|
|
|
# Retrieve all vertices from Intermapper, Net::Intermapper::Vertice instances |
534
|
|
|
|
|
|
|
# Returns hash or hashref, depending on context |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
my $user = $intermapper->users->{"admin"}; |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
# Each class will generate specific header. These are typically only for internal use but are compliant to the import format Intermapper uses. |
539
|
|
|
|
|
|
|
print $user->header; |
540
|
|
|
|
|
|
|
print $device->header; |
541
|
|
|
|
|
|
|
print $map->header; |
542
|
|
|
|
|
|
|
print $interface->header; |
543
|
|
|
|
|
|
|
print $vertice->header; |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
print $user->toTAB; |
546
|
|
|
|
|
|
|
print $device->toXML; # This one is broken still! |
547
|
|
|
|
|
|
|
print $map->toCSV; |
548
|
|
|
|
|
|
|
# Works on ALL subclasses |
549
|
|
|
|
|
|
|
# Produce human-readable output of each record in the formats Intermapper supports |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
my $user = Net::Intermapper::User->new(Name=>"testuser", Password=>"Test12345"); |
552
|
|
|
|
|
|
|
my $response = $intermapper->create($user); |
553
|
|
|
|
|
|
|
# Create new user |
554
|
|
|
|
|
|
|
# Return value is HTTP::Response object |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
my $device = Net::Intermapper::Device->new(Name=>"testDevice", MapName=>"TestMap", MapPath=>"/TestMap", Address=>"10.0.0.1"); |
557
|
|
|
|
|
|
|
my $response = $intermapper->create($device); |
558
|
|
|
|
|
|
|
# Create new device |
559
|
|
|
|
|
|
|
# Return value is HTTP::Response object |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
$user->Password("Foobar123"); |
562
|
|
|
|
|
|
|
my $response = $intermapper->update($user); |
563
|
|
|
|
|
|
|
# Update existing user |
564
|
|
|
|
|
|
|
# Return value is HTTP::Response object |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
my $user = $intermapper->users->{"bob"}; |
567
|
|
|
|
|
|
|
my $response = $intermapper->delete($user); |
568
|
|
|
|
|
|
|
# Delete existing user |
569
|
|
|
|
|
|
|
# Return value is HTTP::Response object |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
my $device = $intermapper->devices->{"UniqueDeviceID"}; |
572
|
|
|
|
|
|
|
my $response = $intermapper->delete($device); |
573
|
|
|
|
|
|
|
# Delete existing device |
574
|
|
|
|
|
|
|
# Return value is HTTP::Response object |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
my $users = { "Tom" => $tom_user, "Bob" => $bob_user }; |
577
|
|
|
|
|
|
|
$intermapper->users($users); |
578
|
|
|
|
|
|
|
# At this point, there is no real reason to do this as update, create and delete work with explicit arguments. |
579
|
|
|
|
|
|
|
# But it can be done with users, devices, interfaces, maps and vertices |
580
|
|
|
|
|
|
|
# Pass a hashref to each method. This will NOT affect the smart-caching (only explicit calls to create, update and delete do this - for now). |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
=head1 DESCRIPTION |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
Net::Intermapper is a perl wrapper around the HelpSystems Intermapper API provided through HTTP/HTTPS for access to user accounts, device information, maps, interfaces and graphical elements. |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
All calls are handled through an instance of the L<Net::Intermapper> class. |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
use Net::Intermapper; |
589
|
|
|
|
|
|
|
my $intermapper = Net::Intermapper->new(hostname => '10.0.0.1', username => 'admin', password => 'nmsadmin'); |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
=over 3 |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
=item new |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
Class constructor. Returns object of Net::Intermapper on succes. Required fields are: |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=over 5 |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
=item hostname |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
=item username |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=item password |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
=back |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
Optional fields are |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
=over 5 |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
=item ssl |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
=item ssl_options |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
=item port |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
=item modifyport |
618
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
=item cache |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
=back |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
=item hostname |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
IP or hostname of Intermapper server. This is a required value in the constructor but can be redefined afterwards. |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
=item username |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
Username of Administrator user. This is a required value in the constructor but can be redefined afterwards. |
630
|
|
|
|
|
|
|
As the API is used a different mechanism to query information than it uses to update, this needs to be changed when switching. Typically, the built-in C<admin> user is used for modifying a record. |
631
|
|
|
|
|
|
|
This value is not automatically changed when running C<create> or C<update>. |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
=item password |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
Password of user. This is a required value in the constructor but can be redefined afterwards. |
636
|
|
|
|
|
|
|
As the API is used a different mechanism to query information than it uses to update, this needs to be changed when switching. Typically, the built-in C<admin> user is used for modifying a record. |
637
|
|
|
|
|
|
|
This value is not automatically changed when running C<create> or C<update>. |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
=item ssl |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
SSL enabled (1 - default) or disabled (0). |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
=item ssl_options |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
Value is passed directly to L<LWP::UserAgent> as C<ssl_opt>. Default value (hash-ref) is |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
{ 'SSL_verify_mode' => SSL_VERIFY_NONE, 'verify_hostname' => '0' } |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
This is an optional value in the constructor and can be redefined afterwards. |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
=item port |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
TCP port used for queries. This is an optional value in the constructor and can be redefined afterwards. By default, this is set to 8181. |
654
|
|
|
|
|
|
|
As the API is used a different mechanism to query information than it uses to update, the C<port> value is used for queries only and is automatically switched. Set this ONLY if you have customized Intermapper to listen to a different port. |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
=item modifyport |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
TCP port used for modifying values. This is an optional value in the constructor and can be redefined afterwards. By default, this is set to 443. |
659
|
|
|
|
|
|
|
As the API is used a different mechanism to modify (create and update) information than it uses to query, the C<modifyport> value is used for modifying only and is automatically switched. Set this ONLY if you have customized Intermapper to listen to a different port. |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
=item cache |
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
Set to true (default) to use in-memory dataset to avoid unnecessary queries. Dataset are always queries when changes are made (after delete, create or update), per type. Changes to users dataset will not affect the devices dataset. This is a required value in the constructor but can be redefined afterwards. |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
$intermapper->cache(0); |
666
|
|
|
|
|
|
|
$intermapper->update($user); |
667
|
|
|
|
|
|
|
# Users have changed. |
668
|
|
|
|
|
|
|
my $users = $intermapper->users; |
669
|
|
|
|
|
|
|
# This will trigger network traffic |
670
|
|
|
|
|
|
|
my $devices = $intermapper->devices |
671
|
|
|
|
|
|
|
# This will NOT trigger network traffic |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
=back |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
From the class instance, call the different methods for retrieving values. |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
=over 3 |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
=item users |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
Returns all users |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
my %users = $intermapper->users(); |
684
|
|
|
|
|
|
|
my $user = $users{"Bob"}; |
685
|
|
|
|
|
|
|
print $user->Password; |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
The returned hash contains instances of L<Net::Intermapper::User>, using the username as the hash key. In scalar context, will return hashref. This method will typically trigger a network connection, depending on caching. |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
Modify the in-memory users dataset: |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
my $users = { "Tom" => $tom_user, "Bob" => $bob_user }; |
692
|
|
|
|
|
|
|
$intermapper->users($users); |
693
|
|
|
|
|
|
|
# At this point, there is no real reason to do this as update, create and delete work with explicit arguments. |
694
|
|
|
|
|
|
|
# But it can be done with users, devices, interfaces, maps and vertices |
695
|
|
|
|
|
|
|
# Pass a hashref to each method. This will NOT affect the smart-caching (only explicit calls to create, update and delete do this - for now). |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
=item devices |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
returns all devices |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
my %devices = $intermapper->devices(); |
702
|
|
|
|
|
|
|
my $device = $devices{"UniqueDeviceID"}; |
703
|
|
|
|
|
|
|
print $device->Address; |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
The returned hash contains instances of L<Net::Intermapper::Device>, using the device ID as the hash key. In scalar context, will return hashref. This method will typically trigger a network connection, depending on caching. |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
Modify the in-memory users dataset: |
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
my $devices = { "MainRouter1" => $main1, "MainRouter2" => $main2 }; |
710
|
|
|
|
|
|
|
$intermapper->devices($devices); |
711
|
|
|
|
|
|
|
# At this point, there is no real reason to do this as update, create and delete work with explicit arguments. |
712
|
|
|
|
|
|
|
# But it can be done with users, devices, interfaces, maps and vertices |
713
|
|
|
|
|
|
|
# Pass a hashref to each method. This will NOT affect the smart-caching (only explicit calls to create, update and delete do this - for now). |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
=item maps |
716
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
returns all maps |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
my %maps = $intermapper->maps(); |
720
|
|
|
|
|
|
|
my $map = $maps{"MainMap"}; |
721
|
|
|
|
|
|
|
print $map->Name; |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
The returned hash contains instances of L<Net::Intermapper::Map>, using the map name as the hash key. In scalar context, will return hashref. This method will typically trigger a network connection, depending on caching. |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
Modify the in-memory users dataset: |
726
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
my $maps = { "MainMap" => $main1, "Layer2" => $main2 }; |
728
|
|
|
|
|
|
|
$intermapper->maps($maps); |
729
|
|
|
|
|
|
|
# At this point, there is no real reason to do this as update, create and delete work with explicit arguments. |
730
|
|
|
|
|
|
|
# But it can be done with users, devices, interfaces, maps and vertices |
731
|
|
|
|
|
|
|
# Pass a hashref to each method. This will NOT affect the smart-caching (only explicit calls to create, update and delete do this - for now). |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
=item interfaces |
734
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
returns all interfaces |
736
|
|
|
|
|
|
|
|
737
|
|
|
|
|
|
|
my %interfaces = $intermapper->interfaces(); |
738
|
|
|
|
|
|
|
my $interface = $devices{"UniqueInterfaceID"}; |
739
|
|
|
|
|
|
|
print $interface->Address; |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
The returned hash contains instances of L<Net::Intermapper::Interface>, using the interface ID (generated by Intermapper) as the hash key. In scalar context, will return hashref. This method will typically trigger a network connection, depending on caching. |
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
Modify the in-memory users dataset: |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
my $interfaces = { "UniqueKey1" => $iface1, "UniqueKey2" => $iface2 }; |
746
|
|
|
|
|
|
|
$intermapper->interfaces($interfaces); |
747
|
|
|
|
|
|
|
# At this point, there is no real reason to do this as update, create and delete work with explicit arguments. |
748
|
|
|
|
|
|
|
# But it can be done with users, devices, interfaces, maps and vertices |
749
|
|
|
|
|
|
|
# Pass a hashref to each method. This will NOT affect the smart-caching (only explicit calls to create, update and delete do this - for now). |
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
=item vertices |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
returns all vertices |
754
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
my %vertices = $intermapper->vertices(); |
756
|
|
|
|
|
|
|
my $vertice = $vertices{"ID"}; # Unique Vertex ID |
757
|
|
|
|
|
|
|
print $vertice->Shape; |
758
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
The returned hash contains instances of L<Net::Intermapper::Vertice>, using the vertex ID as the hash key. In scalar context, will return hashref. This method will typically trigger a network connection, depending on caching. |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
Modify the in-memory users dataset: |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
my $vertices = { "UniqueVertexID1" => $vid1, "UniqueVertexID2" => $vid2 }; |
764
|
|
|
|
|
|
|
$intermapper->vertices($vertices); |
765
|
|
|
|
|
|
|
# At this point, there is no real reason to do this as update, create and delete work with explicit arguments. |
766
|
|
|
|
|
|
|
# But it can be done with users, devices, interfaces, maps and vertices |
767
|
|
|
|
|
|
|
# Pass a hashref to each method. This will NOT affect the smart-caching (only explicit calls to create, update and delete do this - for now). |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
=item create |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
This method created a new entry in Intermapper, depending on the argument passed. Record type is detected automatically. |
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
$intermapper->username("admin"); |
774
|
|
|
|
|
|
|
$intermapper->password("nmsadmin"); |
775
|
|
|
|
|
|
|
my $user = Net::Intermapper::User->new(Name=>"testuser", Password=>"Test12345"); |
776
|
|
|
|
|
|
|
my $response = $intermapper->create($user); |
777
|
|
|
|
|
|
|
# Error checking needs to be added |
778
|
|
|
|
|
|
|
# print $Net::Intermapper::ERROR unless $id; |
779
|
|
|
|
|
|
|
# $Net::Intermapper::ERROR contains details about failure |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
# Add more examples |
782
|
|
|
|
|
|
|
# Interfaces and maps cannot be explicitly created! |
783
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
=item update |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
This method updates an existing entry in Intermapper, depending on the argument passed. Record type is detected automatically. |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
my $user = $intermapper->users->{"testuser"}; |
789
|
|
|
|
|
|
|
$user->Password("TopSecret"); # Change password. Password policies will be enforced! |
790
|
|
|
|
|
|
|
my $response = $intermapper->update($user); |
791
|
|
|
|
|
|
|
# Error checking needs to be added |
792
|
|
|
|
|
|
|
# Update user based on Net::Intermapper::User instance |
793
|
|
|
|
|
|
|
# print $Net::Intermapper::ERROR unless $id; |
794
|
|
|
|
|
|
|
# $Net::Intermapper::ERROR contains details about failure |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
=item delete |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
This method deletes an existing entry in Intermapper, depending on the argument passed. Record type is detected automatically. |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
my $user = $intermapper->users->{"bob"}; |
801
|
|
|
|
|
|
|
my $response = $intermapper->delete($user); |
802
|
|
|
|
|
|
|
# Delete existing user |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
my $device = $intermapper->devices->{"UniqueDeviceID"}; # This key is generated by Intermapper |
805
|
|
|
|
|
|
|
$intermapper->delete($device); |
806
|
|
|
|
|
|
|
# Delete existing device |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
=item $ERROR |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
NEEDS TO BE ADDED |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
This variable will contain detailed error information. |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
=back |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
=head1 REQUIREMENTS |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
For this library to work, you need an instance with Intermapper (obviously) or a simulator like L<Net::Intermapper::Mock>. |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
=over 3 |
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
=item L<Moose> |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
=item L<IO::Socket::SSL> |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
=item L<LWP::UserAgent> |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
=item L<XML::Simple> |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
=item L<MIME::Base64> |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
=item L<URI::Escape> |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
=item L<Text::CSV_XS> |
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
=back |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
=head1 BUGS |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
None so far |
841
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
=head1 TODO |
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
=over 3 |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
=item Filtering should be added (match= keyword in Intermapper documentation) |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
=item XML input and output needs to be completed! |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
=item $ERROR variable needs to actually contain error message! |
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
=back |
853
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
=head1 SUPPORT |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
None so far :) |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
=head1 AUTHOR |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
Hendrik Van Belleghem |
861
|
|
|
|
|
|
|
CPAN ID: BEATNIK |
862
|
|
|
|
|
|
|
hendrik.vanbelleghem@gmail.com |
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
=head1 COPYRIGHT |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
This program is free software licensed under the... |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
The General Public License (GPL) |
869
|
|
|
|
|
|
|
Version 2, June 1991 |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
The full text of the license can be found in the |
872
|
|
|
|
|
|
|
LICENSE file included with this module. |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
=head1 SEE ALSO |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
L<http://download.intermapper.com/docs/UserGuide/Content/09-Reference/09-05-Advanced_Importing/the_directive_line.htm> |
878
|
|
|
|
|
|
|
L<http://download.intermapper.com/schema/imserverschema.html> |
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
=cut |
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
#################### main pod documentation end ################### |
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable(); |
885
|
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
1; |
887
|
|
|
|
|
|
|
# The preceding line will help the module return a true value |
888
|
|
|
|
|
|
|
|