use vars qw(%info $me);
use Tie::IxHash;
+use URI::Escape;
use Frontier::Client;
$me = '['.__PACKAGE__.']';
#'server' => { label => 'Thirdlane server name or IP address', },
'username' => { label => 'Thirdlane username', },
'password' => { label => 'Thirdlane password', },
+ 'ssl' => { label => 'Enable HTTPS (SSL) connection',
+ type => 'checkbox',
+ },
+ 'port' => { label => 'Port number if not 80 or 443', },
'prototype_tenant' => { label => 'Prototype tenant name', },
+ 'omit_countrycode' => { label => 'Omit country code', type => 'checkbox' },
'debug' => { label => 'Checkbox label', type => 'checkbox' },
# 'select_option' => { label => 'Select option description',
# type => 'select', options=>[qw(chocolate vanilla)],
;
%info = (
- 'svc' => [qw( svc_pbx svc_phone )],
+ 'svc' => [qw( svc_pbx svc_phone svc_acct )],
'desc' =>
- 'Export tenants and DIDs to Thirdlane PBX manager',
+ 'Export tenants, DIDs and admins to Thirdlane PBX manager',
'options' => \%options,
'notes' => <<'END'
-Exports tenants and DIDs to Thirdlane PBX manager using the XML-RPC API.
+Exports tenants, DIDs and admins to Thirdlane PBX manager using the XML-RPC API.
END
);
if ( $svc_x->isa('FS::svc_pbx') ) {
+ return 'Name must be 19 characters or less (thirdlane restriction?)'
+ if length($svc_x->title) > 19;
+
+ return 'Name must consist of alphanumerics and spaces only (thirdlane restriction?)'
+ unless $svc_x->title =~ /^[\w\s]+$/;
+
my $tenant = {
'tenant' => $svc_x->title,
'maxusers' => $svc_x->max_extensions,
\@what_to_clone,
);
- use Data::Dumper;
- warn Dumper(\$result);
-
- #$result == 0 means okay??
-
- #$error;
-
- '';
+ #use Data::Dumper;
+ #warn Dumper(\$result);
+ $result eq '0' ? '' : 'Thirdlane API failure (rpc_tenant_create)';
} elsif ( $svc_x->isa('FS::svc_phone') ) {
- } else {
- die "guru meditation #10: $svc_x is not FS::svc_pbx or FS::svc_phone";
- }
-
-}
+ my $result = $self->_thirdlane_command(
+ 'asterisk::rpc_did_create',
+ $self->_thirdlane_did($svc_x)
+ );
-sub _export_insert {
- my($self, $svc_x) = (shift, shift);
+ #use Data::Dumper;
+ #warn Dumper(\$result);
+ $result eq '0' or return 'Thirdlane API failure (rpc_did_create)';
- if ( $svc_x->isa('FS::svc_pbx') ) {
+ return '' unless $svc_x->pbxsvc;
- my $result = $self->_thirdlane_command( 'asterisk::rpc_tenant_delete',
- $svc_x->title,
- );
+ $result = $self->_thirdlane_command(
+ 'asterisk::rpc_did_assign',
+ $self->_thirdlane_did($svc_x),
+ $svc_x->pbx_title,
+ );
- use Data::Dumper;
- warn Dumper(\$result);
+ #use Data::Dumper;
+ #warn Dumper(\$result);
+ $result eq '0' ? '' : 'Thirdlane API failure (rpc_did_assign)';
- #$result == 0 means okay??
+ } elsif ( $svc_x->isa('FS::svc_acct') ) {
- #$error;
+ return 'Must select a PBX' unless $svc_x->pbxsvc;
- '';
+ my $result = $self->_thirdlane_command(
+ 'asterisk::rpc_admin_create',
+ $svc_x->username,
+ $svc_x->_password,
+ $svc_x->pbx_title,
+ );
- } elsif ( $svc_x->isa('FS::svc_phone') ) {
+ #use Data::Dumper;
+ #warn Dumper(\$result);
+ $result eq '0' ? '' : 'Thirdlane API failure (rpc_admin_create)';
} else {
- die "guru meditation #11: $svc_x is not FS::svc_pbx or FS::svc_phone";
+ die "guru meditation #10: $svc_x is not FS::svc_pbx, FS::svc_phone or FS::svc_acct";
}
}
sub _export_replace {
- my($self, $svc_x) = (shift, shift);
+ my($self, $new, $old) = (shift, shift, shift);
- if ( $svc_x->isa('FS::svc_pbx') ) {
+# #return "can't change username with thirdlane"
+# # if $old->username ne $new->username;
+# #return '' unless $old->_password ne $new->_password;
+# $err_or_queue = $self->thirdlane_queue( $new->svcnum,
+# 'replace', $new->username, $new->_password );
+# ref($err_or_queue) ? '' : $err_or_queue;
+
+ if ( $new->isa('FS::svc_pbx') ) {
+
+ #need more info on how the API works for changing names.. can it?
+ return "can't change PBX name with thirdlane (yet?)"
+ if $old->title ne $new->title;
my $tenant = {
- 'tenant' => $svc_x->title,
- 'maxusers' => $svc_x->max_extensions,
+ 'tenant' => $old->title,
+ 'maxusers' => $new->max_extensions,
#others? will they not clone?
};
$tenant
);
- use Data::Dumper;
- warn Dumper(\$result);
+ #use Data::Dumper;
+ #warn Dumper(\$result);
+ $result eq '0' ? '' : 'Thirdlane API failure (rpc_tenant_update)';
+
+ } elsif ( $new->isa('FS::svc_phone') ) {
+
+ return "can't change DID countrycode with thirdlane"
+ if $old->countrycode ne $new->countrycode;
+ return "can't change DID number with thirdlane"
+ if $old->phonenum ne $new->phonenum;
+
+ if ( $old->pbxsvc != $new->pbxsvc ) {
- #$result == 0 means okay??
+ if ( $old->pbxsvc ) {
+ my $result = $self->_thirdlane_command(
+ 'asterisk::rpc_did_unassign',
+ $self->_thirdlane_did($old),
+ );
+ $result eq '0' or return 'Thirdlane API failure (rpc_did_unassign)';
+ }
- #$error;
+ if ( $new->pbxsvc ) {
+ my $result = $self->_thirdlane_command(
+ 'asterisk::rpc_did_assign',
+ $self->_thirdlane_did($new),
+ $new->pbx_title,
+ );
+ $result eq '0' or return 'Thirdlane API failure (rpc_did_assign)';
+ }
+
+
+ }
'';
- } elsif ( $svc_x->isa('FS::svc_phone') ) {
+ } elsif ( $new->isa('FS::svc_acct') ) {
+
+ return "can't change uesrname with thirdlane"
+ if $old->username ne $new->username;
+
+ return "can't change password with thirdlane"
+ if $old->_password ne $new->_password;
+
+ return "can't change PBX for user with thirdlane"
+ if $old->pbxsvc != $new->pbxsvc;
+
+ ''; #we don't care then
} else {
- die "guru meditation #11: $svc_x is not FS::svc_pbx or FS::svc_phone";
+ die "guru meditation #11: $new is not FS::svc_pbx, FS::svc_phone or FS::svc_acct";
}
}
+sub _export_delete {
+ my($self, $svc_x) = (shift, shift);
+ #my( $self, $svc_something ) = (shift, shift);
+ #$err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
+ # 'delete', $svc_something->username );
+ #ref($err_or_queue) ? '' : $err_or_queue;
+
+ if ( $svc_x->isa('FS::svc_pbx') ) {
+
+ my $result = $self->_thirdlane_command( 'asterisk::rpc_tenant_delete',
+ $svc_x->title,
+ );
+
+ #use Data::Dumper;
+ #warn Dumper(\$result);
+ #$result eq '0' ? '' : 'Thirdlane API failure (rpc_tenant_delete)';
+ warn "Thirdlane API failure (rpc_tenant_delete); deleting anyway\n"
+ if $result ne '0';
+ '';
+
+ } elsif ( $svc_x->isa('FS::svc_phone') ) {
+
+ if ( $svc_x->pbxsvc ) {
+ my $result = $self->_thirdlane_command(
+ 'asterisk::rpc_did_unassign',
+ $self->_thirdlane_did($svc_x),
+ );
+ $result eq '0' or return 'Thirdlane API failure (rpc_did_unassign)';
+ }
+
+ my $result = $self->_thirdlane_command(
+ 'asterisk::rpc_did_delete',
+ $self->_thirdlane_did($svc_x),
+ );
+ $result eq '0' ? '' : 'Thirdlane API failure (rpc_did_delete)';
+
+ } elsif ( $svc_x->isa('FS::svc_acct') ) {
+
+ return '' unless $svc_x->pbxsvc; #error out? nah
+
+ my $result = $self->_thirdlane_command(
+ 'asterisk::rpc_admin_delete',
+ $svc_x->username,
+ $svc_x->pbx_title,
+ );
+
+ #use Data::Dumper;
+ #warn Dumper(\$result);
+ #$result eq '0' ? '' : 'Thirdlane API failure (rpc_admin_delete)';
+ warn "Thirdlane API failure (rpc_admin_delete); deleting anyway\n"
+ if $result ne '0';
+ '';
+
+ } else {
+ die "guru meditation #12: $svc_x is not FS::svc_pbx, FS::svc_phone or FS::svc_acct";
+ }
+
+}
sub _thirdlane_command {
my($self, @param) = @_;
- my $url = 'http://'.
- $self->option('username'). ':'. $self->option('password'). '@'.
- $self->machine. '/xmlrpc.cgi';
+ my $url = $self->option('ssl') ? 'https://' : 'http://';
+ $url .= uri_escape($self->option('username')). ':'.
+ uri_escape($self->option('password')). '@'.
+ $self->machine;
+ $url .= ':'. $self->option('port') if $self->option('port');
+ $url .= '/xmlrpc.cgi';
warn "$me connecting to $url\n"
if $self->option('debug');
my $conn = Frontier::Client->new( 'url' => $url,
- 'debug' => $self->option('debug'),
+ #no, spews output to browser
+ #'debug' => $self->option('debug'),
);
warn "$me sending command: ". join(' ', @param). "\n"
}
-sub _export_replace {
- my( $self, $new, $old ) = (shift, shift, shift);
- #return "can't change username with thirdlane"
- # if $old->username ne $new->username;
- #return '' unless $old->_password ne $new->_password;
- $err_or_queue = $self->thirdlane_queue( $new->svcnum,
- 'replace', $new->username, $new->_password );
- ref($err_or_queue) ? '' : $err_or_queue;
+sub _thirdlane_did {
+ my($self, $svc_phone) = @_;
+ if ( $self->option('omit_countrycode') ) {
+ $svc_phone->phonenum;
+ } else {
+ $svc_phone->countrycode. $svc_phone->phonenum;
+ }
}
-sub _export_delete {
- '';
#my( $self, $svc_something ) = (shift, shift);
#$err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
# 'delete', $svc_something->username );
#ref($err_or_queue) ? '' : $err_or_queue;
-}
#these three are optional
-# fallback for svc_acct will change and restore password
-sub _export_suspend {
- my( $self, $svc_something ) = (shift, shift);
- $err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
- 'suspend', $svc_something->username );
- ref($err_or_queue) ? '' : $err_or_queue;
-}
-
-sub _export_unsuspend {
- my( $self, $svc_something ) = (shift, shift);
- $err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
- 'unsuspend', $svc_something->username );
- ref($err_or_queue) ? '' : $err_or_queue;
-}
-
-sub export_links {
- my($self, $svc_something, $arrayref) = (shift, shift, shift);
- #push @$arrayref, qq!<A HREF="http://example.com/~!. $svc_something->username.
- # qq!">!. $svc_something->username. qq!</A>!;
- '';
-}
+## fallback for svc_acct will change and restore password
+#sub _export_suspend {
+# my( $self, $svc_something ) = (shift, shift);
+# $err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
+# 'suspend', $svc_something->username );
+# ref($err_or_queue) ? '' : $err_or_queue;
+#}
+#
+#sub _export_unsuspend {
+# my( $self, $svc_something ) = (shift, shift);
+# $err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
+# 'unsuspend', $svc_something->username );
+# ref($err_or_queue) ? '' : $err_or_queue;
+#}
+#
+#sub export_links {
+# my($self, $svc_something, $arrayref) = (shift, shift, shift);
+# #push @$arrayref, qq!<A HREF="http://example.com/~!. $svc_something->username.
+# # qq!">!. $svc_something->username. qq!</A>!;
+# '';
+#}
####
#