1 package FS::part_export::freeswitch_multifile;
2 use base qw( FS::part_export );
4 use vars qw( %info ); # $DEBUG );
8 #use FS::Record qw( qsearch qsearchs );
9 #use FS::Schema qw( dbdef );
13 tie my %options, 'Tie::IxHash',
14 'user' => { label => 'SSH username', default=>'root', },
15 'directory' => { label => 'Directory to store FreeSWITCH account XML files',
16 default => '/usr/local/freeswitch/conf/directory/',
18 'domain' => { label => 'Optional fixed SIP domain to use, overrides svc_phone domain', },
19 'reload' => { label => 'Reload command',
20 default => '/usr/local/freeswitch/bin/fs_cli -x reloadxml',
22 'user_template' => { label => 'User XML configuration template',
25 <domain name="<% $domain %>">
26 <user id="<% $phonenum %>">
28 <param name="password" value="<% $sip_password %>"/>
29 <param name="nibble_account" value="<% $phonenum %>"/>
30 <param name="nibble_rate" value="<% $nibble_rate %>"/>
40 'desc' => 'Provision phone services to FreeSWITCH XML configuration files (one file per user)',
41 'options' => \%options,
43 Export XML account configuration files to FreeSWITCH, one per phone services.
46 <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:1.9:Documentation:Administration:SSH_Keys">setup SSH for unattended operation</a>.
50 sub rebless { shift; }
53 my( $self, $svc_phone ) = ( shift, shift );
58 #create and copy over file
60 my $tempdir = '%%%FREESIDE_CONF%%%/cache.'. $FS::UID::datasrc;
62 my $svcnum = $svc_phone->svcnum;
64 my $fh = new File::Temp(
65 TEMPLATE => "freeswitch.$svcnum.XXXXXXXX",
70 print $fh $self->freeswitch_template_fillin( $svc_phone, 'user' )
71 or die "print to freeswitch template failed: $!";
74 my $scp = new Net::SCP;
75 my $user = $self->option('user')||'root';
76 my $host = $self->machine;
77 my $dir = $self->option('directory');
79 $scp->scp( $fh->filename, "$user\@$host:$dir/$svcnum.xml" )
80 or return $scp->{errstr};
82 #signal freeswitch to reload config
83 $self->freeswitch_ssh( command => $self->option('reload') );
90 my( $self, $new, $old ) = ( shift, shift, shift );
92 $self->_export_insert($new, @_);
96 my( $self, $svc_phone ) = ( shift, shift );
98 my $dir = $self->option('directory');
99 my $svcnum = $svc_phone->svcnum;
102 $self->freeswitch_ssh( command => "rm $dir/$svcnum.xml" );
104 #signal freeswitch to reload config
105 $self->freeswitch_ssh( command => $self->option('reload') );
110 sub freeswitch_template_fillin {
111 my( $self, $svc_phone, $template ) = (shift, shift, shift);
113 $template ||= 'user'; #?
116 my $tt = new Text::Template (
118 SOURCE => $self->option($template.'_template'),
119 DELIMITERS => [ '<%', '%>' ],
122 my $domain = $self->option('domain')
123 || $svc_phone->domain
124 || '$${sip_profile}';
126 #false lazinessish w/phone_shellcommands::_export_command
129 map { $_ => $svc_phone->getfield($_) } $svc_phone->fields
132 #might as well do em all, they're all going in an XML file as attribs
133 foreach ( keys %hash ) {
134 $hash{$_} =~ s/'/'/g;
135 $hash{$_} =~ s/"/"/g;
143 ##a good idea to queue anything that could fail or take any time
144 #sub shellcommands_queue {
145 # my( $self, $svcnum ) = (shift, shift);
146 # my $queue = new FS::queue {
147 # 'svcnum' => $svcnum,
148 # 'job' => "FS::part_export::freeswitch::ssh_cmd",
150 # $queue->insert( @_ );
153 sub freeswitch_ssh { #method
155 ssh_cmd( user => $self->option('user')||'root',
156 host => $self->machine,
161 sub ssh_cmd { #subroutine, not method
164 open my $def_in, '<', '/dev/null' or die "unable to open /dev/null";
165 my $ssh = Net::OpenSSH->new( $opt->{'user'}.'@'.$opt->{'host'},
166 default_stdin_fh => $def_in,
168 die "Couldn't establish SSH connection: ". $ssh->error if $ssh->error;
169 my ($output, $errput) = $ssh->capture2( #{stdin_discard => 1},
172 die "Error running SSH command: ". $ssh->error if $ssh->error;
174 #who the fuck knows what freeswitch reload outputs, probably a fucking
175 # ascii advertisement for cluecon
176 #die $errput if $errput;
177 #die $output if $output;