From: Ivan Kohler Date: Tue, 11 Sep 2012 13:18:48 +0000 (-0700) Subject: freeswitch export, RT#18087 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=97d5dd9cb66d37a692c0eac78091019befd02a17 freeswitch export, RT#18087 --- diff --git a/FS/FS/part_export/freeswitch.pm b/FS/FS/part_export/freeswitch.pm new file mode 100644 index 000000000..7447849c8 --- /dev/null +++ b/FS/FS/part_export/freeswitch.pm @@ -0,0 +1,180 @@ +package FS::part_export::freeswitch; +use base qw( FS::part_export ); + +use vars qw( %info ); # $DEBUG ); +#use Data::Dumper; +use Tie::IxHash; +use Text::Template; +#use FS::Record qw( qsearch qsearchs ); +#use FS::Schema qw( dbdef ); + +#$DEBUG = 1; + +tie my %options, 'Tie::IxHash', + 'user' => { label => 'SSH username', default=>'root', }, + 'directory' => { label => 'Directory to store FreeSWITCH account XML files', + default => '/usr/local/freeswitch/conf/directory/', + }, + 'domain' => { label => 'Optional fixed SIP domain to use, overrides svc_phone domain', }, + 'reload' => { label => 'Reload command', + default => '/usr/local/freeswitch/bin/fs_cli -x reloadxml', + }, + 'user_template' => { label => 'User XML configuration template', + type => 'textarea', + default => <<'END', + + + + + + + +END + }, +; + +%info = ( + 'svc' => 'svc_phone', + 'desc' => 'Provision phone services to FreeSWITCH XML configuration files', + 'options' => \%options, + 'notes' => <<'END', +Export XML account configuration files to FreeSWITCH, one per phone services. +

+You will need to +setup SSH for unattended operation. +END +); + +sub rebless { shift; } + +sub _export_insert { + my( $self, $svc_phone ) = ( shift, shift ); + + eval "use Net::SCP;"; + die $@ if $@; + + #create and copy over file + + my $tempdir = '%%%FREESIDE_CONF%%%/cache.'. $FS::UID::datasrc; + + my $svcnum = $svc_phone->svcnum; + + my $fh = new File::Temp( + TEMPLATE => "$tempdir/freeswitch.$svcnum.XXXXXXXX", + DIR => $dir, + #UNLINK => 0, + ); + + print $fh $self->freeswitch_template_fillin( $svc_phone, 'user' ) + or die "print to freeswitch template failed: $!"; + close $fh; + + my $scp = new Net::SCP; + my $user = $self->option('user')||'root'; + my $host = $self->machine; + my $dir = $self->option('directory'); + + $scp->scp( $fh->filename, "$user\@$host:$dir/$svcnum.xml" ) + or return $scp->{errstr}; + + #signal freeswitch to reload config + $self->freeswitch_ssh( command => $self->option('reload') ); + + ''; + +} + +sub _export_replace { + my( $self, $new, $old ) = ( shift, shift, shift ); + + $self->_export_insert($new, @_); +} + +sub _export_delete { + my( $self, $svc_phone ) = ( shift, shift ); + + my $dir = $self->option('directory'); + my $svcnum = $svc_phone->svcnum; + + #delete file + $self->freeswitch_ssh( command => "rm $dir/$svcnum.xml" ); + + #signal freeswitch to reload config + $self->freeswitch_ssh( command => $self->option('reload') ); + + ''; +} + +sub freeswitch_template_fillin { + my( $self, $svc_phone, $template ) = (shift, shift, shift); + + $template ||= 'user'; #? + + #cache a %tt hash? + my $tt = new Text::Template ( + TYPE => 'STRING', + SOURCE => $self->option($template.'_template'), + DELIMITERS => [ '<%', '%>' ], + ); + + my $domain = $self->option('domain') + || $svc_phone->domain + || '$${sip_profile}'; + + #false lazinessish w/phone_shellcommands::_export_command + my %hash = ( + 'domain' => $domain, + map { $_ => $svc_phone->getfield($_) } $svc_phone->fields + ); + + #might as well do em all, they're all going in an XML file as attribs + foreach ( keys %hash ) { + $hash{$_} =~ s/'/'/g; + $hash{$_} =~ s/"/"/g; + } + + $tt->fill_in( + HASH => \%hash, + ); +} + +##a good idea to queue anything that could fail or take any time +#sub shellcommands_queue { +# my( $self, $svcnum ) = (shift, shift); +# my $queue = new FS::queue { +# 'svcnum' => $svcnum, +# 'job' => "FS::part_export::freeswitch::ssh_cmd", +# }; +# $queue->insert( @_ ); +#} + +sub freeswitch_ssh { #method + my $self = shift; + ssh_cmd( user => $self->option('user')||'root', + host => $self->machine, + @_, + ); +} + +sub ssh_cmd { #subroutine, not method + use Net::OpenSSH; + my $opt = { @_ }; + open my $def_in, '<', '/dev/null' or die "unable to open /dev/null"; + my $ssh = Net::OpenSSH->new( $opt->{'user'}.'@'.$opt->{'host'}, + default_stdin_fh => $def_in, + ); + die "Couldn't establish SSH connection: ". $ssh->error if $ssh->error; + my ($output, $errput) = $ssh->capture2( #{stdin_discard => 1}, + $opt->{'command'} + ); + die "Error running SSH command: ". $ssh->error if $ssh->error; + + #who the fuck knows what freeswitch reload outputs, probably a fucking + # ascii advertisement for cluecon + #die $errput if $errput; + #die $output if $output; + + ''; +} + +1;