File Coverage

blib/lib/Net/Cisco/ISE.pm
Criterion Covered Total %
statement 51 510 10.0
branch 0 222 0.0
condition 0 2 0.0
subroutine 16 30 53.3
pod 4 14 28.5
total 71 778 9.1


line stmt bran cond sub pod time code
1             package Net::Cisco::ISE;
2 1     1   59621 use strict;
  1         2  
  1         29  
3 1     1   382 use Moose;
  1         398573  
  1         5  
4              
5             # REST IO stuff here
6 1     1   6639 use IO::Socket::SSL qw( SSL_VERIFY_NONE );
  1         100552  
  1         12  
7 1     1   698 use LWP::UserAgent;
  1         57344  
  1         58  
8 1     1   826 use XML::Simple;
  1         7479  
  1         7  
9              
10             # Generics
11 1     1   409 use MIME::Base64;
  1         532  
  1         48  
12 1     1   6 use URI::Escape;
  1         2  
  1         43  
13 1     1   346 use Data::Dumper;
  1         4360  
  1         60  
14              
15             # Net::Cisco::ISE::*
16 1     1   359 use lib qw(.);
  1         474  
  1         5  
17 1     1   376 use Net::Cisco::ISE::InternalUser;
  1         7  
  1         87  
18 1     1   536 use Net::Cisco::ISE::IdentityGroup;
  1         3  
  1         52  
19 1     1   376 use Net::Cisco::ISE::NetworkDevice;
  1         6  
  1         87  
20 1     1   551 use Net::Cisco::ISE::NetworkDeviceGroup;
  1         3  
  1         60  
21             #use Net::Cisco::ISE::Endpoint;
22             #use Net::Cisco::ISE::EndpointCertificate;
23             #use Net::Cisco::ISE::EndpointIdentityGroup;
24             #use Net::Cisco::ISE::Portal;
25             #use Net::Cisco::ISE::Profile;
26              
27             BEGIN {
28 1     1   11 use Exporter ();
  1         3  
  1         33  
29 1     1   9 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $ERROR %actions);
  1         3  
  1         156  
30 1     1   5 $VERSION = '0.05';
31 1         24 @ISA = qw(Exporter);
32 1         4 @EXPORT = qw();
33 1         3 @EXPORT_OK = qw();
34 1         2 %EXPORT_TAGS = ();
35            
36 1         3258 $ERROR = ""; # TODO: Document error properly!
37             }
38              
39             # Moose!
40              
41             has 'ssl_options' => (
42             is => 'rw',
43             isa => 'HashRef',
44             default => sub { { 'SSL_verify_mode' => SSL_VERIFY_NONE, 'verify_hostname' => '0' } }
45             );
46              
47             has 'ssl' => (
48             is => 'rw',
49             isa => 'Str',
50             default => '1',
51             );
52              
53             has 'hostname' => (
54             is => 'rw',
55             isa => 'Str',
56             required => '1',
57             );
58              
59             has 'port' => (
60             is => 'rw',
61             isa => 'Str',
62             default => '9060'
63             );
64            
65             has 'mock' => (
66             is => 'rw',
67             isa => 'Str',
68             default => '0',
69             );
70              
71             has 'debug' => (
72             is => 'rw',
73             isa => 'Str',
74             default => '0',
75             );
76            
77             sub internalusers # No Moose here :(
78 0     0 0   { my $self = shift;
79 0           $ERROR = "";
80 0 0         if (@_)
81 0           { my %args = @_;
82 0           $self->{"InternalUsers"} = $args{"internalusers"};
83 0 0         if ($self->mock())
84 0           { return $self->{"InternalUsers"}; }
85 0 0         if ($args{"id"})
86 0           { $self->{"InternalUsers"} = $self->query("InternalUser","id",$args{"id"}); }
87             } else
88 0           { $self->{"InternalUsers"} = $self->query("InternalUser");
89             }
90 0           return $self->{"InternalUsers"};
91             }
92              
93             sub identitygroups # No Moose here :(
94 0     0 1   { my $self = shift;
95 0           $ERROR = "";
96 0 0         if (@_)
97 0           { my %args = @_;
98 0           $self->{"IdentityGroups"} = $args{"identitygroups"};
99 0 0         if ($self->mock())
100 0           { return $self->{"IdentityGroups"}; }
101 0 0         if ($args{"id"})
102 0           { $self->{"IdentityGroups"} = $self->query("IdentityGroup","id",$args{"id"}); }
103             } else
104 0           { $self->{"IdentityGroups"} = $self->query("IdentityGroup");
105             }
106 0           return $self->{"IdentityGroups"};
107             }
108              
109             sub endpointidentitygroups # No Moose here :(
110 0     0 0   { my $self = shift;
111 0           $ERROR = "";
112 0 0         if (@_)
113 0           { my %args = @_;
114 0           $self->{"EndpointIdentityGroups"} = $args{"endpointidentitygroups"};
115 0 0         if ($self->mock())
116 0           { return $self->{"EndpointIdentityGroups"}; }
117 0 0         if ($args{"id"})
118 0           { $self->{"EndpointIdentityGroups"} = $self->query("EndpointIdentityGroup","id",$args{"id"}); }
119             } else
120 0           { $self->{"EndpointIdentityGroups"} = $self->query("EndpointIdentityGroup");
121             }
122 0           return $self->{"EndpointIdentityGroups"};
123             }
124              
125             sub networkdevices # No Moose here :(
126 0     0 0   { my $self = shift;
127 0           $ERROR = "";
128 0 0         if (@_)
129 0           { my %args = @_;
130 0           $self->{"NetworkDevices"} = $args{"networkdevices"};
131 0 0         if ($self->mock())
132 0           { return $self->{"NetworkDevices"}; }
133 0 0         if ($args{"id"})
134 0           { $self->{"NetworkDevices"} = $self->query("NetworkDevice","id",$args{"id"}); }
135             } else
136 0           { $self->{"NetworkDevices"} = $self->query("NetworkDevice");
137             }
138 0           return $self->{"NetworkDevices"};
139             }
140              
141             sub networkdevicegroups # No Moose here :(
142 0     0 0   { my $self = shift;
143 0           $ERROR = "";
144 0 0         if (@_)
145 0           { my %args = @_;
146 0           $self->{"NetworkDeviceGroups"} = $args{"networkdevicegroups"};
147 0 0         if ($self->mock())
148 0           { return $self->{"NetworkDeviceGroups"}; }
149 0 0         if ($args{"id"})
150 0           { $self->{"NetworkDeviceGroups"} = $self->query("NetworkDeviceGroup","id",$args{"id"}); }
151             } else
152 0           { $self->{"NetworkDeviceGroups"} = $self->query("NetworkDeviceGroup");
153             }
154 0           return $self->{"NetworkDeviceGroups"};
155             }
156              
157             sub endpoints # No Moose here :(
158 0     0 0   { my $self = shift;
159 0           $ERROR = "";
160 0 0         if (@_)
161 0           { my %args = @_;
162 0           $self->{"Endpoints"} = $args{"endpoints"};
163 0 0         if ($self->mock())
164 0           { return $self->{"Endpoints"}; }
165 0 0         if ($args{"id"})
166 0           { $self->{"Endpoints"} = $self->query("Endpoint","id",$args{"id"}); }
167             } else
168 0           { $self->{"Endpoints"} = $self->query("Endpoint");
169             }
170 0           return $self->{"Endpoints"};
171             }
172            
173             sub endpointcertificates # No Moose here :(
174 0     0 0   { my $self = shift;
175 0           $ERROR = "";
176 0 0         if (@_)
177 0           { my %args = @_;
178 0           $self->{"EndpointCertificates"} = $args{"endpointcertificates"};
179 0 0         if ($self->mock())
180 0           { return $self->{"EndpointCertificates"}; }
181 0 0         if ($args{"id"})
182 0           { $self->{"EndpointCertificates"} = $self->query("EndpointCertificate","id",$args{"id"}); }
183             } else
184 0           { $self->{"EndpointCertificates"} = $self->query("EndpointCertificate");
185             }
186 0           return $self->{"EndpointCertificates"};
187             }
188              
189             sub portals # No Moose here :(
190 0     0 0   { my $self = shift;
191 0           $ERROR = "";
192 0 0         if (@_)
193 0           { my %args = @_;
194 0           $self->{"Portals"} = $args{"portals"};
195 0 0         if ($self->mock())
196 0           { return $self->{"Portals"}; }
197 0 0         if ($args{"id"})
198 0           { $self->{"Portals"} = $self->query("Portal","id",$args{"id"}); }
199             } else
200 0           { $self->{"Portals"} = $self->query("Portal");
201             }
202 0           return $self->{"Portals"};
203             }
204              
205             sub profiles # No Moose here :(
206 0     0 0   { my $self = shift;
207 0           $ERROR = "";
208 0 0         if (@_)
209 0           { my %args = @_;
210 0           $self->{"Profiles"} = $args{"profiles"};
211 0 0         if ($self->mock())
212 0           { return $self->{"Profiles"}; }
213 0 0         if ($args{"id"})
214 0           { $self->{"Profiles"} = $self->query("Profile","id",$args{"id"}); }
215             } else
216 0           { $self->{"Profiles"} = $self->query("Profile");
217             }
218 0           return $self->{"Profiles"};
219             }
220              
221              
222             has 'username' => (
223             is => 'rw',
224             isa => 'Str',
225             required => '1',
226             );
227              
228             has 'password' => (
229             is => 'rw',
230             isa => 'Str',
231             required => '1',
232             );
233            
234             # Non-Moose
235              
236             sub query
237 0     0 0   { my ($self, $type, $key, $value) = @_;
238 0           my $hostname = $self->hostname;
239 0           my $credentials = encode_base64($self->username.":".$self->password);
240 0 0         if ($self->ssl)
241 0           { $hostname = "https://$hostname"; } else
242 0           { $hostname = "http://$hostname"; }
243 0 0         $hostname .= ":".$self->port if $self->port;
244 0           my $action = "";
245 0           my $mode = "";
246 0           my $accepttype ="";
247 0   0       $key ||= "";
248 0 0         if ($type eq "InternalUser")
249 0           { $action = $Net::Cisco::ISE::InternalUser::actions{"query"};
250 0           $mode = "InternalUsers";
251 0           $accepttype = "identity.internaluser.1.0";
252 0 0         if ($key eq "id")
253 0           { $action = $Net::Cisco::ISE::InternalUser::actions{"getById"}.$value;
254 0           $mode = "InternalUser";
255             }
256             }
257 0 0         if ($type eq "IdentityGroup")
258 0           { $action = $Net::Cisco::ISE::IdentityGroup::actions{"query"};
259 0           $mode = "IdentityGroups";
260 0           $accepttype = "identity.identitygroup.1.0";
261 0 0         if ($key eq "id")
262 0           { $action = $Net::Cisco::ISE::IdentityGroup::actions{"getById"}.$value;
263 0           $mode = "IdentityGroup";
264             }
265             }
266              
267 0 0         if ($type eq "EndpointIdentityGroup")
268             { #$action = $Net::Cisco::ISE::EndpointIdentityGroup::actions{"query"};
269 0           $mode = "EndpointIdentityGroups";
270 0           $accepttype = "identity.endpointgroup.1.0";
271 0 0         if ($key eq "id")
272             { #$action = $Net::Cisco::ISE::EndpointIdentityGroup::actions{"getById"}.$value;
273 0           $mode = "EndpointIdentityGroup";
274             }
275             }
276 0 0         if ($type eq "NetworkDevice")
277 0           { $action = $Net::Cisco::ISE::NetworkDevice::actions{"query"};
278 0           $mode = "NetworkDevices";
279 0           $accepttype = "network.networkdevice.1.1";
280 0 0         if ($key eq "id")
281 0           { $action = $Net::Cisco::ISE::NetworkDevice::actions{"getById"}.$value;
282 0           $mode = "NetworkDevice";
283             }
284             }
285 0 0         if ($type eq "NetworkDeviceGroup")
286 0           { $action = $Net::Cisco::ISE::NetworkDeviceGroup::actions{"query"};
287 0           $mode = "NetworkDeviceGroups";
288 0           $accepttype = "network.networkdevicegroup.1.1";
289 0 0         if ($key eq "id")
290 0           { $action = $Net::Cisco::ISE::NetworkDeviceGroup::actions{"getById"}.$value;
291 0           $mode = "NetworkDeviceGroup";
292             }
293             }
294 0 0         if ($type eq "Endpoint")
295             { #$action = $Net::Cisco::ISE::Endpoint::actions{"query"};
296 0           $mode = "Endpoints";
297 0           $accepttype = "identity.endpoint.1.0";
298 0 0         if ($key eq "id")
299             { #$action = $Net::Cisco::ISE::Endpoint::actions{"getById"}.$value;
300 0           $mode = "Endpoint";
301             }
302             }
303 0 0         if ($type eq "EndpointCertificate")
304             { #$action = $Net::Cisco::ISE::EndpointCertificate::actions{"query"};
305 0           $mode = "EndpointCertificates";
306 0           $accepttype = "ca.endpointcert.1.0";
307 0 0         if ($key eq "id")
308             { #$action = $Net::Cisco::ISE::EndpointCertificate::actions{"getById"}.$value;
309 0           $mode = "EndpointCertificate";
310             }
311             }
312              
313 0 0         if ($type eq "Portal")
314             { #$action = $Net::Cisco::ISE::Portal::actions{"query"};
315 0           $mode = "Portals";
316 0           $accepttype = "identity.portal.1.0";
317 0 0         if ($key eq "id")
318             { #$action = $Net::Cisco::ISE::Portal::actions{"getById"}.$value;
319 0           $mode = "Portal";
320             }
321             }
322 0 0         if ($type eq "Profile")
323             { #$action = $Net::Cisco::ISE::Profile::actions{"query"};
324 0           $mode = "Profiles";
325 0           $accepttype = "identity.profilerprofile.1.0";
326 0 0         if ($key eq "id")
327             { #$action = $Net::Cisco::ISE::Profile::actions{"getById"}.$value;
328 0           $mode = "Profile";
329             }
330             }
331              
332 0           $hostname = $hostname . $action;
333 0           my $useragent = LWP::UserAgent->new (ssl_opts => $self->ssl_options);
334 0           my $request = HTTP::Request->new(GET => $hostname );
335 0           $request->header('Authorization' => "Basic $credentials", Accept => "application/vnd.com.cisco.ise.$accepttype+xml");
336 0           my $result = $useragent->request($request);
337 0 0         if ($result->code eq "400") { $ERROR = "Bad Request - HTTP Status: 400"; }
  0            
338 0 0         if ($result->code eq "410") { $ERROR = "Unknown $type queried by name or ID - HTTP Status: 410"; }
  0            
339 0 0         warn Dumper $result->content if $self->debug;
340 0           $result = $self->parse_xml($mode, $result->content);
341 0 0         warn Dumper $result if $self->debug;
342 0           return $result;
343             }
344              
345             sub create
346 0     0 1   { my $self = shift;
347 0           my $record = shift;
348 0 0         return unless $record;
349 0           my $hostname = $self->hostname;
350 0           my $credentials = encode_base64($self->username.":".$self->password);
351 0 0         if ($self->ssl)
352 0           { $hostname = "https://$hostname"; } else
353 0           { $hostname = "http://$hostname"; }
354 0 0         $hostname .= ":".$self->port if $self->port;
355 0           my $action = "";
356 0           my $data = "";
357 0           my $accepttype = "";
358 0 0         if (ref($record) eq "Net::Cisco::ISE::InternalUser")
359 0           { $action = $Net::Cisco::ISE::InternalUser::actions{"create"};
360 0           $accepttype = "identity.internaluser.1.0";
361             }
362              
363 0 0         if (ref($record) eq "Net::Cisco::ISE::IdentityGroup")
364             { #$action = $Net::Cisco::ISE::IdentityGroup::actions{"create"};
365             #$accepttype = "identity.identitygroup.1.0";
366             # ISE does not support creating Identity Groups through the API. No idea why this is!
367             }
368              
369 0 0         if (ref($record) eq "Net::Cisco::ISE::NetworkDevice")
370 0           { $action = $Net::Cisco::ISE::NetworkDevice::actions{"create"};
371 0           $accepttype = "network.networkdevice.1.1";
372             }
373            
374 0 0         if (ref($record) eq "Net::Cisco::ISE::NetworkDeviceGroup")
375 0           { $action = $Net::Cisco::ISE::NetworkDeviceGroup::actions{"create"};
376 0           $accepttype = "network.networkdevicegroup.1.1";
377             }
378              
379 0 0         if (ref($record) eq "Net::Cisco::ISE::Endpoint")
380             { #$action = $Net::Cisco::ISE::Endpoint::actions{"create"};
381 0           $accepttype = "identity.endpoint.1.0";
382             }
383 0 0         if (ref($record) eq "Net::Cisco::ISE::EndpointCertificate")
384             { #$action = $Net::Cisco::ISE::EndpointCertificate::actions{"create"};
385 0           $accepttype = "ca.endpointcert.1.0";
386             }
387 0 0         if (ref($record) eq "Net::Cisco::ISE::EndpointIdentityGroup")
388             { #$action = $Net::Cisco::ISE::EndpointIdentityGroup::actions{"create"};
389 0           $accepttype = "identity.endpointgroup.1.0";
390             }
391 0 0         if (ref($record) eq "Net::Cisco::ISE::Portal")
392             { #$action = $Net::Cisco::ISE::Portal::actions{"create"};
393 0           $accepttype = "identity.portal.1.0";
394             }
395 0 0         if (ref($record) eq "Net::Cisco::ISE::Profile")
396             { #$action = $Net::Cisco::ISE::Profile::actions{"create"};
397 0           $accepttype = "identity.profilerprofile.1.0";
398             }
399              
400 0           $data .= $record->toXML;
401 0           $data = $record->header($data,$record);
402 0           $hostname = $hostname . $action;
403 0           my $useragent = LWP::UserAgent->new (ssl_opts => $self->ssl_options);
404 0           my $request = HTTP::Request->new(POST => $hostname );
405 0           $request->content_type("application/xml");
406 0           $request->header("Authorization" => "Basic $credentials", "Content-Type" => "application/vnd.com.cisco.ise.$accepttype+xml; charset=utf-8", Accept => "application/vnd.com.cisco.ise.$accepttype+xml");
407 0           $request->content($data);
408 0           my $result = $useragent->request($request);
409 0           my $id = "";
410 0 0         if ($result->code ne "201")
411 0           { my $result_ref = $self->parse_xml("messages", $result->content);
412 0           $ERROR = $result_ref->{"messages"}{"message"}{"type"}.":".$result_ref->{"messages"}{"message"}{"code"}." - ".$result_ref->{"messages"}{"message"}{"title"}." "." - HTTP Status: ".$result->code;
413             } else
414 0           { my $location = $result->header("location");
415 0           ($id) = $location =~ /^.*\/([^\/]*)$/;
416             }
417 0           return $id;
418             }
419              
420             sub update
421 0     0 1   { my $self = shift;
422 0           my $record = shift;
423 0 0         return unless $record;
424 0           my $hostname = $self->hostname;
425 0           my $credentials = encode_base64($self->username.":".$self->password);
426 0 0         if ($self->ssl)
427 0           { $hostname = "https://$hostname"; } else
428 0           { $hostname = "http://$hostname"; }
429 0 0         $hostname .= ":".$self->port if $self->port;
430 0           my $action = "";
431 0           my $data = "";
432 0           my $accepttype = "";
433 0 0         if (ref($record) eq "Net::Cisco::ISE::InternalUser")
434 0           { $action = $Net::Cisco::ISE::InternalUser::actions{"update"};
435 0           $accepttype = "identity.internaluser.1.0";
436             }
437              
438 0 0         if (ref($record) eq "Net::Cisco::ISE::IdentityGroup")
439 0           { $action = $Net::Cisco::ISE::IdentityGroup::actions{"update"};
440 0           $accepttype = "identity.identitygroup.1.0";
441             }
442              
443 0 0         if (ref($record) eq "Net::Cisco::ISE::NetworkDevice")
444 0           { $action = $Net::Cisco::ISE::NetworkDevice::actions{"update"};
445 0           $accepttype = "network.networkdevice.1.1";
446             }
447            
448 0 0         if (ref($record) eq "Net::Cisco::ISE::NetworkDeviceGroup")
449 0           { $action = $Net::Cisco::ISE::NetworkDeviceGroup::actions{"update"};
450 0           $accepttype = "network.networkdevicegroup.1.1";
451             }
452              
453 0 0         if (ref($record) eq "Net::Cisco::ISE::Endpoint")
454             { #$action = $Net::Cisco::ISE::Endpoint::actions{"update"};
455 0           $accepttype = "identity.endpoint.1.0";
456             }
457              
458 0 0         if (ref($record) eq "Net::Cisco::ISE::EndpointCertificate")
459             { #$action = $Net::Cisco::ISE::EndpointCertificate::actions{"update"};
460 0           $accepttype = "ca.endpointcert.1.0";
461             }
462              
463 0 0         if (ref($record) eq "Net::Cisco::ISE::EndpointIdentityGroup")
464             { #$action = $Net::Cisco::ISE::EndpointIdentityGroup::actions{"update"};
465 0           $accepttype = "identity.endpointgroup.1.0";
466             }
467              
468 0 0         if (ref($record) eq "Net::Cisco::ISE::Portal")
469             { #$action = $Net::Cisco::ISE::Portal::actions{"update"};
470 0           $accepttype = "identity.portal.1.0";
471             }
472              
473 0 0         if (ref($record) eq "Net::Cisco::ISE::Profile")
474             { #$action = $Net::Cisco::ISE::Profile::actions{"update"};
475 0           $accepttype = "identity.profilerprofile.1.0";
476             }
477              
478 0           $data .= $record->toXML;
479              
480 0           $data = $record->header($data, $record);
481 0           $hostname = $hostname . $action.$record->id;
482 0           my $useragent = LWP::UserAgent->new (ssl_opts => $self->ssl_options);
483 0           my $request = HTTP::Request->new(PUT => $hostname );
484 0           $request->content_type("application/xml");
485 0           $request->header("Authorization" => "Basic $credentials", "Content-Type" => "application/vnd.com.cisco.ise.$accepttype+xml");
486 0           $request->content($data);
487 0 0         warn Dumper $request if $self->debug;
488 0           my $result = $useragent->request($request);
489 0           my $id = "";
490 0 0         if ($result->code ne "200")
491 0           { my $result_ref = $self->parse_xml("messages", $result->content);
492 0           $ERROR = $result_ref->{"messages"}{"message"}{"type"}.":".$result_ref->{"messages"}{"message"}{"code"}." - ".$result_ref->{"messages"}{"message"}{"title"}." "." - HTTP Status: ".$result->code;
493             } else
494 0           { my $location = $result->header("location");
495 0           ($id) = $location =~ /^.*\/([^\/]*)$/;
496             }
497 0           return $id;
498             }
499              
500             sub delete
501 0     0 1   { my $self = shift;
502 0           my $record = shift;
503 0           my $hostname = $self->hostname;
504 0           my $credentials = encode_base64($self->username.":".$self->password);
505 0 0         if ($self->ssl)
506 0           { $hostname = "https://$hostname"; } else
507 0           { $hostname = "http://$hostname"; }
508 0 0         $hostname .= ":".$self->port if $self->port;
509 0           my $action = "";
510 0           my $type = "";
511 0           my $accepttype = "";
512            
513 0 0         if (ref($record) eq "ARRAY") { $record = $record->[0]; }
  0            
514 0 0         if (ref($record) eq "Net::Cisco::ISE::InternalUser")
515 0           { $action = $Net::Cisco::ISE::InternalUser::actions{"getById"};
516 0           $type = "InternalUser";
517 0           $accepttype = "identity.internaluser.1.0";
518             }
519              
520 0 0         if (ref($record) eq "Net::Cisco::ISE::IdentityGroup")
521 0           { $action = $Net::Cisco::ISE::IdentityGroup::actions{"getById"};
522 0           $type = "IdentityGroup";
523 0           $accepttype = "identity.identitygroup.1.0";
524             }
525              
526 0 0         if (ref($record) eq "Net::Cisco::ISE::NetworkDevice")
527 0           { $action = $Net::Cisco::ISE::NetworkDevice::actions{"getById"};
528 0           $type = "NetworkDevice";
529 0           $accepttype = "network.networkdevice.1.1";
530             }
531            
532 0 0         if (ref($record) eq "Net::Cisco::ISE::NetworkDeviceGroup")
533 0           { $action = $Net::Cisco::ISE::NetworkDeviceGroup::actions{"getById"};
534 0           $type = "NetworkDeviceGroup";
535 0           $accepttype = "network.networkdevicegroup.1.1";
536             }
537              
538 0 0         if (ref($record) eq "Net::Cisco::ISE::Endpoint")
539             { #$action = $Net::Cisco::ISE::Endpoint::actions{"getById"};
540 0           $type = "Endpoint";
541 0           $accepttype = "identity.endpoint.1.0";
542             }
543              
544             # Not sure Endpoint Certificates can be deleted
545 0 0         if (ref($record) eq "Net::Cisco::ISE::EndpointCertificate")
546             { #$action = $Net::Cisco::ISE::EndpointCertificate::actions{"getById"};
547 0           $type = "EndpointCertificate";
548 0           $accepttype = "ca.endpointcert.1.0";
549             }
550              
551 0 0         if (ref($record) eq "Net::Cisco::ISE::EndpointIdentityGroup")
552             { #$action = $Net::Cisco::ISE::EndpointIdentityGroup::actions{"getById"};
553 0           $type = "EndpointIdentityGroup";
554 0           $accepttype = "identity.endpointgroup.1.0";
555             }
556              
557 0 0         if (ref($record) eq "Net::Cisco::ISE::Portal")
558             { #$action = $Net::Cisco::ISE::Portal::actions{"getById"};
559 0           $type = "Portal";
560 0           $accepttype = "identity.portal.1.0";
561             }
562              
563 0 0         if (ref($record) eq "Net::Cisco::ISE::Profile")
564             { #$action = $Net::Cisco::ISE::Profile::actions{"getById"};
565 0           $type = "Profile";
566 0           $accepttype = "identity.profilerprofile.1.0";
567             }
568              
569            
570 0           $hostname = $hostname . $action.$record->id;
571 0           my $useragent = LWP::UserAgent->new (ssl_opts => $self->ssl_options);
572 0           my $request = HTTP::Request->new(DELETE => $hostname );
573 0           $request->content_type("application/xml");
574 0           $request->header("Authorization" => "Basic $credentials", Accept => "application/vnd.com.cisco.ise.$accepttype+xml");
575 0           my $result = $useragent->request($request);
576 0           my $id = "";
577 0 0         if ($result->code ne "204")
578 0           { $ERROR = $result->{"code"};
579             }
580             }
581              
582             sub parse_xml
583 0     0 0   { my $self = shift;
584 0           my $type = shift;
585 0           my $xml_ref = shift;
586 0           my $xmlsimple = XML::Simple->new(SuppressEmpty => 1);
587 0           my $xmlout = $xmlsimple->XMLin($xml_ref);
588 0 0         if ($type eq "InternalUsers")
589             { #my $users_ref = $xmlout->{"InternalUser"};
590 0           my $users_ref = $xmlout->{"resources"}{"resource"};
591 0           my %users = ();
592 0           for my $key (keys % {$users_ref})
  0            
593 0           { my $user = Net::Cisco::ISE::InternalUser->new( name => $key, %{ $users_ref->{$key} } );
  0            
594 0           $users{$key} = $user;
595             }
596 0           $self->{"InternalUsers"} = \%users;
597 0           return $self->{"InternalUsers"};
598             }
599 0 0         if ($type eq "InternalUser") # userByName and userById DO NOT return hash but a single instance of Net::Cisco::ISE::InternalUser
600 0           { my %user_hash = %{ $xmlout };
  0            
601 0           my $user = Net::Cisco::ISE::InternalUser->new( %user_hash );
602 0           $self->{"InternalUsers"} = $user ;
603 0           return $self->{"InternalUsers"};
604             }
605              
606 0 0         if ($type eq "IdentityGroups")
607 0           { my $identitygroups_ref = $xmlout->{"resources"}{"resource"};
608 0           my %identitygroups = ();
609             # With Single entry, this approach will break!!!
610             # !!BUG!!
611 0           for my $key (keys % {$identitygroups_ref})
  0            
612 0           { my $identitygroup = Net::Cisco::ISE::IdentityGroup->new( name => $key, %{ $identitygroups_ref->{$key} } );
  0            
613 0           $identitygroups{$key} = $identitygroup;
614             }
615 0           $self->{"IdentityGroups"} = \%identitygroups;
616 0           return $self->{"IdentityGroups"};
617             }
618 0 0         if ($type eq "IdentityGroup") # ByName and ById DO NOT return hash but a single instance of Net::Cisco::ISE::IdentityGroup
619 0           { my %identitygroup_hash = %{ $xmlout };
  0            
620 0           my $identitygroup = Net::Cisco::ISE::IdentityGroup->new( %identitygroup_hash );
621 0           $self->{"IdentityGroups"} = $identitygroup;
622 0           return $self->{"IdentityGroups"};
623             }
624            
625 0 0         if ($type eq "NetworkDevices")
626 0           { my $device_ref = $xmlout->{"resources"}{"resource"};
627 0           my %devices = ();
628 0           for my $key (keys % {$device_ref})
  0            
629 0           { my $device = Net::Cisco::ISE::NetworkDevice->new( name => $key, id => $device_ref->{$key}{"id"} );
630 0           $devices{$key} = $device;
631             }
632 0           $self->{"NetworkDevices"} = \%devices;
633 0           return $self->{"NetworkDevices"};
634             }
635 0 0         if ($type eq "NetworkDevice") # deviceByName and deviceById DO NOT return hash but a single instance of Net::Cisco::ISE::NetworkDevice
636 0           { my %device_hash = %{ $xmlout };
  0            
637 0           my $device = Net::Cisco::ISE::NetworkDevice->new( %device_hash );
638 0           $self->{"NetworkDevices"} = $device;
639 0           return $self->{"NetworkDevices"};
640             }
641              
642 0 0         if ($type eq "NetworkDeviceGroups")
643 0           { my $devicegroup_ref = $xmlout->{"resources"}{"resource"};
644 0           my %devicegroups = ();
645 0           for my $key (keys % {$devicegroup_ref})
  0            
646 0           { my $devicegroup = Net::Cisco::ISE::NetworkDeviceGroup->new( name => $key, %{ $devicegroup_ref->{$key} } );
  0            
647 0           $devicegroups{$key} = $devicegroup;
648             }
649 0           $self->{"NetworkDeviceGroups"} = \%devicegroups;
650 0           return $self->{"NetworkDeviceGroups"};
651             }
652 0 0         if ($type eq "NetworkDeviceGroup") # deviceGroupByName and deviceGroupById DO NOT return hash but a single instance of Net::Cisco::ISE::NetworkDeviceGroup
653 0           { my %devicegroup_hash = %{ $xmlout };
  0            
654 0           my $devicegroup = Net::Cisco::ISE::NetworkDeviceGroup->new( %devicegroup_hash );
655 0           $self->{"NetworkDeviceGroups"} = $devicegroup;
656 0           return $self->{"NetworkDeviceGroups"};
657             }
658            
659 0 0         if ($type eq "Endpoints")
660 0           { my $host_ref = $xmlout->{"resources"}{"resource"};
661 0           my %hosts = ();
662 0           for my $key (keys % {$host_ref})
  0            
663             { #my $host = Net::Cisco::ISE::Endpoint->new( macAddress => $key, %{ $host_ref->{$key} } );
664             #$hosts{$key} = $host;
665             }
666 0           $self->{"Endpoints"} = \%hosts;
667 0           return $self->{"Endpoints"};
668             }
669 0 0         if ($type eq "Endpoint") # ByName and ById DO NOT return hash but a single instance of Net::Cisco::ISE::Endpoint
670 0           { my %host_hash = %{ $xmlout };
  0            
671             #my $host = Net::Cisco::ISE::Endpoint->new( %host_hash );
672             #$self->{"Endpoints"} = $host;
673 0           return $self->{"Endpoints"};
674             }
675            
676 0 0         if ($type eq "EndpointCertificates")
677 0           { my $host_ref = $xmlout->{"resources"}{"resource"};
678 0           my %hosts = ();
679 0           for my $key (keys % {$host_ref})
  0            
680             { #my $host = Net::Cisco::ISE::EndpointCertificate->new( name => $key, %{ $host_ref->{$key} } );
681             #$hosts{$key} = $host;
682             }
683 0           $self->{"EndpointCertificates"} = \%hosts;
684 0           return $self->{"EndpointCertificates"};
685             }
686 0 0         if ($type eq "EndpointCertificate") # ByName and ById DO NOT return hash but a single instance of Net::Cisco::ISE::Endpoint
687 0           { my %host_hash = %{ $xmlout };
  0            
688             #my $host = Net::Cisco::ISE::EndpointCertificate->new( %host_hash );
689             #$self->{"EndpointCertificates"} = $host;
690 0           return $self->{"EndpointCertificates"};
691             }
692              
693 0 0         if ($type eq "EndpointIdentityGroups")
694 0           { my $host_ref = $xmlout->{"resources"}{"resource"};
695 0           my %hosts = ();
696 0           for my $key (keys % {$host_ref})
  0            
697             { #my $host = Net::Cisco::ISE::EndpointIdentityGroup->new( name => $key, %{ $host_ref->{$key} } );
698             #$hosts{$key} = $host;
699             }
700 0           $self->{"EndpointIdentityGroups"} = \%hosts;
701 0           return $self->{"EndpointIdentityGroups"};
702             }
703 0 0         if ($type eq "EndpointIdentityGroup") # ByName and ById DO NOT return hash but a single instance of Net::Cisco::ISE::Endpoint
704 0           { my %host_hash = %{ $xmlout };
  0            
705             #my $host = Net::Cisco::ISE::EndpointIdentityGroup->new( %host_hash );
706             #$self->{"EndpointIdentityGroups"} = $host;
707 0           return $self->{"EndpointIdentityGroups"};
708             }
709              
710 0 0         if ($type eq "Portals")
711 0           { my $host_ref = $xmlout->{"resources"}{"resource"};
712 0           my %hosts = ();
713 0           for my $key (keys % {$host_ref})
  0            
714             { #my $host = Net::Cisco::ISE::Portal->new( name => $key, %{ $host_ref->{$key} } );
715             #$hosts{$key} = $host;
716             }
717 0           $self->{"Portals"} = \%hosts;
718 0           return $self->{"Portals"};
719             }
720 0 0         if ($type eq "Portal") # ByName and ById DO NOT return hash but a single instance of Net::Cisco::ISE::Endpoint
721 0           { my %host_hash = %{ $xmlout };
  0            
722             #my $host = Net::Cisco::ISE::Portal->new( %host_hash );
723             #$self->{"Portals"} = $host;
724 0           return $self->{"Portals"};
725             }
726              
727 0 0         if ($type eq "Profiles")
728 0           { my $host_ref = $xmlout->{"resources"}{"resource"};
729 0           my %hosts = ();
730 0           for my $key (keys % {$host_ref})
  0            
731             { #my $host = Net::Cisco::ISE::Profile->new( name => $key, %{ $host_ref->{$key} } );
732             #$hosts{$key} = $host;
733             }
734 0           $self->{"Profiles"} = \%hosts;
735 0           return $self->{"Profiles"};
736             }
737 0 0         if ($type eq "Profile") # ByName and ById DO NOT return hash but a single instance of Net::Cisco::ISE::Endpoint
738 0           { my %host_hash = %{ $xmlout };
  0            
739             #my $host = Net::Cisco::ISE::Profile->new( %host_hash );
740             #$self->{"Profiles"} = $host;
741 0           return $self->{"Profiles"};
742             }
743              
744 0 0         if ($type eq "result")
745 0           { my %result_hash = %{ $xmlout };
  0            
746 0           return \%result_hash;
747             }
748 0 0         if ($type eq "messages")
749 0           { my %result_hash = %{ $xmlout };
  0            
750 0           return \%result_hash;
751             }
752             }
753              
754             =head1 NAME
755              
756             Net::Cisco::ISE - Access Cisco ISE functionality through REST API
757              
758             =head1 SYNOPSIS
759              
760             use Net::Cisco::ISE;
761             my $ise = Net::Cisco::ISE->new(hostname => '10.0.0.1', username => 'admin', password => 'testPassword');
762             # Options:
763             # hostname - IP or hostname of Cisco ISE 5.x server
764             # username - Username of Administrator user
765             # password - Password of user
766             # port - TCP port 9060 by default
767             # ssl - SSL enabled (1 - default) or disabled (0)
768            
769             my %users = $ise->internalusers;
770             # Retrieve all users from ISE
771             # Returns hash with username / Net::Cisco::ISE::InternalUser pairs
772            
773             print $ise->internalusers->{"admin"}->toXML;
774             # Dump in XML format (used by ISE for API calls)
775            
776             my $user = $ise->internalusers("name","admin");
777             # Faster call to request specific user information by name
778              
779             my $user = $ise->internalusers("id","b74a0ef2-b29c-40e3-a0d1-4c0dfb51ace9");
780             # Faster call to request specific user information by ID (assigned by ISE, present in Net::Cisco::ISE::InternalUser)
781              
782             my %identitygroups = $ise->identitygroups;
783             # Retrieve all identitygroups from ISE
784             # Returns hash with name / Net::Cisco::ISE::IdentityGroup pairs
785            
786             print $ise->identitygroups->{"All Groups"}->toXML;
787             # Dump in XML format (used by ISE for API calls)
788            
789             my $identitygroup = $ise->identitygroups("name","All Groups");
790             # Faster call to request specific identity group information by name
791              
792             my $identitygroup = $ise->identitygroups("id","4fffc260-9b96-11e6-93fb-005056ad1454");
793             # Faster call to request specific identity group information by ID (assigned by ISE, present in Net::Cisco::ISE::IdentityGroup)
794              
795             my $device = $acs->networkdevices("name","MAIN_Router");
796             # Faster call to request specific device information by name
797              
798             my $device = $acs->networkdevices("id","250");
799             # Faster call to request specific device information by ID (assigned by ISE, present in Net::Cisco::ISE::NetworkDevice)
800            
801             $user->id(0); # Required for new user!
802             my $id = $ise->create($user);
803             # Create new user based on Net::Cisco::ISE::InternalUser instance
804             # Return value is ID generated by ISE
805             print "Record ID is $id" if $id;
806             print $Net::Cisco::ISE::ERROR unless $id;
807             # $Net::Cisco::ISE::ERROR contains details about failure
808              
809             my $id = $ise->create(@users); # Still requires nullified ID!
810             # Create new users based on Net::Cisco::ISE::InternalUser instances in arguments
811             # Return value is not guaranteed in this case!
812             # print "Record ID is $id" if $id;
813             # print $Net::Cisco::ISE::ERROR unless $id;
814             # $Net::Cisco::ISE::ERROR contains details about failure
815            
816             $identitygroup->id(0); # Required for new record!
817             my $id = $ise->create($identitygroup);
818             # Create new identity group based on Net::Cisco::ISE::IdentityGroup instance
819             # Return value is ID generated by ISE
820             print "Record ID is $id" if $id;
821             print $Net::Cisco::ISE::ERROR unless $id;
822             # $Net::Cisco::ISE::ERROR contains details about failure
823              
824             # Cisco ISE does not support modifying an identity group through the API
825            
826             my $id = $ise->update($user);
827             # Update existing user based on Net::Cisco::ISE::InternalUser instance
828             # Return value is ID generated by ISE
829             print "Record ID is $id" if $id;
830             print $Net::Cisco::ISE::ERROR unless $id;
831             # $Net::Cisco::ISE::ERROR contains details about failure
832              
833             my $id = $ise->update(@users);
834             # Update existing users based on Net::Cisco::ISE::InternalUser instances in arguments
835             # Return value is not guaranteed in this case!
836             # print "Record ID is $id" if $id;
837             # print $Net::Cisco::ISE::ERROR unless $id;
838             # $Net::Cisco::ISE::ERROR contains details about failure
839            
840             $ise->delete($user);
841             # Delete existing user based on Net::Cisco::ISE::InternalUser instance
842            
843             =head1 DESCRIPTION
844              
845             Net::Cisco::ISE is an implementation of the Cisco Identity Services Engine (ISE) REST API. Cisco ISE is a application / appliance that can be used for network access policy control. In short, it allows configuration of access policies for specific users onto specific devices and applications (either using RADIUS or TACACS+ authentication). Net::Cisco::ISE currently supports InternalUser and IdentityGroup.
846              
847             =head1 USAGE
848              
849             All calls are handled through an instance of the L<Net::Cisco::ISE> class.
850              
851             use Net::Cisco::ISE;
852             my $ise = Net::Cisco::ISE->new(hostname => '10.0.0.1', username => 'admin', password => 'testPassword');
853              
854             =over 3
855              
856             =item new
857              
858             Class constructor. Returns object of Net::Cisco::ISE on succes. Required fields are:
859              
860             =over 5
861              
862             =item hostname
863              
864             =item username
865              
866             =item password
867              
868             =back
869              
870             Optional fields are
871              
872             =over 5
873              
874             =item ssl
875              
876             =item ssl_options
877              
878             =back
879              
880             =item hostname
881              
882             IP or hostname of Cisco ISE 2.x server. This is a required value in the constructor but can be redefined afterwards.
883              
884             =item username
885              
886             Username of Administrator user. This is a required value in the constructor but can be redefined afterwards.
887              
888             =item password
889              
890             Password of user. This is a required value in the constructor but can be redefined afterwards.
891              
892             =item ssl
893              
894             SSL enabled (1 - default) or disabled (0).
895              
896             =item ssl_options
897              
898             Value is passed directly to LWP::UserAGent as ssl_opt. Default value (hash-ref) is
899              
900             { 'SSL_verify_mode' => SSL_VERIFY_NONE, 'verify_hostname' => '0' }
901              
902             =back
903              
904             From the class instance, call the different methods for retrieving values.
905              
906             =over 3
907              
908             =item users
909              
910             Returns hash or single instance, depending on context.
911              
912             my %users = $ise->internalusers(); # Slow
913             my $user = $ise->internalusers()->{"admin"};
914             print $user->name;
915            
916             The returned hash contains instances of L<Net::Cisco::ISE::InternalUser>, using name (typically the username) as the hash key. Using a call to C<users> with no arguments will retrieve all users and can take quite a few seconds (depending on the size of your database). When you know the username or ID, use the L<users> call with arguments as listed below.
917            
918             my $user = $ise->internalusers("name","admin"); # Faster
919             # or
920             my $user = $ise->internalusers("id","b74a0ef2-b29c-40e3-a0d1-4c0dfb51ace9"); # Faster
921             print $user->name;
922              
923             The ID is typically generated by Cisco ISE when the entry is created. It can be retrieved by calling the C<id> method on the object.
924              
925             print $user->id;
926              
927             =item identitygroups
928              
929             Returns hash or single instance, depending on context.
930              
931             my %identitygroups = $ise->identitygroups(); # Slow
932             my $identitygroup = $ise->identitygroups()->{"All Groups"};
933             print $identitgroup->name;
934            
935             The returned hash contains instances of L<Net::Cisco::ISE::IdentityGroup>, using name (typically the username) as the hash key. Using a call to C<identitygroup> with no arguments will retrieve all identitygroups and can take quite a few seconds (depending on the size of your database). When you know the group name or ID, use the L<identitygroups> call with arguments as listed below.
936            
937             my $identitygroup = $ise->identitygroups("name","All Groups"); # Faster
938             # or
939             my $identitygroup = $ise->identitygroups("id","4fffc260-9b96-11e6-93fb-005056ad1454"); # Faster
940             print $identitygroup->name;
941              
942             The ID is typically generated by Cisco ISE when the entry is created. It can be retrieved by calling the C<id> method on the object.
943              
944             print $identitygroup->id;
945            
946             =item devices
947              
948             Returns hash or single instance, depending on context.
949              
950             my %devices = $acs->networkdevices(); # Slow
951             my $device = $acs->networkdevices()->{"Main_Router"};
952             print $device->name;
953            
954             The returned hash contains instances of L<Net::Cisco::ISE::NetworkDevice>, using name (typically the sysname) as the hash key. Using a call to C<device> with no arguments will retrieve all devices and can take quite a few seconds (depending on the size of your database). When you know the hostname or ID, use the L<devices> call with arguments as listed below.
955            
956             my $device = $acs->device("name","Main_Router"); # Faster
957             # or
958             my $device = $acs->device("id","123"); # Faster
959             print $device->name;
960              
961             The ID is typically generated by Cisco ISE when the entry is created. It can be retrieved by calling the C<id> method on the object.
962              
963             print $device->id;
964              
965             =item devicegroups
966              
967             Returns hash or single instance, depending on context.
968              
969             my %devicegroups = $acs->networkdevicegroups(); # Slow
970             my $devicegroup = $acs->networkdevicegroups()->{"All Locations:Main Site"};
971             print $devicegroup->name;
972              
973             The returned hash contains instances of L<Net::Cisco::ISE::NetworkDeviceGroup>, using name (typically the device group name) as the hash key. Using a call to C<devicegroups> with no arguments will retrieve all device groups and can take quite a few seconds (depending on the size of your database). When you know the device group or ID, use the L<devicegroups> call with arguments as listed below.
974            
975             my $devicegroup = $acs->networkdevicegroups("name","All Locations::Main Site"); # Faster
976             # or
977             my $devicegroup = $acs->networkdevicegroups("id","123"); # Faster
978             print $devicegroup->name;
979              
980             The ID is typically generated by Cisco ISE when the entry is created. It can be retrieved by calling the C<id> method on the object.
981              
982             print $devicegroup->id;
983              
984             =item create
985              
986             This method created a new entry in Cisco ISE, depending on the argument passed. Record type is detected automatically. For all record types, the ID value must be set to 0.
987              
988             my $user = $ise->internalusers("name","admin");
989             $user->id(0); # Required for new user!
990             $user->name("altadmin"); # Required field
991             $user->password("TopSecret"); # Password policies will be enforced!
992             $user->description("Alternate Admin");
993             my $id = $ise->create($user);
994             # Create new user based on Net::Cisco::ISE::InternalUser instance
995             # Return value is ID generated by ISE
996             print "Record ID is $id" if $id;
997             print $Net::Cisco::ISE::ERROR unless $id;
998             # $Net::Cisco::ISE::ERROR contains details about failure
999              
1000             my $device = $acs->networkdevices("name","Main_Router");
1001             $device->name("AltRouter"); # Required field
1002             $device->description("Standby Router");
1003             $device->ips([{netMask => "32", ipAddress=>"10.0.0.2"}]); # Change IP address! Overlap check is enforced!
1004             $device->id(0); # Required for new device!
1005             my $id = $acs->create($device);
1006             # Create new device based on Net::Cisco::ISE::NetworkDevice instance
1007             # Return value is ID generated by ISE
1008             print "Record ID is $id" if $id;
1009             print $Net::Cisco::ISE::ERROR unless $id;
1010             # $Net::Cisco::ISE::ERROR contains details about failure
1011              
1012             Multiple instances can be passed as an argument. Objects will be created in bulk (one transaction). The returned ID is not guaranteed to be the IDs of the created objects.
1013              
1014             my $user = $ise->internalusers("name","admin");
1015             $user->id(0); # Required for new user!
1016             $user->name("altadmin"); # Required field
1017             $user->password("TopSecret"); # Password policies will be enforced!
1018             $user->description("Alternate Admin");
1019              
1020             my $user2 = $ise->internalusers("name","admin");
1021             $user2->id(0); # Required for new user!
1022             $user2->name("altadmin"); # Required field
1023             $user2->password("TopSecret"); # Password policies will be enforced!
1024             $user2->description("Alternate Admin");
1025              
1026             my $id = $ise->create($user,$user2);
1027             # Create new users based on Net::Cisco::ISE::InternalUser instances in argument.
1028             # Return value is ID generated by ISE but not guaranteed.
1029             # print "Record ID is $id" if $id;
1030             # print $Net::Cisco::ISE::ERROR unless $id;
1031             # $Net::Cisco::ISE::ERROR contains details about failure
1032            
1033             =item update
1034              
1035             This method updates an existing entry in Cisco ISE, depending on the argument passed. Record type is detected automatically.
1036              
1037             my $user = $ise->internalusers("name","admin");
1038             $user->password("TopSecret"); # Change password. Password policies will be enforced!
1039             my $id = $ise->update($user);
1040             # Update user based on Net::Cisco::ISE::InternalUser instance
1041             # Return value is ID generated by ISE
1042             print "Record ID is $id" if $id;
1043             print $Net::Cisco::ISE::ERROR unless $id;
1044             # $Net::Cisco::ISE::ERROR contains details about failure
1045              
1046             my $device = $acs->networkdevices("name","Main_Router");
1047             $user->description("To be ceased"); # Change description
1048             $device->ips([{netMask => "32", ipAddress=>"10.0.0.2"}]); # or Change IP address. Overlap check is enforced!
1049             my $id = $acs->update($device);
1050             # Create new device based on Net::Cisco::ISE::NetworkDevice instance
1051             # Return value is ID generated by ISE
1052             print "Record ID is $id" if $id;
1053             print $Net::Cisco::ISE::ERROR unless $id;
1054             # $Net::Cisco::ISE::ERROR contains details about failure
1055              
1056             Multiple instances can be passed as an argument. Objects will be updated in bulk (one transaction). The returned ID is not guaranteed to be the IDs of the created objects.
1057              
1058             my $user = $ise->internalusers("name","admin");
1059             $user->id(0); # Required for new user!
1060             $user->password("TopSecret"); # Password policies will be enforced!
1061              
1062             my $user2 = $ise->internalusers("name","admin2");
1063             $user2->password("TopSecret"); # Password policies will be enforced!
1064              
1065             my $id = $ise->update($user,$user2);
1066             # Update users based on Net::Cisco::ISE::InternalUser instances in arguments
1067             # Return value is ID generated by ISE but not guaranteed.
1068             # print "Record ID is $id" if $id;
1069             # print $Net::Cisco::ISE::ERROR unless $id;
1070             # $Net::Cisco::ISE::ERROR contains details about failure
1071              
1072             my $device = $acs->networkdevices("name","Main_Router");
1073             $device->description("Main Router");
1074             $device->ips([{netMask => "32", ipAddress=>"10.0.0.1"}]); # Change IP address! Overlap check is enforced!
1075              
1076             my $device2 = $acs->networkdevices("name","Alt_Router");
1077             $device2->description("Standby Router");
1078             $device2->ips([{netMask => "32", ipAddress=>"10.0.0.2"}]); # Change IP address! Overlap check is enforced!
1079            
1080             my $id = $acs->create($device,$device2);
1081             # Update devices based on Net::Cisco::ISE::NetworkDevice instances in arguments
1082             # Return value is ID generated by ISE but not guaranteed.
1083             # print "Record ID is $id" if $id;
1084             # print $Net::Cisco::ISE::ERROR unless $id;
1085             # $Net::Cisco::ISE::ERROR contains details about failure
1086            
1087             =item delete
1088              
1089             This method deletes an existing entry in Cisco ISE, depending on the argument passed. Record type is detected automatically.
1090              
1091             my $user = $ise->internalusers("name","admin");
1092             $ise->delete($user);
1093              
1094             =item $ERROR
1095              
1096             This variable will contain detailed error information, based on the REST API answer. This value is reset during every call to C<internalusers> and C<identitygroups>.
1097            
1098             =back
1099              
1100             =head1 REQUIREMENTS
1101              
1102             For this library to work, you need an instance with Cisco ISE (obviously) or a simulator like L<Net::Cisco::ISE::Mock>.
1103              
1104             Instructions on enabling Cisco ISE for API access will be added later.
1105              
1106             You will also need
1107              
1108             =over 3
1109              
1110             =item L<Moose>
1111              
1112             =item L<IO::Socket::SSL>
1113              
1114             =item L<LWP::UserAgent>
1115              
1116             =item L<XML::Simple>
1117              
1118             =item L<MIME::Base64>
1119              
1120             =item L<URI::Escape>
1121              
1122             =back
1123            
1124             =head1 BUGS
1125              
1126             None so far
1127              
1128             =head1 SUPPORT
1129              
1130             None so far :)
1131              
1132             =head1 AUTHOR
1133              
1134             Hendrik Van Belleghem
1135             CPAN ID: BEATNIK
1136             hendrik.vanbelleghem@gmail.com
1137              
1138             =head1 COPYRIGHT
1139              
1140             This program is free software licensed under the...
1141              
1142             The General Public License (GPL)
1143             Version 2, June 1991
1144              
1145             The full text of the license can be found in the
1146             LICENSE file included with this module.
1147              
1148             =head1 COMPATIBILITY
1149              
1150             Certain API calls are not support from Cisco ISE 5.0 onwards. The current supported versions of Cisco ISE (by Cisco) are 5.6, 5.7 and 5.8 (Active).
1151              
1152             =head1 SEE ALSO
1153              
1154             =over 3
1155              
1156             See L<Net::Cisco::ISE::InternalUser> for more information on User management.
1157              
1158             See L<Net::Cisco::ISE::IdentityGroup> for more information on User Group management.
1159              
1160             See L<Net::Cisco::ISE::NetworkDevice> for more information on Device management.
1161              
1162             See L<Net::Cisco::ISE::NetworkDeviceGroup> for more information on Device Group management.
1163              
1164             See the L<Cisco ISE product page|http://www.cisco.com/c/en/us/products/security/identity-services-engine/index.html> for more information.
1165              
1166             L<Net::Cisco::ISE> relies on L<Moose>.
1167              
1168             =back
1169              
1170             =cut
1171              
1172             #################### main pod documentation end ###################
1173              
1174             __PACKAGE__->meta->make_immutable();
1175              
1176             1;
1177             # The preceding line will help the module return a true value
1178              
1179