277 lines
7.4 KiB
Perl
277 lines
7.4 KiB
Perl
package Spectre::Admin;
|
|
|
|
=head1 LEGAL
|
|
|
|
-------------------------------------------------------------------
|
|
WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
|
-------------------------------------------------------------------
|
|
Please read the legal notices (docs/legal.txt) and the license
|
|
(docs/license.txt) that came with this distribution before using
|
|
this software.
|
|
-------------------------------------------------------------------
|
|
http://www.plainblack.com info@plainblack.com
|
|
-------------------------------------------------------------------
|
|
|
|
=cut
|
|
|
|
use strict;
|
|
use HTTP::Request;
|
|
use JSON;
|
|
use Log::Log4perl;
|
|
use LWP::UserAgent;
|
|
use POE;
|
|
use POE::Component::IKC::Server;
|
|
use POE::Component::IKC::Specifier;
|
|
use Spectre::Cron;
|
|
use Spectre::Workflow;
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 _safe_shutdown ( )
|
|
|
|
Stops the kernel when TERM signal is received
|
|
|
|
=cut
|
|
|
|
sub _safe_shutdown {
|
|
my ($obj) = $_[ OBJECT ];
|
|
$obj->error('Spectre shut down');
|
|
POE::Kernel->stop;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 _start ( )
|
|
|
|
Initializes the admin interface.
|
|
|
|
=cut
|
|
|
|
sub _start {
|
|
my ( $kernel, $self, $publicEvents) = @_[ KERNEL, OBJECT, ARG0 ];
|
|
$self->debug("Starting Spectre administrative manager.");
|
|
my $serviceName = "admin";
|
|
$kernel->alias_set($serviceName);
|
|
$kernel->call( IKC => publish => $serviceName, $publicEvents );
|
|
$kernel->delay_set("loadSiteData",3);
|
|
$kernel->sig( TERM => '_safe_shutdown' );
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 config ( )
|
|
|
|
Returns a reference to the config object.
|
|
|
|
=cut
|
|
|
|
sub config {
|
|
my $self = shift;
|
|
return $self->{_config};
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 debug ( output )
|
|
|
|
Prints out debug information if debug is enabled.
|
|
|
|
=head3 output
|
|
|
|
The debug message to be printed if debug is enabled.
|
|
|
|
=cut
|
|
|
|
sub debug {
|
|
my $self = shift;
|
|
my $output = shift;
|
|
if ($self->{_debug}) {
|
|
print "ADMIN: ".$output."\n";
|
|
}
|
|
$self->getLogger->debug("ADMIN: ".$output);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 error ( output )
|
|
|
|
Prints out error information.
|
|
|
|
=head3 output
|
|
|
|
The error message to be printed if debug is enabled.
|
|
|
|
=cut
|
|
|
|
sub error {
|
|
my $self = shift;
|
|
my $output = shift;
|
|
print "ADMIN: [Error] ".$output."\n";
|
|
$self->getLogger->error("ADMIN: ".$output);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getLogger ( )
|
|
|
|
Returns a reference to the logger.
|
|
|
|
=cut
|
|
|
|
sub getLogger {
|
|
my $self = shift;
|
|
return $self->{_logger};
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 loadSiteData ( )
|
|
|
|
Fetches the site from each defined site, and loads it into the Workflow and Cron governors.
|
|
|
|
=cut
|
|
|
|
sub loadSiteData {
|
|
my ( $kernel, $self) = @_[ KERNEL, OBJECT ];
|
|
my $configs = WebGUI::Config->readAllConfigs($self->{_config}->getWebguiRoot);
|
|
$self->debug("Reading site configs.");
|
|
foreach my $key (keys %{$configs}) {
|
|
next if $key =~ m/^demo/;
|
|
$self->debug("Fetching site data for $key");
|
|
my $userAgent = new LWP::UserAgent;
|
|
if (!$self->config->get('ignoreEnvProxy')) {
|
|
$userAgent->env_proxy;
|
|
}
|
|
$userAgent->agent("Spectre");
|
|
$userAgent->timeout(30);
|
|
my $url = "http://".$configs->{$key}->get("sitename")->[0].":".$self->{_config}->get("webguiPort").$configs->{$key}->get("gateway")."?op=spectreGetSiteData";
|
|
my $request = new HTTP::Request (GET => $url);
|
|
my $response = $userAgent->request($request);
|
|
if ($response->is_error) {
|
|
$self->error( "Couldn't connect to WebGUI site $key at $url. Response: " . $response->status_line );
|
|
}
|
|
else {
|
|
my $siteData = {};
|
|
eval { $siteData = JSON::decode_json($response->content); };
|
|
if ($@) {
|
|
$self->error("Couldn't fetch Spectre configuration data for $key : $@");
|
|
}
|
|
else {
|
|
$self->debug("Loading workflow data for $key");
|
|
foreach my $instance (@{$siteData->{workflow}}) {
|
|
$kernel->post("workflow" ,"addInstance", $instance);
|
|
}
|
|
$self->debug("Loading scheduler data for $key");
|
|
foreach my $task (@{$siteData->{cron}}) {
|
|
$task->{config} = $key;
|
|
$kernel->post("cron", "addJob", $task);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 new ( config [ , debug ] )
|
|
|
|
Constructor.
|
|
|
|
=head3 config
|
|
|
|
A WebGUI::Config object that represents the spectre.conf file.
|
|
|
|
=head3 debug
|
|
|
|
A boolean indicating Spectre should spew forth debug as it runs.
|
|
|
|
=cut
|
|
|
|
sub new {
|
|
my $class = shift;
|
|
my $config = shift;
|
|
my $debug = shift;
|
|
Log::Log4perl->init( $config->getWebguiRoot."/etc/log.conf" );
|
|
$Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth+3;
|
|
my $logger = Log::Log4perl->get_logger($config->getFilename);
|
|
my $self = {_debug=>$debug, _config=>$config, _logger=>$logger};
|
|
bless $self, $class;
|
|
$self->debug("Trying to bind to ".$config->get("ip").":".$config->get("port"));
|
|
create_ikc_server(
|
|
ip => $config->get("ip"),
|
|
port => $config->get("port"),
|
|
name => 'Spectre'
|
|
);
|
|
POE::Session->create(
|
|
object_states => [ $self => {_start=>"_start", "ping"=>"ping", "loadSiteData"=>"loadSiteData", "_safe_shutdown" => "_safe_shutdown"} ],
|
|
args=>[["ping"]]
|
|
);
|
|
Spectre::Workflow->new($config, $logger, $debug);
|
|
Spectre::Cron->new($config, $logger, $debug);
|
|
POE::Kernel->run();
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 ping ( )
|
|
|
|
Check to see if Spectre is alive. Returns "pong".
|
|
|
|
=cut
|
|
|
|
sub ping {
|
|
my ($kernel, $request) = @_[KERNEL,ARG0];
|
|
my ($data, $rsvp) = @$request;
|
|
$kernel->call(IKC=>post=>$rsvp,"pong");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 runTests ( )
|
|
|
|
Executes a test to see if Spectre can establish a connection to WebGUI and get back a valid response. This is a class method.
|
|
|
|
=head3 config
|
|
|
|
A WebGUI::Config object that represents the spectre.conf file.
|
|
|
|
=cut
|
|
|
|
sub runTests {
|
|
my $class = shift;
|
|
my $config = shift;
|
|
print "Running connectivity tests.\n";
|
|
my $configs = WebGUI::Config->readAllConfigs($config->getWebguiRoot);
|
|
foreach my $key (keys %{$configs}) {
|
|
next if $key =~ m/^demo/;
|
|
print "Testing $key\n";
|
|
my $userAgent = new LWP::UserAgent;
|
|
if (!$config->get('ignoreEnvProxy')) {
|
|
$userAgent->env_proxy;
|
|
}
|
|
$userAgent->agent("Spectre");
|
|
$userAgent->timeout(30);
|
|
my $url = "http://".$configs->{$key}->get("sitename")->[0].":".$config->get("webguiPort").$configs->{$key}->get("gateway")."?op=spectreTest";
|
|
my $request = new HTTP::Request (GET => $url);
|
|
my $response = $userAgent->request($request);
|
|
if ($response->is_error) {
|
|
print "ERROR: Couldn't connect to WebGUI site $key\n";
|
|
} else {
|
|
my $response = $response->content;
|
|
if ($response eq "subnet") {
|
|
print "ERROR: Spectre cannot communicate with WebGUI. Perhaps you need to adjust the spectreSubnets setting in this config file: $key.\n";
|
|
} elsif ($response eq "spectre") {
|
|
print "ERROR: WebGUI cannot communicate with Spectre. Perhaps you need to adjust the spectreIp or spectrePort setting the this config file: $key.";
|
|
} elsif ($response ne "success") {
|
|
print "ERROR: Spectre received an invalid response ($response) from WebGUI while testing $key\n";
|
|
}
|
|
}
|
|
}
|
|
print "Tests completed.\n";
|
|
}
|
|
|
|
|
|
1;
|