agent-virtualize credit card surcharge percentage, RT#72961
[freeside.git] / FS / FS / part_export / phone_shellcommands.pm
1 package FS::part_export::phone_shellcommands;
2
3 use strict;
4 use vars qw(@ISA %info);
5 use Tie::IxHash;
6 use String::ShellQuote;
7 use FS::part_export;
8
9 @ISA = qw(FS::part_export);
10
11 #TODO
12 #- modify command (get something from freepbx for changing PINs)
13 #- suspension/unsuspension
14
15 tie my %options, 'Tie::IxHash',
16   'user'       => { label=>'Remote username', default=>'root', },
17   'useradd'    => { label=>'Insert command', }, 
18   'userdel'    => { label=>'Delete command', }, 
19   'usermod'    => { label=>'Modify command', }, 
20   'suspend'    => { label=>'Suspension command', }, 
21   'unsuspend'  => { label=>'Unsuspension command', }, 
22   'mac_insert' => { label=>'Device MAC address insert command', },
23   'mac_delete' => { label=>'Device MAC address delete command', },
24 ;
25
26 %info = (
27   'svc'     => [qw( svc_phone part_device )],
28   'desc'    => 'Run remote commands via SSH, for phone numbers',
29   'options' => \%options,
30   'notes'   => <<'END'
31 Run remote commands via SSH, for phone numbers.  You will need to
32 <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:1.9:Documentation:Administration:SSH_Keys">setup SSH for unattended operation</a>.
33 <BR><BR>Use these buttons for some useful presets:
34 <UL>
35   <LI>
36     <INPUT TYPE="button" VALUE="FreePBX (build_exten CLI module needed)" onClick='
37       this.form.user.value = "root";
38       this.form.useradd.value = "build_exten.php --create --exten $phonenum --directdid 1$phonenum --sip-secret $sip_password --name $cust_name --vm-password $pin && /usr/share/asterisk/bin/module_admin reload";
39       this.form.userdel.value = "build_exten.php --delete --exten $phonenum && /usr/share/asterisk/bin/module_admin reload";
40       this.form.usermod.value = "build_exten.php --modify --exten $new_phonenum --directdid 1$new_phonenum --sip-secret $new_sip_password --name $new_cust_name --vm-password $new_pin && /usr/share/asterisk/bin/module_admin reload";
41       this.form.suspend.value = "";
42       this.form.unsuspend.value = "";
43     '> (Important note: Reduce freeside-queued "max_kids" to 1 when using FreePBX integration)
44   </UL>
45
46 The following variables are available for interpolation (prefixed with new_ or
47 old_ for replace operations):
48 <UL>
49   <LI><code>$countrycode</code> - Country code
50   <LI><code>$phonenum</code> - Phone number
51   <LI><code>$sip_password</code> - SIP secret (quoted for the shell)
52   <LI><code>$pin</code> - Personal identification number
53   <LI><code>$cust_name</code> - Customer name (quoted for the shell)
54   <LI><code>$pkgnum</code> - Internal package number
55   <LI><code>$custnum</code> - Internal customer number
56   <LI><code>$phone_name</code> - Phone name (quoted for the shell)
57   <LI><code>$mac_addr</code> - MAC address (Device MAC address insert and delete commands only)
58   <LI><code>$devicename</code> - Device type (Device type insert and delete commands only)
59 </UL>
60 END
61 );
62
63 sub rebless { shift; }
64
65 sub _export_insert {
66   my $self = shift;
67   $self->_export_command('useradd', @_);
68 }
69
70 sub _export_delete {
71   my $self = shift;
72   $self->_export_command('userdel', @_);
73 }
74
75 sub _export_suspend {
76   my $self = shift;
77   $self->_export_command('suspend', @_);
78 }
79
80 sub _export_unsuspend {
81   my $self = shift;
82   $self->_export_command('unsuspend', @_);
83 }
84
85 sub export_device_insert {
86   my( $self, $svc_phone, $phone_device ) = @_;
87   $self->_export_command('mac_insert', $svc_phone,
88                            mac_addr   => $phone_device->mac_addr,
89                            devicename => $phone_device->part_device->devicename,
90                         );
91 }
92
93 sub export_device_delete {
94   my( $self, $svc_phone, $phone_device ) = @_;
95   $self->_export_command('mac_delete', $svc_phone,
96                            mac_addr   => $phone_device->mac_addr,
97                            devicename => $phone_device->part_device->devicename,
98                         );
99 }
100
101 sub _export_command {
102   my ( $self, $action, $svc_phone, %addl_vars) = @_;
103   my $command = $self->option($action);
104   return '' if $command =~ /^\s*$/;
105
106   #set variable for the command
107   no strict 'vars';
108   {
109     no strict 'refs';
110     ${$_} = $svc_phone->getfield($_) foreach $svc_phone->fields;
111     ${$_} = $addl_vars{$_} foreach keys %addl_vars;
112   }
113   my $cust_pkg = $svc_phone->cust_svc->cust_pkg;
114   my $pkgnum = $cust_pkg ? $cust_pkg->pkgnum : '';
115   my $custnum = $cust_pkg ? $cust_pkg->custnum : '';
116   my $cust_name = $cust_pkg ? $cust_pkg->cust_main->name : '';
117   $cust_name = shell_quote $cust_name;
118   my $sip_password = shell_quote $svc_phone->sip_password;
119   my $phone_name = shell_quote $svc_phone->phone_name;
120   #done setting variables for the command
121
122   $self->shellcommands_queue( $svc_phone->svcnum,
123     user         => $self->option('user')||'root',
124     host         => $self->machine,
125     command      => eval(qq("$command")),
126   );
127 }
128
129 sub _export_replace {
130   my($self, $new, $old ) = (shift, shift, shift);
131   my $command = $self->option('usermod');
132   
133   #set variable for the command
134   no strict 'vars';
135   {
136     no strict 'refs';
137     ${"old_$_"} = $old->getfield($_) foreach $old->fields;
138     ${"new_$_"} = $new->getfield($_) foreach $new->fields;
139   }
140
141   my $old_cust_pkg = $old->cust_svc->cust_pkg;
142   my $old_pkgnum = $old_cust_pkg ? $old_cust_pkg->pkgnum : '';
143   my $old_custnum = $old_cust_pkg ? $old_cust_pkg->custnum : '';
144   my $cust_pkg = $new->cust_svc->cust_pkg;
145   my $new_pkgnum = $cust_pkg ? $cust_pkg->pkgnum : '';
146   my $new_custnum = $new_cust_pkg ? $new_cust_pkg->custnum : '';
147   my $new_cust_name = $cust_pkg ? $cust_pkg->cust_main->name : '';
148   $new_cust_name = shell_quote $new_cust_name;
149   #done setting variables for the command
150
151   $self->shellcommands_queue( $new->svcnum,
152     user         => $self->option('user')||'root',
153     host         => $self->machine,
154     command      => eval(qq("$command")),
155   );
156 }
157
158 #a good idea to queue anything that could fail or take any time
159 sub shellcommands_queue {
160   my( $self, $svcnum ) = (shift, shift);
161   my $queue = new FS::queue {
162     'svcnum' => $svcnum,
163     'job'    => "FS::part_export::phone_shellcommands::ssh_cmd",
164   };
165   $queue->insert( @_ );
166 }
167
168 sub ssh_cmd { #subroutine, not method
169   use Net::SSH '0.08';
170   &Net::SSH::ssh_cmd( { @_ } );
171 }
172
173 1;