diff options
Diffstat (limited to 'FS/FS/Cron/check.pm')
-rw-r--r-- | FS/FS/Cron/check.pm | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/FS/FS/Cron/check.pm b/FS/FS/Cron/check.pm new file mode 100644 index 0000000..9d3ffbd --- /dev/null +++ b/FS/FS/Cron/check.pm @@ -0,0 +1,200 @@ +package FS::Cron::check; + +use strict; +use vars qw( @ISA @EXPORT_OK $DEBUG $FS_RUN $error_msg + $SELFSERVICE_USER $SELFSERVICE_MACHINES @SELFSERVICE_MACHINES + ); +use Exporter; +use LWP::UserAgent; +use HTTP::Request; +use URI::Escape; +use Email::Send; +use FS::Conf; +use FS::Record qw(qsearch); +use FS::cust_pay_pending; + +@ISA = qw( Exporter ); +@EXPORT_OK = qw( + check_queued check_selfservice check_apache check_bop_failures + check_sg check_sg_login check_sgng + alert error_msg +); + +$DEBUG = 0; + +$FS_RUN = '/var/run'; + +sub check_queued { + _check_fsproc('queued'); +} + +$SELFSERVICE_USER = '%%%SELFSERVICE_USER%%%'; + +$SELFSERVICE_MACHINES = '%%%SELFSERVICE_MACHINES%%%'; #substituted by Makefile +$SELFSERVICE_MACHINES =~ s/^\s+//; +$SELFSERVICE_MACHINES =~ s/\s+$//; +@SELFSERVICE_MACHINES = split(/\s+/, $SELFSERVICE_MACHINES); +@SELFSERVICE_MACHINES = () + if scalar(@SELFSERVICE_MACHINES) == 1 + && $SELFSERVICE_MACHINES[0] eq '%%%'.'SELFSERVICE_MACHINES'.'%%%'; + +sub check_selfservice { + foreach my $machine ( @SELFSERVICE_MACHINES ) { + unless ( _check_fsproc("selfservice-server.$SELFSERVICE_USER.$machine") ) { + $error_msg = "Self-service daemon not running for $machine"; + return 0; + } + } + return 1; +} + +sub check_sg { + my $conf = new FS::Conf; + #different trigger if they ever stop using multicustomer_hack ? + return 1 unless $conf->exists('sg-multicustomer_hack'); + + my $ua = new LWP::UserAgent; + $ua->agent("FreesideCronCheck/0.1 " . $ua->agent); + + my $USER = $conf->config('sg-ping_username'); + my $PASS = $conf->config('sg-ping_password'); + my $req = new HTTP::Request GET=>"https://$USER:$PASS\@localhost/sg/ping.cgi"; + my $res = $ua->request($req); + + return 1 if $res->is_success + && $res->content =~ /OK/ + && $res->content !~ /error/i; #doh, the error message includes "OK" + + $error_msg = $res->is_success ? $res->content : $res->status_line; + return 0; +} + +sub check_sg_login { + my $conf = new FS::Conf; + #different trigger if they ever stop using multicustomer_hack ? + return 1 unless $conf->exists('sg-multicustomer_hack'); + + my $ua = new LWP::UserAgent; + $ua->agent("FreesideCronCheck/0.1 " . $ua->agent); + + my $USER = $conf->config('sg-ping_username'); + my $PASS = $conf->config('sg-ping_password'); + my $USERNAME = $conf->config('sg-login_username'); + my $req = new HTTP::Request + GET=>"https://$USER:$PASS\@localhost/sg/start.cgi?". + 'username='. uri_escape($USERNAME); + my $res = $ua->request($req); + + return 1 if $res->is_success + && $res->content =~ /[\da-f]{32}/i #session_id + && $res->content !~ /error/i; + + $error_msg = $res->is_success ? $res->content : $res->status_line; + return 0; +} + +sub check_sgng { + my $conf = new FS::Conf; + #different trigger if they ever stop using multicustomer_hack ? + return 1 unless $conf->exists('sg-multicustomer_hack'); + + eval 'use RPC::XML; use RPC::XML::Client;'; + if ($@) { $error_msg = $@; return 0; }; + + my $cli = RPC::XML::Client->new('https://localhost/selfservice/xmlrpc.cgi'); + my $resp = $cli->send_request('FS.SelfService.XMLRPC.ping'); + + return 1 if ref($resp) + && ! $resp->is_fault + && ref($resp->value) + && $resp->value->{'pong'} == 1; + + #hua + $error_msg = ref($resp) + ? ( $resp->is_fault + ? $resp->string + : ( ref($resp->value) ? $resp->value->{'error'} + : $resp->value + ) + ) + : $resp; + return 0; +} + +sub _check_fsproc { + my $arg = shift; + _check_pidfile( "freeside-$arg.pid" ); +} + +sub _check_pidfile { + my $pidfile = shift; + open(PID, "$FS_RUN/$pidfile") or return 0; + chomp( my $pid = scalar(<PID>) ); + close PID; # or return 0; + + $pid && kill 0, $pid; +} + +sub check_apache { + my $ua = new LWP::UserAgent; + $ua->agent("FreesideCronCheck/0.1 " . $ua->agent); + + my $req = new HTTP::Request GET => 'https://localhost/'; + my $res = $ua->request($req); + + return 1 if $res->is_success || $res->status_line =~ /^403/; + $error_msg = $res->status_line; + return 0; + +} + +#and now for something entirely different... +my $num_consecutive_bop_failures = 60; +sub check_bop_failures { + + return 1 if grep { $_->statustext eq 'captured' } + qsearch({ + 'table' => 'cust_pay_pending', + 'hashref' => { 'status' => 'done' }, + 'order_by' => 'ORDER BY paypendingnum DESC'. + " LIMIT $num_consecutive_bop_failures", + }); + $error_msg = "Last $num_consecutive_bop_failures real-time payments failed"; + return 0; +} + +# + +sub error_msg { + $error_msg; +} + +sub alert { + my( $alert, @emails ) = @_; + + my $conf = new FS::Conf; + my $smtpmachine = $conf->config('smtpmachine'); + my $company_name = $conf->config('company_name'); + + foreach my $email (@emails) { + warn "warning $email about $alert\n" if $DEBUG; + + my $message = <<"__MESSAGE__"; +From: support\@freeside.biz +To: $email +Subject: FREESIDE ALERT for $company_name + +FREESIDE ALERT: $alert + +__MESSAGE__ + + my $sender = Email::Send->new({ mailer => 'SMTP' }); + $sender->mailer_args([ Host => $smtpmachine ]); + $sender->send($message); + + } + +} + +1; + |