Advertisement
Guest User

jabber provisioning

a guest
Oct 16th, 2017
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.63 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. #use strict;
  4.  
  5. use Getopt::Long;
  6. use HTTP::Request;
  7. use LWP::UserAgent;
  8. use JSON;
  9. use SOAP::Lite;
  10. use Data::Dumper;
  11. use Net::LDAP;
  12.  
  13. my $phone = ''; #'SEPXXXXXX';
  14. my $provision = 0 ;
  15.  
  16. GetOptions ('phone=s' => \$phone, 'provision' => \$provision );
  17.  
  18. $phone = uc( $phone ) ; # switch to upper
  19.  
  20. our $user = 'XXXXX' ;
  21. our $password = 'XXXXX' ;
  22. our $ccmuser = 'XXXXXX' ;
  23. our $ccmpassword = 'xxxxxx' ;
  24. our $cucxhost = 'ucxpub.xxxx.local' ;
  25. our $cucmhost = 'ucspub.xxxx.local' ;
  26.  
  27. our $ad_userdn = 'CN=theaccount,DC=xxxx,DC=yyy' ;
  28. our $ad_basedn = 'OU=ouAccounts,DC=xxxx,DC=yyy' ;
  29. our @ad_srvs = [ 'dc01.xxxx.yyy', 'dc02.xxxx.yyy' ] ;
  30.  
  31. my $unity_base_url = 'https://'.$cucxhost.'/vmrest/' ;
  32.  
  33. my @rolesrequired = (
  34. "Standard CCM End Users", # testing roles "fasoulis","fasoulos",
  35. "Standard CTI Enabled",
  36. "Standard CTI Allow Control of Phones supporting Connected Xfer and conf",
  37. "Standard CTI Allow Control of Phones supporting Rollover Mode",
  38. );
  39.  
  40. my $canprovision = 1;
  41.  
  42. $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
  43.  
  44. #SOAP::Lite->import(+trace); ### use to trace calls
  45.  
  46. BEGIN {
  47. package MyDeserializer;
  48. @MyDeserializer::ISA = 'SOAP::Deserializer';
  49.  
  50. sub typecast {
  51. my( $self, $val, $name, $attrs, $children, $type ) = @_;
  52. if( $type && $type =~ m@http://schemas.cisco.com/ast/soap/@) {
  53. return $val;
  54. }
  55. return undef;
  56. };
  57. }
  58.  
  59. sub SOAP::Transport::HTTP::Client::get_basic_credentials {
  60. return $ccmuser => $ccmpassword ;
  61. }
  62.  
  63. my $soap = SOAP::Lite->new( proxy => 'https://'.$cucmhost.':8443/axl/', ssl_opts => [ SSL_verify_mode => 0 ] );
  64.  
  65. $soap->deserializer( MyDeserializer->new );
  66. $soap->readable( 1 ) ;
  67. $soap->on_action( sub { join ' ', 'CUCM:DB ver=9.1', $_[1] } ) ;
  68. $soap->ns("http://www.cisco.com/AXL/API/9.1");
  69. $soap->{_transport}->{_proxy}->{ssl_opts}->{verify_hostname} = 0;
  70. $soap->{_transport}->{_proxy}->{ssl_opts}->{ SSL_verify_mode } = 0;
  71. $soap->ssl_opts( verify_hostname => 0 );
  72.  
  73.  
  74. my $actions_to_take ;
  75.  
  76. ### AXL & LDAP initialization
  77.  
  78. my $ldap = Net::LDAP->new( @ad_srvs , scheme => 'ldaps' , onerror => 'undef' ) or die "Could not connect to AD because: $@";
  79. $ldap->bind( $ad_userdn, password => $password ) or die "Could not bind to AD... password is wrong? ";
  80.  
  81. print "INFO! Starting queries, phone is $phone \n";
  82.  
  83. ### get phone data, the owner and check it exists
  84.  
  85. my $getphoneReq = SOAP::Data->name("name" => $phone ) ;
  86. my $som_getphone = $soap->call( 'getPhone', $getphoneReq ) ;
  87.  
  88. my $getphone_soap_error = cucm_soap_error( $som_getphone ) ;
  89.  
  90. if ($som_getphone->fault)
  91. {
  92. my $axl_error_code = $som_getphone->faultdetail->{'axlError'}->{'axlcode'};
  93.  
  94. if ( $axl_error_code eq '5007' )
  95. {
  96. die "ERROR! Phone <$phone> does not exist!\n";
  97. }
  98. }
  99. die "Error contacting CUCM" if ( $getphone_soap_error );
  100.  
  101. my $getphone = $som_getphone->result;
  102.  
  103. my $owner = $getphone->{'phone'}->{'ownerUserName'};
  104. my $phone_descr = $getphone->{'phone'}->{'description'};
  105. my $phone_descr_ext = substr($phone_descr, 0, 4);
  106.  
  107. #print Dumper($getphone->{'phone'}->{'lines'}->{'line'}) ; die;
  108.  
  109. my $phone_lines_hash = $getphone->{'phone'}->{'lines'}->{'line'} ;
  110. my @phone_lines ;
  111. if ( ref $phone_lines_hash eq 'ARRAY' ) # Cisco sends array when multiple lines, single value when not
  112. {
  113. @phone_lines = @{ $phone_lines_hash } ;
  114. }
  115. else
  116. {
  117. push( @phone_lines, $phone_lines_hash );
  118. }
  119.  
  120. my $phone_line_pattern = '';
  121. my $phone_line_partition = '';
  122. my $phone_line_displayAscii = '';
  123. print "INFO! Got ".scalar(@phone_lines)." lines for this phone \n";
  124. foreach my $line (@phone_lines)
  125. {
  126. if ( ($line->{'dirn'}->{'pattern'} eq $phone_descr_ext) && !( $line->{'dirn'}->{'routePartitionName'} =~ /anager/ ) )
  127. {
  128. # we found a line on the phone with the same number as description / AD etc
  129. $phone_line_pattern = $line->{ 'dirn' }->{'pattern'} ;
  130. $phone_line_partition = $line->{ 'dirn' }->{'routePartitionName'} ;
  131. $phone_line_displayAscii = $line->{'displayAscii'};
  132. print "INFO! Got line with number <$phone_line_pattern> on partition <$phone_line_partition>\n" ;
  133. last;
  134. }
  135. }
  136.  
  137. print "INFO! owner is <$owner>\n";
  138. die "FATAL! Phone has no owner, please fix this in order to proceed :(" if $owner eq '' ;
  139.  
  140. print "HAPPY! owner exists :)\n";
  141. print "INFO! phone type is <".$getphone->{'phone'}->{'product'}.">\n";
  142. print "INFO! phone description is <".$phone_descr.">\n";
  143. print "INFO! phone extension from description is <".$phone_descr_ext.">\n";
  144.  
  145. if ( $phone_descr_ext ne $phone_line_pattern )
  146. {
  147. print "ERROR! Phone associated lines do not match description \n" ;
  148. $canprovision = 0;
  149. }
  150.  
  151. print "HAPPY! Found line on phone that matches description \n";
  152.  
  153. ### get user details from CUCM and perform some checks
  154.  
  155. my $getuserReq = SOAP::Data->name("userid" => $owner ) ;
  156. my $som_getuser = $soap->call( 'getUser', $getuserReq ) ;
  157. die "FATAL! Error contacting CUCM" if ( cucm_soap_error( $som_getphone ) );
  158.  
  159. my $getuser = $som_getuser->result;
  160.  
  161. my $cucm_userphone = $getuser->{'user'}->{'telephoneNumber'};
  162. my $cucm_phoneext = substr( $cucm_userphone, -4 );
  163.  
  164. my $cucm_user_primaryExtension = $getuser->{'user'}->{'primaryExtension'} ;
  165. my $cucm_user_enableCti = $getuser->{'user'}->{'enableCti'} ;
  166. my $cucm_user_imAndPresenceEnable = $getuser->{'user'}->{'imAndPresenceEnable'} ;
  167. my $cucm_user_serviceProfile = $getuser->{'user'}->{'serviceProfile'} ;
  168. my $cucm_user_presenceGroupName = $getuser->{'user'}->{'presenceGroupName'} ;
  169. my $cucm_user_homeCluster = $getuser->{'user'}->{'homeCluster'} ;
  170. my $cucm_user_associatedGroups = $getuser->{'user'}->{'associatedGroups'} ;
  171. my $cucm_user_associatedDevices = $getuser->{'user'}->{'associatedDevices'} ;
  172.  
  173. print "INFO! cucm user telephone is <$cucm_userphone>\n";
  174. print "INFO! cucm user phone extension telephone is <$cucm_phoneext>\n";
  175.  
  176. if ($cucm_phoneext ne $phone_descr_ext)
  177. {
  178. print "ERROR! Phone from description does not match phone in cucm user database (comes from AD)\n" ;
  179. $canprovision = 0;
  180. }
  181.  
  182. print "HAPPY! phone in description matches cucm user database phone (coming from AD)\n";
  183.  
  184. ### get user details from AD and perform some checks
  185.  
  186. my $ad_result = $ldap->search(
  187. base => $ad_basedn,
  188. scope => 'sub',
  189. filter => '(&(objectclass=person)(sAMAccountName='.$owner.'))',
  190. attrs => [ 'telephoneNumber', 'physicalDeliveryOfficeName' ]
  191. );
  192.  
  193. my @ad_entries = $ad_result->entries;
  194.  
  195. my $num_entries = scalar( @ad_entries );
  196. if ( $num_entries != 1 )
  197. {
  198. print "ERROR! Got more than $num_entries Active directory entries for <$owner>, something is really wrong\n" ;
  199. $canprovision = 0;
  200. }
  201.  
  202. print "HAPPY! Got 1 AD entry for <$owner>\n";
  203.  
  204. my $ad_userphone = $ad_entries[0]->get_value( "telephoneNumber" );
  205. my $ad_useroffice = $ad_entries[0]->get_value( "physicalDeliveryOfficeName" );
  206. my $ad_userphone_ext = substr( $ad_userphone, -4 );
  207. print "INFO! Active directory user telephone is <$ad_userphone>\n";
  208. print "INFO! Active directory user phone ext is <$ad_userphone_ext>\n";
  209.  
  210. if ( $ad_userphone_ext ne $cucm_phoneext )
  211. {
  212. print "ERROR! AD telephone number does not match CUCM phone number! That is strange... Maybe wait 12h for CUCM <-> AD resync \n";
  213. $canprovision = 0;
  214. }
  215.  
  216. print "HAPPY! phone in AD matches cucm user database phone (coming from AD)\n";
  217. $ldap->disconnect();
  218.  
  219. ### Check jabber phone does not exist
  220.  
  221. my $jabber_phone = substr("JAB".$owner,0,15) ; # make it JAB
  222.  
  223. print "INFO! Jabber phone name is <$jabber_phone>\n";
  224.  
  225. my $getjabphoneReq = SOAP::Data->name("name" => $jabber_phone ) ;
  226. my $som_getjabphone = $soap->call( 'getPhone', $getjabphoneReq ) ;
  227.  
  228. my $getjab_soap_error = cucm_soap_error( $som_getjabphone ) ;
  229.  
  230. if ( !( ($getjab_soap_error eq 0) || $getjab_soap_error eq '500' ) )
  231. {
  232. print "ERROR! Something is not working properly on getPhone for Jabber phone....\n" ;
  233. $canprovision = 0;
  234. }
  235.  
  236. if ($som_getjabphone->fault)
  237. {
  238. my $axl_error_code = $som_getjabphone->faultdetail->{'axlError'}->{'axlcode'};
  239.  
  240. if ( $axl_error_code eq '5007' )
  241. {
  242. print "HAPPY! jabber phone does not exist\n";
  243. my $action_to_take = {};
  244. $action_to_take->{ 'name' } = $jabber_phone ;
  245. $action_to_take->{ 'description' } = $phone_descr ;
  246. $action_to_take->{ 'ownerUserName' } = $owner ;
  247. $action_to_take->{ 'primaryPhoneName' } = $phone ;
  248. $action_to_take->{'line'}->{'dirn'}->{ 'pattern' } = $phone_line_pattern ;
  249. $action_to_take->{'line'}->{'dirn'}->{ 'routePartitionName' } = $phone_line_partition ;
  250. $action_to_take->{'line'}->{ 'displayAscii' } = $phone_line_displayAscii ;
  251. $actions_to_take->{'add_jabber_phone'}->{'phone'} = $action_to_take ;
  252.  
  253. }
  254. else
  255. {
  256. print Dumper( $som_getjabphone->faultdetail );
  257. print "ERROR! Didn't expect this!... AXL error on getPhone jabber\n" ;
  258. $canprovision = 0;
  259. }
  260. }
  261. else
  262. {
  263. print "INFO! jabber phone $jabber_phone exists!\n" ;
  264. }
  265.  
  266. ### unity connection checks
  267.  
  268.  
  269.  
  270. my $url_user = $unity_base_url."users/?query=(alias is $owner)&rowsPerPage=0"; # rowsperpage=0 is the way to get only the count
  271. print "INFO! User url to search is <$url_user>\n" ;
  272. my $vmuser_resp = ask_unity( $url_user );
  273.  
  274. my $url_import_user = $unity_base_url."import/users/ldap?query=(alias is $owner)";
  275. print "INFO! Import User url to search is <$url_import_user>\n" ;
  276. my $vm_import_user_resp = ask_unity( $url_import_user );
  277.  
  278. my $url_check_dtmf = $unity_base_url."users/?query=(dtmfAccessId is $ad_userphone_ext)";
  279. print "INFO! Checking existence of voice mailbox with this extension, URL is: <$url_check_dtmf>\n";
  280. my $vm_check_dtmf = ask_unity( $url_check_dtmf );
  281.  
  282. if ( ( $vmuser_resp->{'@total'} eq '0' ) && ( $vm_import_user_resp->{'@total'} eq '1' ) && ( $vm_check_dtmf->{'@total'} eq '0' ) )
  283. {
  284. print "HAPPY! User is not already in unity DB and exists as a user to be imported and extension is not used\n";
  285. my $action_to_take = {};
  286. $action_to_take->{ 'alias' } = $owner ;
  287. $action_to_take->{ 'dtmfAccessId' } = $ad_userphone_ext ;
  288. $action_to_take->{ 'pkid' } = $vm_import_user_resp->{'ImportUser'}->{'pkid'};
  289. if ( $ad_useroffice eq 'REMOFFICE' )
  290. {
  291. $action_to_take->{'template'} = 'VoiceMail_Users_REMOFFICE' ;
  292. }
  293. else
  294. {
  295. $action_to_take->{'template'} = 'VoiceMail_Users_HQ' ;
  296. }
  297. $actions_to_take->{'add_voicemail'}->{'voicemail'} = $action_to_take ;
  298. }
  299. else
  300. {
  301. print "INFO! User is already in unity DB!\n" if ( $vmuser_resp->{'@total'} ne '0' ) ;
  302. print "INFO! User does not exist as an AD importable user... Sync required?!\n" if ( $vm_import_user_resp->{'@total'} ne '1' ) ;
  303. if ( $vm_check_dtmf->{'@total'} ne '0' )
  304. {
  305. print "INFO! Voicemail extension is already assigned to user <".$vm_check_dtmf->{'User'}->{'Alias'}."> <".$vm_check_dtmf->{'User'}->{'DisplayName'}.">\n" ;
  306. if ( ( $vmuser_resp->{'@total'} eq '0' ) && ( $vm_import_user_resp->{'@total'} eq '1' ) )
  307. {
  308. print "ERROR! will not provision because of existence of voice mailbox\n";
  309. $canprovision = 0 ;
  310. }
  311. }
  312. }
  313.  
  314.  
  315. ### We can now provision the settings
  316. ### looking at user attributes / small flags first
  317.  
  318. #if ( !(defined $cucm_user_primaryExtension && defined $cucm_user_primaryExtension->{'pattern'} && defined $cucm_user_primaryExtension->{'routePartitionName'} ) )
  319. #if ( !(defined $cucm_user_primaryExtension && defined $cucm_user_primaryExtension->{'pattern'} && defined $cucm_user_primaryExtension->{'routePartitionName'} ) )
  320. if ( $cucm_user_primaryExtension eq '' )
  321. {
  322. $actions_to_take->{'update_user'}->{'user'}->{ 'userid' } = $owner if ( ! defined $actions_to_take->{'update_user'} ) ;
  323. $actions_to_take->{'update_user'}->{'user'}->{ 'primaryExtension' }->{'pattern'} = $phone_line_pattern ;
  324. $actions_to_take->{'update_user'}->{'user'}->{ 'primaryExtension' }->{'routePartitionName'} = $phone_line_partition ;
  325. print "INFO! Will create primary extension for the user\n";
  326. }
  327. else
  328. {
  329. if ( ($cucm_user_primaryExtension->{'pattern'} ne $phone_line_pattern) || ($cucm_user_primaryExtension->{'routePartitionName'} ne $phone_line_partition) )
  330. {
  331. $actions_to_take->{'update_user'}->{'user'}->{ 'userid' } = $owner if ( ! defined $actions_to_take->{'update_user'} ) ;
  332. $actions_to_take->{'update_user'}->{'user'}->{ 'primaryExtension' }->{'pattern'} = $phone_line_pattern ;
  333. $actions_to_take->{'update_user'}->{'user'}->{ 'primaryExtension' }->{'routePartitionName'} = $phone_line_partition ;
  334. print "WARNING! User has primary extension but needs to be changed, was: ".$cucm_user_primaryExtension->{'pattern'}."/".$cucm_user_primaryExtension->{'routePartitionName'} ;
  335. print " will become: ".$phone_line_pattern."/".$phone_line_partition."\n" ;
  336. }
  337. }
  338. if ( $cucm_user_enableCti ne 'true' )
  339. {
  340. $actions_to_take->{'update_user'}->{'user'}->{ 'userid' } = $owner if ( ! defined $actions_to_take->{'update_user'} ) ;
  341. $actions_to_take->{'update_user'}->{'user'}->{ 'enableCti' } = 'true' ;
  342. print "INFO! Will set enablecti to true\n";
  343. }
  344.  
  345. if ( $cucm_user_imAndPresenceEnable ne 'true' )
  346. {
  347. $actions_to_take->{'update_user'}->{'user'}->{ 'userid' } = $owner if ( ! defined $actions_to_take->{'update_user'} ) ;
  348. $actions_to_take->{'update_user'}->{'user'}->{ 'imAndPresenceEnable' } = 'true' ;
  349. print "INFO! Will set imandpresenceenable to true\n";
  350. }
  351.  
  352. if ( $cucm_user_homeCluster ne 'true' )
  353. {
  354. $actions_to_take->{'update_user'}->{'user'}->{ 'userid' } = $owner if ( ! defined $actions_to_take->{'update_user'} ) ;
  355. $actions_to_take->{'update_user'}->{'user'}->{ 'homeCluster' } = 'true' ;
  356. print "INFO! Will set homecluster to true\n";
  357. }
  358.  
  359. if ( $cucm_user_serviceProfile ne 'Jabber' )
  360. {
  361. $actions_to_take->{'update_user'}->{'user'}->{ 'userid' } = $owner if ( ! defined $actions_to_take->{'update_user'} ) ;
  362. $actions_to_take->{'update_user'}->{'user'}->{ 'serviceProfile' } = 'Jabber' ;
  363. print "INFO! Will set serviceProfile to Jabber\n";
  364. }
  365.  
  366. if ( $cucm_user_presenceGroupName ne 'PGR_HOME' )
  367. {
  368. $actions_to_take->{'update_user'}->{'user'}->{ 'userid' } = $owner if ( ! defined $actions_to_take->{'update_user'} ) ;
  369. $actions_to_take->{'update_user'}->{'user'}->{ 'presenceGroupName' } = 'PGR_HOME' ;
  370. print "INFO! Will set presencegroupname to PGR_HOME\n";
  371. }
  372.  
  373. ### now looking at roles associated with the user
  374.  
  375.  
  376. my $currentroles ;
  377.  
  378. #print Dumper( $cucm_user_associatedGroups );
  379.  
  380. if ( $cucm_user_associatedGroups ne '' )
  381. {
  382. if ( ref $cucm_user_associatedGroups->{'userGroup'} eq 'ARRAY' ) # Cisco sends array when multiple lines, single value when not
  383. {
  384. foreach my $rolename ( @{$cucm_user_associatedGroups->{'userGroup'}} )
  385. {
  386. $currentroles->{ $rolename->{'name'} } = "EXISTS" ;
  387. }
  388. }
  389. else
  390. {
  391. my $rolename = $cucm_user_associatedGroups->{'userGroup'} ;
  392. $currentroles->{ $rolename->{'name'} } = "EXISTS" ;
  393. }
  394. }
  395.  
  396. foreach my $rolename ( @rolesrequired )
  397. {
  398. if ( ! ( defined $currentroles->{ $rolename } ) )
  399. {
  400. $actions_to_take->{'update_user_group'}->{'add_member_to_role'}->{ $rolename } = $owner ;
  401. print "INFO! Will give to user $owner the role $rolename \n";
  402. }
  403. }
  404.  
  405. #print Dumper( $currentroles );
  406.  
  407. ### now checking at associated devices
  408.  
  409. my @devicesrequired = ( $jabber_phone, $phone ) ;
  410.  
  411. my @currentdevices = ();
  412.  
  413. if ( $cucm_user_associatedDevices ne '' )
  414. {
  415. if ( ref $cucm_user_associatedDevices->{'device'} eq 'ARRAY' ) # Cisco sends array when multiple lines, single value when not
  416. {
  417. @currentdevices = @{$cucm_user_associatedDevices->{'device'}} ;
  418. }
  419. else
  420. {
  421. push( @currentdevices, $cucm_user_associatedDevices->{'device'} )
  422. }
  423. }
  424.  
  425. my @newdevices ;
  426. my $currentdeviceshash ;
  427.  
  428. foreach my $device ( @currentdevices )
  429. {
  430. $currentdeviceshash->{ $device } = "EXISTS" ;
  431. }
  432.  
  433. foreach my $device ( @devicesrequired )
  434. {
  435. if ( ! ( defined $currentdeviceshash->{ $device } ) )
  436. {
  437. push( @newdevices, $device );
  438. }
  439. }
  440.  
  441. if ( scalar(@newdevices) > 0 )
  442. {
  443. $actions_to_take->{'update_user'}->{'user'}->{ 'userid' } = $owner if ( ! defined $actions_to_take->{'update_user'} ) ;
  444. foreach my $device (@currentdevices)
  445. {
  446. push(@newdevices, $device);
  447. }
  448. $actions_to_take->{'update_user'}->{'user'}->{'associatedDevices'}->{ 'device' } = \@newdevices ;
  449. print "INFO! Will associate the devices ";
  450. foreach my $device ( @newdevices ) { print $device." " ; };
  451. print " to user profile\n" ;
  452. }
  453.  
  454. #print Dumper( $cucm_user_associatedDevices );
  455.  
  456.  
  457. ### Here are the actions to enable the user:
  458. print "INFO! This is what needs to be provisioned\n";
  459. print Dumper( $actions_to_take );
  460. if ( defined $actions_to_take )
  461. {
  462. if ( $canprovision && $provision )
  463. {
  464. print "\n\nINFO! Starting provisioning:\n";
  465.  
  466. ### We've got all the data let's provision....
  467. #die;
  468. #print Dumper( keys $actions_to_take );
  469.  
  470.  
  471. if ( defined $actions_to_take->{'add_jabber_phone'} ) { add_jabber_phone( $actions_to_take->{'add_jabber_phone'} ) ; }
  472. if ( defined $actions_to_take->{'update_user'} ) { update_user( $actions_to_take->{'update_user'} ) ; }
  473. if ( defined $actions_to_take->{'update_user_group'} ) { update_user_group( $actions_to_take->{'update_user_group'} ) ; }
  474. if ( defined $actions_to_take->{'add_voicemail'} ) { add_voicemail( $actions_to_take->{'add_voicemail'} ) ; }
  475.  
  476. print "INFO Check above information to see if everything went ok\n" ;
  477. }
  478. else
  479. {
  480. if ( !$canprovision )
  481. {
  482. print "INFO! Will not provision because of errors\n";
  483. }
  484. if ( !$provision )
  485. {
  486. print "INFO! Will not provision because you said so\n";
  487. }
  488. }
  489. }
  490. else
  491. {
  492. print "INFO! Nothing needs to be provisioned, everything seems to be in place\n";
  493. }
  494.  
  495. exit(0);
  496.  
  497.  
  498.  
  499.  
  500. sub update_user
  501. {
  502.  
  503. # print "update_user: ".Dumper( $_[0] );
  504. my $udata = $_[0] ;
  505.  
  506. my $theuser = $udata->{'user'}->{'userid'} ;
  507. my $enablecti = $udata->{'user'}->{'enableCti'} ;
  508. my $homecluster = $udata->{'user'}->{'homeCluster'} ;
  509. my $enableforim = $udata->{'user'}->{'imAndPresenceEnable'} ;
  510. my $serviceprofile = $udata->{'user'}->{'serviceProfile'} ;
  511. my $presencegroup = $udata->{'user'}->{'presenceGroupName'} ;
  512. my $ext = $udata->{'user'}->{ 'primaryExtension' }->{'pattern'} ;
  513. my $par = $udata->{'user'}->{ 'primaryExtension' }->{'routePartitionName'} ;
  514. my @associateddevs = ();
  515.  
  516. if ( defined $udata->{'user'}->{'associatedDevices'}->{'device'} )
  517. {
  518. @associateddevs = @{ $udata->{'user'}->{'associatedDevices'}->{'device'} } ;
  519. }
  520.  
  521.  
  522. my @params = ();
  523.  
  524. if ( scalar(@associateddevs) gt 0 )
  525. {
  526. my @soapdevarr ;
  527. my $assosdev ;
  528. foreach my $dev ( @associateddevs )
  529. {
  530. push( @soapdevarr, SOAP::Data->name( 'device' => $dev ) );
  531. }
  532. $assosdev = SOAP::Data->name("associatedDevices" => \@soapdevarr );
  533. push( @params, $assosdev);
  534. }
  535.  
  536. my $userSoap = SOAP::Data->name( 'userid' => $theuser ) ;
  537.  
  538. if ( (defined $ext) && ($ext ne '') )
  539. {
  540. my $param = SOAP::Data->name( 'primaryExtension' => [ SOAP::Data->name( 'pattern' => $ext )->type('string'),
  541. SOAP::Data->name( 'routePartitionName' => $par) ] ) ;
  542. push( @params, $param );
  543. }
  544.  
  545. if( (defined $enablecti) && ($enablecti ne '') ) {
  546. my $param = SOAP::Data->name( 'enableCti' => $enablecti );
  547. push( @params, $param ) ;
  548. }
  549.  
  550. if( (defined $presencegroup) && ($presencegroup ne '') ) {
  551. my $param = SOAP::Data->name( 'presenceGroupName' => $presencegroup );
  552. push( @params, $param ) ;
  553. }
  554.  
  555. if( (defined $homecluster) && ($homecluster ne '') ) {
  556. my $param = SOAP::Data->name( 'homeCluster' => $homecluster );
  557. push( @params, $param ) ;
  558. }
  559.  
  560. if( (defined $enableforim) && ($enableforim ne '') ) {
  561. my $param = SOAP::Data->name( 'imAndPresenceEnable' => $enableforim );
  562. push( @params, $param ) ;
  563. }
  564.  
  565. if( (defined $serviceprofile) && ($serviceprofile ne '') ) {
  566. my $param = SOAP::Data->name( 'serviceProfile' => $serviceprofile );
  567. push( @params, $param ) ;
  568. }
  569.  
  570. if ( scalar(@params) gt 0 )
  571. {
  572. my $som_updu = $soap->call( 'updateUser', $userSoap, @params ) ;
  573. my $updu_soap_error = cucm_soap_error( $som_updu ) ;
  574. if ( $updu_soap_error )
  575. {
  576. print "INFO! error while updating user $theuser \n";
  577. # print Dumper( $som_updu)."\n";
  578. }
  579. else
  580. {
  581. print "INFO! success on update user $theuser ".Dumper($som_updu->result)."\n";
  582. }
  583. }
  584. else
  585. {
  586. print "WARNING! No updates needed for $theuser ....skipping (but we should not be here)...\n"
  587. }
  588.  
  589. }
  590.  
  591. sub update_user_group
  592. {
  593. print "on update_user_group\n";
  594. # print "update_user_group ".Dumper( $_[0] );
  595.  
  596. my $roleactions = $_[0];
  597.  
  598. my $rolestoadd = $roleactions->{'add_member_to_role'};
  599.  
  600. if ( defined $rolestoadd )
  601. {
  602. foreach my $role ( keys %{$rolestoadd} )
  603. {
  604.  
  605. my @soapuserarr ;
  606. push( @soapuserarr, SOAP::Data->name( 'member' => \SOAP::Data->name( 'userId' => $rolestoadd->{$role} )) );
  607.  
  608. my $grouprole = SOAP::Data->name("name" => $role );
  609. my $assosuserstoadd = SOAP::Data->name("addMembers" => \@soapuserarr );
  610.  
  611. my $som_updugroup = $soap->call( 'updateUserGroup', $grouprole, $assosuserstoadd ) ;
  612. my $updugroup_soap_error = cucm_soap_error( $som_updugroup ) ;
  613. if ( $updugroup_soap_error )
  614. {
  615. print "ERROR! error while adding role $role to ".$rolestoadd->{$role}."\n";
  616. }
  617. else
  618. {
  619. print "INFO! success on adding role $role to ".$rolestoadd->{$role}." ".Dumper($som_updugroup->result)."\n";
  620. }
  621.  
  622. }
  623. }
  624.  
  625.  
  626. }
  627.  
  628.  
  629. sub add_jabber_phone
  630. {
  631. # print "add_jabber_phone ".Dumper( $_[0] );
  632.  
  633. my $phdata = $_[0];
  634. my $phonemask = "9999XXXX";
  635.  
  636. my $jabbphonename = $phdata->{'phone'}->{'name'} ;
  637. my $owneruid = $phdata->{'phone'}->{'ownerUserName'} ;
  638. my $phonedescr = $phdata->{'phone'}->{'description'} ;
  639. my $deskphone = $phdata->{'phone'}->{'primaryPhoneName'} ;
  640. my $dirnpattern = $phdata->{'phone'}->{'line'}->{'dirn'}->{'pattern'} ;
  641. my $dirnpartition = $phdata->{'phone'}->{'line'}->{'dirn'}->{'routePartitionName'} ;
  642. my $linedescription = $phdata->{'phone'}->{'line'}->{'displayAscii'};
  643.  
  644. my $addphoneSoap = SOAP::Data->name( 'phone' => [
  645. SOAP::Data->name( 'name' => $jabbphonename ),
  646. SOAP::Data->name( 'description' => $phonedescr ),
  647. SOAP::Data->name( 'product' => 'Cisco Unified Client Services Framework' ),
  648. SOAP::Data->name( 'class' => 'Phone' ),
  649. SOAP::Data->name( 'protocol' => 'SIP' ),
  650. SOAP::Data->name( 'protocolSide' => 'User' ),
  651. SOAP::Data->name( 'devicePoolName' => 'DEV_Phones' ),
  652. SOAP::Data->name( 'securityProfileName' => 'Cisco Unified Client Services Framework - Standard SIP Non-Secure' ),
  653. SOAP::Data->name( 'sipProfileName' => 'Jabber Windows SIP Profile' ),
  654. SOAP::Data->name( 'lines' => [
  655. SOAP::Data->name( 'line' => [
  656. SOAP::Data->name( 'index' => '1' )->type('string'),
  657. SOAP::Data->name( 'label' => $linedescription ),
  658. SOAP::Data->name( 'asciilabel' => $linedescription ),
  659. SOAP::Data->name( 'display' => $linedescription ),
  660. SOAP::Data->name( 'dirn' => [
  661. SOAP::Data->name( 'pattern' => $dirnpattern )->type('string'),
  662. SOAP::Data->name( 'routePartitionName' => $dirnpartition )
  663. ] ),
  664. SOAP::Data->name( 'displayAscii' => $linedescription ),
  665. SOAP::Data->name( 'e164Mask' => $phonemask ),
  666. ] ),
  667. ] ),
  668. SOAP::Data->name( 'phoneTemplateName' => 'Standard Client Services Framework' ),
  669. SOAP::Data->name( 'primaryPhoneName' => $deskphone ),
  670. SOAP::Data->name( 'ownerUserName' => $owneruid ),
  671. ] ) ;
  672.  
  673.  
  674. my $som_addphone = $soap->call( 'addPhone', $addphoneSoap ) ;
  675. my $addphone_soap_error = cucm_soap_error( $som_addphone ) ;
  676. if ( $addphone_soap_error )
  677. {
  678. print "ERROR! error while adding jabber phone $jabbphonename \n";
  679. }
  680. else
  681. {
  682. print "INFO! success on provisioning jabber phone $jabbphonename ".Dumper($som_addphone->result)."\n";
  683. }
  684.  
  685. }
  686.  
  687. sub add_voicemail
  688. {
  689. # print "add_voicemail ".Dumper( $_[0] );
  690. my $vmdata = $_[0] ;
  691. my $template = $vmdata->{'voicemail'}->{'template'};
  692.  
  693. my $importdata ;
  694.  
  695. $importdata->{'alias'} = $vmdata->{'voicemail'}->{'alias'} ;
  696. $importdata->{'dtmfAccessId'} = $vmdata->{'voicemail'}->{'dtmfAccessId'} ;
  697. $importdata->{'pkid'} = $vmdata->{'voicemail'}->{'pkid'} ;
  698.  
  699. my $json_importdata = to_json( $importdata );
  700.  
  701. print Dumper( $json_importdata );
  702.  
  703. my $url = $unity_base_url."import/users/ldap?templateAlias=$template";
  704. #my $url = $_[0];
  705. my $request = HTTP::Request->new(POST => $url);
  706.  
  707.  
  708. $request->header(
  709. 'Accept' => 'application/json',
  710. 'Content_type' => 'application/json'
  711. );
  712.  
  713. $request->content( $json_importdata );
  714.  
  715. my $ua = LWP::UserAgent->new( ssl_opts => {
  716. SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
  717. verify_hostname => 0
  718. }
  719. );
  720. $ua->timeout(30);
  721. $ua->ssl_opts( verify_hostnames => 0 );
  722.  
  723. # my $ua = LWP::UserAgent->new;
  724. # $ua->timeout(30);
  725.  
  726. $ua->credentials("$cucxhost:443", "Cisco VTG Realm", $ccmuser, $ccmpassword);
  727.  
  728. my $response = $ua->request($request);
  729.  
  730. if( !($response->is_success) )
  731. {
  732. print "ERROR! error while importing user in Unity via $url\n" ;
  733. print "ERRORINFO! voicemail: status: ".$response->status_line."\nERRORINFO! voicemail: Response:".$response->content."\n";
  734. }
  735.  
  736. }
  737.  
  738. sub cucm_soap_error
  739. {
  740. my $som = $_[0];
  741. # print Dumper($som);
  742. my $http_code = $som->{'_context'}->{'_transport'}->{_proxy}->{_code};
  743. if ( $http_code ne '200' )
  744. {
  745. print "INFO! CUCM http code is $http_code\n";
  746. return $http_code ;
  747. }
  748. else
  749. {
  750. return 0 ; #undef;
  751. }
  752. }
  753.  
  754. sub ask_unity
  755. {
  756. my $url = $_[0];
  757. my $request = HTTP::Request->new(GET => $url);
  758.  
  759. $request->header(
  760. 'Accept' => 'application/json',
  761. 'Content_type' => 'application/json'
  762. );
  763.  
  764. my $ua = LWP::UserAgent->new( ssl_opts => {
  765. SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
  766. verify_hostname => 0
  767. }
  768. );
  769. $ua->timeout(30);
  770. $ua->ssl_opts( verify_hostnames => 0 );
  771.  
  772.  
  773. # my $ua = LWP::UserAgent->new;
  774. # $ua->timeout(30);
  775.  
  776. $ua->credentials("$cucxhost:443", "Cisco VTG Realm", $ccmuser, $ccmpassword);
  777.  
  778. my $response = $ua->request($request);
  779.  
  780.  
  781. if( !($response->is_success) )
  782. {
  783. print "ERROR! error while accessing $url status: ".$response->status_line."\n" ;
  784. }
  785.  
  786. return from_json( $response->content );
  787. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement