communigate provisioning phase 2: add svc_domain.trailer -> communigate TrailerText...
[freeside.git] / FS / FS / Tron.pm
1 package FS::Tron;
2 # a program to monitor outside systems
3
4 use strict;
5 use warnings;
6 use base 'Exporter';
7 use Net::SSH qw( sshopen2 ); #sshopen3 );
8 use FS::Record qw( qsearchs );
9 use FS::svc_external;
10 use FS::cust_svc_option;
11
12 our @EXPORT_OK = qw( tron_ping tron_scan tron_lint);
13
14 our %desired = (
15   #less lenient, we need to make sure we upgrade deb 4 & pg 7.4 
16   'freeside_version' => qr/^1\.(7\.3|9\.0)/,
17   'debian_version'   => qr/^5/, #qr/^5.0.[2-9]$/ #qr/^4/,
18   'apache_mpm'       => qw/^(Prefork|$)/,
19   'pg_version'       => qr/^8\.[1-9]/,
20   'apache_version'   => qr/^2/,
21
22   #payment gateway survey
23 #  'payment_gateway'  => qw/^authorizenet$/,
24
25   #stuff to add/replace later
26   #'apache_mpm'       => qw/^Prefork/,
27   #'pg_version'       => qr/^8\.[3-9]/,
28 );
29
30 sub _cust_svc_external {
31   my $cust_svc_or_svcnum = shift;
32
33   my ( $cust_svc, $svc_external );
34   if ( ref($cust_svc_or_svcnum) ) {
35     $cust_svc = $cust_svc_or_svcnum;
36     $svc_external = $cust_svc->svc_x;
37   } else {
38     $svc_external = qsearchs('svc_external', { svcnum=>$cust_svc_or_svcnum } );
39     $cust_svc = $svc_external->cust_svc;
40   }
41
42   ( $cust_svc, $svc_external );
43
44 }
45
46 sub tron_ping {
47   my( $cust_svc, $svc_external ) = _cust_svc_external(shift);
48
49   my %hash = ();
50   my $machine = $svc_external->title; # or better as a cust_svc_option??
51   sshopen2($machine, *READER, *WRITER, '/bin/echo pong');
52   my $pong = scalar(<READER>);
53   close READER;
54   close WRITER;
55   
56   $pong =~ /pong/;
57 }
58
59 sub tron_scan {
60   my( $cust_svc, $svc_external ) = _cust_svc_external(shift);
61
62   #don't scan again if things are okay
63   my $bad = 0;
64   foreach my $option ( keys %desired ) {
65     my $current = $cust_svc->option($option);
66     $bad++ unless $current =~ $desired{$option};
67   }
68   return '' unless $bad;
69
70   #do the scan
71   my %hash = ();
72   my $machine = $svc_external->title; # or better as a cust_svc_option??
73   #sshopen2($machine, *READER, *WRITER, '/usr/local/bin/freeside-yori all');
74   #fix freeside users' patch if necessary, since packages put this in /usr/bin
75   sshopen2($machine, *READER, *WRITER, 'freeside-yori all');
76   while (<READER>) {
77     chomp;
78     my($option, $value) = split(/: ?/);
79     next unless defined($option) && exists($desired{$option});
80     $hash{$option} = $value;
81   }
82   close READER;
83   close WRITER;
84
85   unless ( keys %hash ) {
86     return "error scanning $machine\n";
87   }
88
89   # store the results
90   foreach my $option ( keys %hash ) {
91     my %opthash = ( 'optionname' => $option,
92                     'svcnum'     => $cust_svc->svcnum,
93                   );
94     my $cust_svc_option =  qsearchs('cust_svc_option', \%opthash )
95                           || new FS::cust_svc_option   \%opthash;
96     next if $cust_svc_option->optionvalue eq $hash{$option};
97     $cust_svc_option->optionvalue( $hash{$option} );
98     my $error = $cust_svc_option->optionnum
99                   ? $cust_svc_option->replace
100                   : $cust_svc_option->insert;
101     return $error if $error;
102   }
103   
104   '';
105
106 }
107
108 sub tron_lint {
109   my $cust_svc = shift;
110
111   my @lint;
112   foreach my $option ( keys %desired ) {
113     my $current = $cust_svc->option($option);
114     push @lint, "$option is $current" unless $current =~ $desired{$option};
115   }
116
117   push @lint, 'unchecked' unless scalar($cust_svc->options);
118
119   @lint;
120
121 }
122
123 1;