#!/usr/bin/perl
#
# Exit codes;
# 0 == OK
# 1 == Host UUID not available yet.
#
# TODO:
# * Switch out XML::Simple to XML::Twig or libXML - Started in Cluster->parse_cib();
# - 15:05 < perlbot> XML::Simple commits the fatal flaw of trying to massage complicated and often
# irregular XML into the simple and highly regular world of perl data structures.
# Irregularities cause "not a hashref" sort of errors in your program. Use a real
# parser. see: xml
# - 15:06 < perlbot> Don't parse XML with regex! Use a real parser. Avoid XML::Simple (see the xml::simple
# factoid). Choices are ::Easy, ::TreeBuilder, ::Twig, Mojo::DOM (in XML mode) for
# simple stuff. LibXML is a good general purpose starting point. See also XML::All.
# http://perl-xml.sf.net/faq/
#
use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;
use NetAddr::IP;
use CGI::Carp "fatalsToBrowser";
# Turn off buffering
$| = 1;
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
$running_directory =~ s/^\./$ENV{PWD}/;
}
my $anvil = Anvil::Tools->new();
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
### NOTE: We'll print the headers only when we need to. If we print them here, it will block cookies being set.
# Setup some variables.
$anvil->data->{skin}{url} = $anvil->data->{path}{urls}{skins}."/".$anvil->Template->skin;
$anvil->data->{form}{body} = "";
$anvil->data->{form}{error_massage} = "";
$anvil->data->{form}{ok_message} = "";
$anvil->data->{form}{back_link} = "";
$anvil->data->{form}{refresh_link} = "";
# Read in any CGI variables, if needed.
$anvil->Get->cgi();
# If we're being asked to get a file, do so now.
if ($anvil->data->{cgi}{upload_file}{file_handle})
{
# Save and exit. We've got ajax handling the UI so this invocation only saves the file.
handle_upload($anvil);
$anvil->nice_exit({exit_code => 0});
}
# If the system hasn't initialized, there may be no host.uuid, and we'll need a better error to show the
# user.
if (not -e $anvil->data->{path}{data}{host_uuid})
{
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0002"}) }});
print_and_exit($anvil);
}
$anvil->Database->connect({debug => 3});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
# No databases, exit.
print $anvil->Template->get({file => "shared.html", name => "http_headers"})."\n";
print $anvil->Template->get({file => "main.html", name => "header", variables => { language => $anvil->Words->language }});
print $anvil->Words->string({key => "error_0003"});
$anvil->nice_exit({exit_code => 2});
}
# If any jobs are pending/running, show the "unavailable" option.
my $configured = $anvil->System->check_if_configured;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { configured => $configured }});
# Are we in maintenance mode?
my $available = $configured ? check_availability($anvil) : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {available => $available }});
if (not $configured)
{
# If there is no user account yet, then the system is new and needs to be reconfigured.
configure_striker($anvil);
}
elsif (not $available)
{
# Set the body to 'say::maintenance'.
$anvil->data->{form}{body} = $anvil->data->{say}{maintenance};
}
else
{
# Normal operation
process_task($anvil);
}
# Build the page to display
my $refresh_button = "";
if ($anvil->data->{form}{refresh_link})
{
$refresh_button = $anvil->Template->get({file => "main.html", name => "refresh_button_on", variables => { url => $anvil->data->{form}{refresh_link} }});
}
else
{
$refresh_button = $anvil->Template->get({file => "main.html", name => "refresh_button_off"});
}
print_and_exit($anvil);
#############################################################################################################
# Functions #
#############################################################################################################
# This handles uploading (downloading by our perspective)
sub handle_upload
{
my ($anvil) = @_;
# Get the file handle.
my $cgi_file_handle = $anvil->data->{cgi}{upload_file}{file_handle};
my $file_name = $anvil->data->{cgi}{upload_file}{file_name};
my $mime_type = $anvil->data->{cgi}{upload_file}{mime_type};
my $output_file = $anvil->data->{path}{directories}{shared}{incoming}."/".$file_name;
$output_file =~ s/\/\//\//g;
# TODO: Make sure characters like spaces and whatnot don't need to be escaped.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
cgi_file_handle => $cgi_file_handle,
file_name => $file_name,
mime_type => $mime_type,
output_file => $output_file,
}});
open (my $file_handle, ">", $output_file) or $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0015", variables => { shell_call => $output_file, error => $! }});
binmode $file_handle;
while(<$file_handle>)
{
print $cgi_file_handle $_;
}
close $file_handle;
if (not -f $output_file)
{
# Something went wrong
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0257", variables => { file => $output_file }});
}
else
{
# Looks like we got it.
my $file_size = -s $output_file;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file_size => $file_size }});
if (not $file_size)
{
# Looks like we didn't actually get the file...
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0258", variables => { file => $output_file }});
unlink $output_file;
}
else
{
my $say_size_in_bytes = $anvil->Convert->add_commas({number => $file_size});
my $say_human_size = $anvil->Convert->bytes_to_human_readable({'bytes' => $file_size});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0256", variables => {
file => $output_file,
size_in_bytes => $say_size_in_bytes,
human_readable_size => $say_human_size,
}});
}
}
return(0);
}
sub print_and_exit
{
my ($anvil) = @_;
# Time for the header
my $header = $anvil->Template->get({file => "main.html", name => "header", variables => { language => $anvil->Words->language }});
my $back_button = "";
if ($anvil->data->{form}{back_link})
{
my $url = $THIS_FILE;
if ($anvil->data->{form}{back_link} ne "?")
{
# Turn on the back button,
$url = $anvil->data->{form}{back_link};
}
$back_button = $anvil->Template->get({file => "main.html", name => "back_button_on", variables => { url => $url }});
}
else
{
# Back is disabled.
$back_button = $anvil->Template->get({file => "main.html", name => "back_button_off"});
}
my $left_buttons = $anvil->Template->get({file => "main.html", name => "button_bar_left", variables => {
back_button => $back_button,
refresh_button => $refresh_button,
}});
# The jobs button is "on" when the user is logged in and there is one or more jobs on this system
# under 100% complete.
my $say_jobs_button = $anvil->Template->get({file => "main.html", name => "jobs_button_off"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_jobs_button => $say_jobs_button }});
if (($anvil->data->{sys}{users}{user_name}) && ($anvil->Job->running({debug => 3})))
{
$say_jobs_button = $anvil->Template->get({file => "main.html", name => "jobs_button_on"});
}
my $right_buttons = $anvil->Template->get({file => "main.html", name => "button_bar_right", variables => {
anvil_button => $anvil->data->{sys}{users}{user_name} ? $anvil->Template->get({file => "main.html", name => "anvil_button_on"}) : $anvil->Template->get({file => "main.html", name => "anvil_button_off"}),
configure_button => $anvil->data->{sys}{users}{user_name} ? $anvil->Template->get({file => "main.html", name => "configure_button_on"}) : $anvil->Template->get({file => "main.html", name => "configure_button_off"}),
files_button => $anvil->data->{sys}{users}{user_name} ? $anvil->Template->get({file => "main.html", name => "files_button_on"}) : $anvil->Template->get({file => "main.html", name => "files_button_off"}),
jobs_button => $say_jobs_button,
striker_button => $anvil->data->{sys}{users}{user_name} ? $anvil->Template->get({file => "main.html", name => "striker_button_on"}) : $anvil->Template->get({file => "main.html", name => "striker_button_off"}),
email_button => $anvil->data->{sys}{users}{user_name} ? $anvil->Template->get({file => "main.html", name => "email_button_on"}) : $anvil->Template->get({file => "main.html", name => "email_button_off"}),
user_button => $anvil->data->{sys}{users}{user_name} ? $anvil->Template->get({file => "main.html", name => "user_button_on"}) : $anvil->Template->get({file => "main.html", name => "user_button_off"}),
}});
my $footer = $anvil->Template->get({file => "main.html", name => "footer", variables => {
user => $anvil->data->{sys}{users}{user_name} ? "#!string!message_0034!#" : " ",
}});
# Display the page.
my $say_center_top_bar = " ";
if ($anvil->data->{form}{error_massage})
{
$say_center_top_bar = $anvil->data->{form}{error_massage};
}
elsif ($anvil->data->{form}{ok_message})
{
$say_center_top_bar = $anvil->data->{form}{ok_message};
}
my $body = $anvil->Template->get({file => "main.html", name => "master", variables => {
header => $header,
skin_url => $anvil->data->{path}{urls}{skins}."/".$anvil->Template->skin,
center_top_bar => $say_center_top_bar,
right_top_bar => $right_buttons,
left_top_bar => $left_buttons,
center_body => $anvil->data->{form}{body},
left_bottom_bar => " ",
center_bottom_bar => " ",
right_bottom_bar => " ",
footer => $footer,
}});
print $anvil->Template->get({file => "shared.html", name => "http_headers"})."\n";
print "$body";
$anvil->nice_exit({exit_code => 0});
return(0);
}
# This handles all the daily tasks of Striker.
sub process_task
{
my ($anvil) = @_;
# Is the user trying to log in?
my $logged_in = 0;
$anvil->data->{cgi}{login}{value} = "" if not defined $anvil->data->{cgi}{login}{value};
$anvil->data->{cgi}{logout}{value} = "" if not defined $anvil->data->{cgi}{logout}{value};
$anvil->data->{cgi}{save}{value} = "" if not defined $anvil->data->{cgi}{save}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"cgi::login::value" => $anvil->data->{cgi}{login}{value},
"cgi::logout::value" => $anvil->data->{cgi}{logout}{value},
"cgi::save::value" => $anvil->data->{cgi}{save}{value},
}});
if ($anvil->data->{cgi}{login}{value})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::login::value" => $anvil->data->{cgi}{login}{value} }});
# Woot!
my $failed = $anvil->Account->login({debug => 2});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }});
if (not $failed)
{
$logged_in = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { logged_in => $logged_in }});
}
}
elsif ($anvil->data->{cgi}{logout}{value})
{
# Bye now!
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::logout::value" => $anvil->data->{cgi}{logout}{value} }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0215"});
$anvil->Account->logout({debug => 2});
}
else
{
# Is the user logged in?
# 0 - The cookies were read, the account was validated and the user's details were loaded.
# 1 - No cookie was found or read. The user needs to log in
# 2 - There was a problem reading the user's UUID (it wasn't found in the database), so the
# cookies were deleted (via C<< Account->logout() >>. The user needs to log back in.
# 3 - There user's hash is invalid, it is probably expired. The user has been logged out and
# needs to log back in.
my $cookie_problem = $anvil->Account->read_cookies();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { cookie_problem => $cookie_problem }});
if (not $cookie_problem)
{
$logged_in = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { logged_in => $logged_in }});
}
}
# Show the login screen, if the user isn't logged in.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { logged_in => $logged_in }});
if (not $logged_in)
{
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "striker-login", variables => {
user => $anvil->data->{cgi}{username}{value},
password => "",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }});
return(0);
}
# If we're here, the user is logged in!
if ($anvil->data->{cgi}{striker}{value})
{
process_striker_menu($anvil);
}
elsif ($anvil->data->{cgi}{anvil}{value})
{
process_anvil_menu($anvil);
}
elsif ($anvil->data->{cgi}{files}{value})
{
process_file_menu($anvil);
}
elsif ($anvil->data->{cgi}{jobs}{value})
{
process_jobs_menu($anvil);
}
elsif ($anvil->data->{cgi}{email}{value})
{
process_email_menu($anvil);
}
else
{
# Load the main page.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "striker-welcome"});
}
# $anvil->data->{sys}{users}{user_name} = $user_name;
# $anvil->data->{sys}{users}{user_uuid} = $user_uuid;
# $anvil->data->{sys}{users}{user_password_hash} = $user_password_hash,
# $anvil->data->{sys}{users}{user_salt} = $user_salt,
# $anvil->data->{sys}{users}{user_algorithm} = $user_algorithm,
# $anvil->data->{sys}{users}{user_hash_count} = $user_hash_count,
# $anvil->data->{sys}{users}{user_language} = $user_language,
# $anvil->data->{sys}{users}{user_is_admin} = $user_is_admin,
# $anvil->data->{sys}{users}{user_is_experienced} = $user_is_experienced,
# $anvil->data->{sys}{users}{user_is_trusted} = $user_is_trusted,
return(0);
}
# This handles tasks related to email, mail servers and alert recipients.
sub process_email_menu
{
my ($anvil) = @_;
$anvil->data->{form}{back_link} = "?email=true";
$anvil->data->{cgi}{task}{value} = "" if not defined $anvil->data->{cgi}{task}{value};
$anvil->data->{cgi}{action}{value} = "" if not defined $anvil->data->{cgi}{action}{value};
$anvil->data->{cgi}{save}{value} = "" if not defined $anvil->data->{cgi}{save}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"form::back_link" => $anvil->data->{form}{back_link},
"cgi::task::value" => $anvil->data->{cgi}{task}{value},
"cgi::action::value" => $anvil->data->{cgi}{action}{value},
"cgi::save::value" => $anvil->data->{cgi}{save}{value},
}});
if ($anvil->data->{cgi}{task}{value} eq "email_server")
{
process_email_server_page($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "email_recipient")
{
process_email_recipient_page($anvil);
}
else
{
# What we show for the reboot icon and text depends on if a reboot is pending.
my $reboot_needed = $anvil->System->reboot_needed();
my $reboot_icon = $reboot_needed ? "reboot_needed_icon.png" : "reboot_icon.png";
my $reboot_message = $reboot_needed ? "#!string!striker_0093!#" : "#!string!striker_0092!#";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
reboot_needed => $reboot_needed,
reboot_icon => $reboot_icon,
reboot_message => $reboot_message,
}});
# The 'back' goes home
$anvil->data->{form}{back_link} = "?";
$anvil->data->{form}{refresh_link} = "?email=true";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "main-menu", variables => {
}});
}
return(0);
}
# This processes mail recipients.
sub process_email_recipient_page
{
my ($anvil) = @_;
my $recipient_uuid = defined $anvil->data->{cgi}{recipient_uuid}{value} ? $anvil->data->{cgi}{recipient_uuid}{value} : "";
my $recipient_name = defined $anvil->data->{cgi}{recipient_name}{value} ? $anvil->data->{cgi}{recipient_name}{value} : "";
my $recipient_email = defined $anvil->data->{cgi}{recipient_email}{value} ? $anvil->data->{cgi}{recipient_email}{value} : "";
my $recipient_language = defined $anvil->data->{cgi}{recipient_language}{value} ? $anvil->data->{cgi}{recipient_language}{value} : "en_CA";
my $recipient_level = defined $anvil->data->{cgi}{recipient_level}{value} ? $anvil->data->{cgi}{recipient_level}{value} : "2";
my $delete = defined $anvil->data->{cgi}{'delete'}{value} ? $anvil->data->{cgi}{'delete'}{value} : "";
my $back = defined $anvil->data->{cgi}{back}{value} ? $anvil->data->{cgi}{back}{value} : "";
my $save = defined $anvil->data->{cgi}{save}{value} ? $anvil->data->{cgi}{save}{value} : "";
my $confirm = defined $anvil->data->{cgi}{confirm}{value} ? $anvil->data->{cgi}{confirm}{value} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
recipient_uuid => $recipient_uuid,
recipient_name => $recipient_name,
recipient_email => $recipient_email,
recipient_language => $recipient_language,
recipient_level => $recipient_level,
back => $back,
save => $save,
'delete' => $delete,
confirm => $confirm,
}});
if ($back)
{
$save = "";
$delete = "";
$confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
save => $save,
'delete' => $delete,
confirm => $confirm,
}});
}
# If we have a recipient_uuid and we're not saving, load the information.
if (($recipient_uuid) && (not $save))
{
# Load. If we're deleting, we'll check 'mail_server_helo_domain' to see if it already was.
my $query = "
SELECT
recipient_name,
recipient_email,
recipient_language,
recipient_level
FROM
recipients
WHERE
recipient_uuid = ".$anvil->Database->quote($recipient_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
$recipient_name = $row->[0];
$recipient_email = $row->[1];
$recipient_language = $row->[2];
$recipient_level = $row->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
recipient_name => $recipient_name,
recipient_email => $recipient_email,
recipient_language => $recipient_language,
recipient_level => $recipient_level,
}});
if ($delete)
{
# Has the user confirmed?
if ($confirm)
{
# Delete.
$anvil->Database->insert_or_update_recipients({
debug => 2,
'delete' => 1,
recipient_uuid => $recipient_uuid,
});
# Saved successfully.
my $ok_message = $anvil->Words->string({key => "ok_0003", variables => { recipient_email => $recipient_email }});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }});
# Clear the form
$recipient_name = "";
$recipient_email = "";
$recipient_language = "en_CA";
$recipient_level = "2";
}
else
{
# Ask them to confirm.
$anvil->data->{form}{back_link} = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{back_link} =~ s/save=.*?&//;
$anvil->data->{form}{back_link} =~ s/save=.*?$//;
$anvil->data->{form}{refresh_link} = "";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "recipient-delete-confirm", variables => {
recipient_name => $recipient_name,
recipient_email => $recipient_email,
recipient_uuid => $recipient_uuid,
}});
return(0);
}
}
}
}
# If we're saving, make sure we have a valid email address and a name.
if ($save)
{
# Did the user give both an email address and name?
if ((not $recipient_name) or (not $recipient_name))
{
# Which was missing?
if (not $recipient_name)
{
$anvil->data->{cgi}{recipient_name}{alert} = 1;
}
if (not $recipient_email)
{
$anvil->data->{cgi}{recipient_email}{alert} = 1;
}
$save = "";
$confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
save => $save,
confirm => $confirm,
}});
}
# Verify that the mail server and ports are sane.
if (not $anvil->Validate->email({email => $recipient_email}))
{
# Bad domain
my $error_message = $anvil->Words->string({key => "warning_0026"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }});
$anvil->data->{cgi}{recipient_email}{alert} = 1;
$save = "";
$confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
error_message => $error_message,
"form::error_massage" => $anvil->data->{form}{error_massage},
"cgi::recipient_email::alert" => $anvil->data->{cgi}{recipient_email}{alert},
save => $save,
confirm => $confirm,
}});
}
}
# Are we still saving?
if ($save)
{
# Have we confirmed?
if ($confirm)
{
($recipient_uuid) = $anvil->Database->insert_or_update_recipients({
debug => 2,
recipient_uuid => $recipient_uuid,
recipient_name => $recipient_name,
recipient_email => $recipient_email,
recipient_language => $recipient_language,
recipient_level => $recipient_level,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { recipient_uuid => $recipient_uuid }});
if ($recipient_uuid)
{
# Saved successfully.
my $ok_message = $anvil->Words->string({key => "ok_0004"});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }});
# Clear the form
$recipient_uuid = "";
$recipient_name = "";
$recipient_email = "";
$recipient_language = "en_CA";
$recipient_level = "2";
}
else
{
# Something went wrong...
my $error_message = $anvil->Words->string({key => "warning_0027"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }});
}
}
else
{
# Ignore
my $say_recipient_level = "#!string!unit_0023!#";
if ($recipient_level eq "1")
{
# Critical
$say_recipient_level = "#!string!unit_0024!#";
}
elsif ($recipient_level eq "2")
{
# Warning
$say_recipient_level = "#!string!unit_0025!#";
}
elsif ($recipient_level eq "3")
{
# Notice
$say_recipient_level = "#!string!unit_0026!#";
}
my $say_recipient_language = $anvil->Words->language({iso => $recipient_language, long => 1});
$say_recipient_language = "???" if not $say_recipient_language;
# Ask the user to confirm
$anvil->data->{form}{back_link} = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{back_link} =~ s/save=.*?&//;
$anvil->data->{form}{back_link} =~ s/save=.*?$//;
$anvil->data->{form}{refresh_link} = "";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "recipient-confirm", variables => {
recipient_uuid => $recipient_uuid,
recipient_name => $recipient_name,
recipient_email => $recipient_email,
recipient_language => $recipient_language,
say_recipient_language => $say_recipient_language,
recipient_level => $recipient_level,
say_recipient_level => $say_recipient_level,
}});
return(0);
}
}
# Get a list of existing alert recipients.
my $query = "SELECT recipient_uuid, recipient_name, recipient_email FROM recipients WHERE recipient_name != 'DELETED' ORDER BY recipient_name ASC;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
my $recipients_form = "";
if ($count)
{
# Build the list of existing mail servers
$recipients_form .= $anvil->Template->get({file => "email.html", name => "recipient-entry-open"});;
foreach my $row (@{$results})
{
my $recipient_uuid = $row->[0];
my $recipient_name = $row->[1];
my $recipient_email = $row->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
recipient_uuid => $recipient_uuid,
recipient_name => $recipient_name,
recipient_email => $recipient_email,
}});
$recipients_form .= $anvil->Template->get({file => "email.html", name => "recipient-entry", variables => {
name => $recipient_name." (".$recipient_email.")",
uuid => $recipient_uuid,
}});;
}
$recipients_form .= $anvil->Template->get({file => "email.html", name => "recipient-entry-close"});;
}
# Name
my $recipient_name_class = $anvil->data->{cgi}{recipient_name}{alert} ? "input_alert" : "input_clear";
my $recipient_name_form = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => {
name => "recipient_name",
id => "recipient_name",
field => "#!string!striker_0194!#",
description => "#!string!striker_0195!#",
value => $recipient_name,
default_value => "",
class => $recipient_name_class,
extra => "",
}});
# Email
my $recipient_email_class = $anvil->data->{cgi}{recipient_email}{alert} ? "input_alert" : "input_clear";
my $recipient_email_form = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => {
name => "recipient_email",
id => "recipient_email",
field => "#!string!striker_0196!#",
description => "#!string!striker_0197!#",
value => $recipient_email,
default_value => "",
class => $recipient_email_class,
extra => "",
}});
# Language (select)
$anvil->Words->language_list();
my $options = [];
foreach my $iso (sort {$a cmp $b} keys %{$anvil->data->{sys}{languages}})
{
push @{$options}, $iso."#!#".$anvil->data->{sys}{languages}{$iso};
}
my $recipient_language_select = $anvil->Template->select_form({
name => "recipient_language",
options => $options,
blank => 0,
selected => $recipient_language,
class => $anvil->data->{cgi}{recipient_language}{alert} ? "input_alert" : "input_clear",
});
# Log Level (select)
my $recipient_level_select = $anvil->Template->select_form({
name => "recipient_level",
options => [
"1#!#".$anvil->Words->string({key => "unit_0024"}),
"2#!#".$anvil->Words->string({key => "unit_0025"}),
"3#!#".$anvil->Words->string({key => "unit_0026"}),
"4#!#".$anvil->Words->string({key => "unit_0027"}),
"0#!#".$anvil->Words->string({key => "unit_0023"}),
],
'sort' => 0,
blank => 0,
selected => $recipient_level,
class => $anvil->data->{cgi}{recipient_level}{alert} ? "input_alert" : "input_clear",
});
# Show the menu.
$anvil->data->{form}{back_link} = "?email=true";
$anvil->data->{form}{refresh_link} = "?email=true&task=email_recipient";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "recipient-menu", variables => {
recipients => $recipients_form,
recipient_name => $recipient_name_form,
recipient_email => $recipient_email_form,
language => $recipient_language_select,
new_level => $recipient_level_select,
recipient_uuid => $recipient_uuid,
}});
return(0);
}
# This configures mail servers
sub process_email_server_page
{
my ($anvil) = @_;
# Prep the cgi variables.
my $mail_server_uuid = defined $anvil->data->{cgi}{mail_server_uuid}{value} ? $anvil->data->{cgi}{mail_server_uuid}{value} : "";
my $outgoing_mail_server = defined $anvil->data->{cgi}{outgoing_mail_server}{value} ? $anvil->data->{cgi}{outgoing_mail_server}{value} : "";
my $login_name = defined $anvil->data->{cgi}{login_name}{value} ? $anvil->data->{cgi}{login_name}{value} : "";
my $login_password = defined $anvil->data->{cgi}{login_password}{value} ? $anvil->data->{cgi}{login_password}{value} : "";
my $connection_security = defined $anvil->data->{cgi}{connection_security}{value} ? $anvil->data->{cgi}{connection_security}{value} : "ifn_link1";
my $authentication_method = defined $anvil->data->{cgi}{authentication_method}{value} ? $anvil->data->{cgi}{authentication_method}{value} : "normal_password";
my $port = defined $anvil->data->{cgi}{port}{value} ? $anvil->data->{cgi}{port}{value} : "143";
my $helo_domain = defined $anvil->data->{cgi}{helo_domain}{value} ? $anvil->data->{cgi}{helo_domain}{value} : "";
my $back = defined $anvil->data->{cgi}{back}{value} ? $anvil->data->{cgi}{back}{value} : "";
my $save = defined $anvil->data->{cgi}{save}{value} ? $anvil->data->{cgi}{save}{value} : "";
my $delete = defined $anvil->data->{cgi}{'delete'}{value} ? $anvil->data->{cgi}{'delete'}{value} : "";
my $confirm = defined $anvil->data->{cgi}{confirm}{value} ? $anvil->data->{cgi}{confirm}{value} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
outgoing_mail_server => $outgoing_mail_server,
login_name => $login_name,
login_password => $login_password,
connection_security => $connection_security,
authentication_method => $authentication_method,
back => $back,
save => $save,
'delete' => $delete,
confirm => $confirm,
}});
if ($back)
{
$save = "";
$delete = "";
$confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
save => $save,
'delete' => $delete,
confirm => $confirm,
}});
}
# Are we loading an existing record?
if (($mail_server_uuid) && not ($save))
{
# Load. If we're deleting, we'll check 'mail_server_helo_domain' to see if it already was.
my $query = "
SELECT
mail_server_address,
mail_server_authentication,
mail_server_helo_domain,
mail_server_password,
mail_server_port,
mail_server_security,
mail_server_username
FROM
mail_servers
WHERE
mail_server_uuid = ".$anvil->Database->quote($mail_server_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
$outgoing_mail_server = $row->[0];
$authentication_method = $row->[1];
$helo_domain = $row->[2];
$login_password = $row->[3];
$port = $row->[4];
$connection_security = $row->[5];
$login_name = $row->[6];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
outgoing_mail_server => $outgoing_mail_server,
authentication_method => $authentication_method,
helo_domain => $helo_domain,
login_password => $login_password,
port => $port,
connection_security => $connection_security,
login_name => $login_name,
}});
if ($delete)
{
# Has the user confirmed?
if ($confirm)
{
# Delete.
$anvil->Database->insert_or_update_mail_servers({
debug => 2,
'delete' => 1,
mail_server_uuid => $mail_server_uuid,
});
# Saved successfully.
my $ok_message = $anvil->Words->string({key => "ok_0002", variables => { mail_server => $outgoing_mail_server }});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }});
# Clear the form
$mail_server_uuid = "";
$outgoing_mail_server = "";
$login_name = "";
$login_password = "";
$connection_security = "";
$authentication_method = "";
}
else
{
# Ask them to confirm.
$anvil->data->{form}{back_link} = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{back_link} =~ s/save=.*?&//;
$anvil->data->{form}{back_link} =~ s/save=.*?$//;
$anvil->data->{form}{refresh_link} = "";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "mail-server-delete-confirm", variables => {
outgoing_mail_server => $outgoing_mail_server,
mail_server_uuid => $mail_server_uuid,
}});
return(0);
}
}
}
}
# if the user put a port on the mail server, break it off now and override any passed in port.
# Normally, the port is set via a hidden variable when the security check box is changed.
my $test_outgoing_mail_server = $outgoing_mail_server;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_outgoing_mail_server => $test_outgoing_mail_server }});
if ($test_outgoing_mail_server =~ /^(.*):(\d+)$/)
{
$test_outgoing_mail_server = $1;
$port = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
test_outgoing_mail_server => $test_outgoing_mail_server,
port => $port,
}});
}
elsif (not $port)
{
# Port wasn't passed. Use '587' unless $connection_security is 'ssl_tls'
$port = 143;
if ($connection_security eq "ssl_tls")
{
$port = 465;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { port => $port }});
}
### NOTE: For now, the HELO domain is not configurable by the user.
# If we don't have $helo_domain, use the host's domain
if (not $helo_domain)
{
$helo_domain = $anvil->Get->domain_name();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { helo_domain => $helo_domain }});
}
# Sanity check our save
if ($save)
{
# Did the user give an outgoing mail server?
if (not $outgoing_mail_server)
{
# Just silently send them back to the form.
$save = "";
$confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
save => $save,
confirm => $confirm,
}});
}
# Verify that the mail server and ports are sane.
if ((not $anvil->Validate->ipv4({ip => $test_outgoing_mail_server})) and
(not $anvil->Validate->domain_name({name => $test_outgoing_mail_server})))
{
# Bad domain
my $error_message = $anvil->Words->string({key => "warning_0023"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }});
$anvil->data->{cgi}{outgoing_mail_server}{alert} = 1;
$save = "";
$confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
error_message => $error_message,
"form::error_massage" => $anvil->data->{form}{error_massage},
"cgi::outgoing_mail_server::alert" => $anvil->data->{cgi}{outgoing_mail_server}{alert},
save => $save,
confirm => $confirm,
}});
}
if (not $anvil->Validate->port({port => $port}))
{
# Bad port
my $error_message = $anvil->Words->string({key => "warning_0024"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }});
$anvil->data->{cgi}{outgoing_mail_server}{alert} = 1;
$save = "";
$confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
error_message => $error_message,
"form::error_massage" => $anvil->data->{form}{error_massage},
"cgi::outgoing_mail_server::alert" => $anvil->data->{cgi}{outgoing_mail_server}{alert},
save => $save,
confirm => $confirm,
}});
}
}
# Still saving?
if ($save)
{
# Confirmed?
if ($confirm)
{
# Save!
($mail_server_uuid) = $anvil->Database->insert_or_update_mail_servers({
debug => 2,
mail_server_uuid => $mail_server_uuid,
mail_server_address => $test_outgoing_mail_server,
mail_server_authentication => $authentication_method,
mail_server_helo_domain => $helo_domain,
mail_server_password => $login_password,
mail_server_port => $port,
mail_server_security => $connection_security,
mail_server_username => $login_name,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mail_server_uuid => $mail_server_uuid }});
if ($mail_server_uuid)
{
# Saved successfully.
my $ok_message = $anvil->Words->string({key => "ok_0001"});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }});
# Clear the form
$mail_server_uuid = "";
$outgoing_mail_server = "";
$login_name = "";
$login_password = "";
$connection_security = "";
$authentication_method = "";
}
else
{
# Something went wrong...
my $error_message = $anvil->Words->string({key => "warning_0025"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }});
}
}
else
{
# Ask the user to confirm
$anvil->data->{form}{back_link} = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{back_link} =~ s/save=.*?&//;
$anvil->data->{form}{back_link} =~ s/save=.*?$//;
$anvil->data->{form}{refresh_link} = "";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "mail-server-confirm", variables => {
say_outgoing_mail_server => $test_outgoing_mail_server.":".$port,
outgoing_mail_server => $outgoing_mail_server,
port => $port,
login_name => $login_name,
login_password => $login_password,
connection_security => $connection_security,
authentication_method => $authentication_method,
helo_domain => $helo_domain,
mail_server_uuid => $mail_server_uuid,
}});
return(0);
}
}
# Get a list of existing mail servers.
my $query = "SELECT mail_server_uuid, mail_server_address FROM mail_servers WHERE mail_server_helo_domain != 'DELETED' ORDER BY mail_server_address ASC;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
my $mail_servers_form = "";
if ($count)
{
# Build the list of existing mail servers
$mail_servers_form .= $anvil->Template->get({file => "email.html", name => "mail-server-entry-open"});;
foreach my $row (@{$results})
{
my $mail_server_uuid = $row->[0];
my $mail_server_address = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
mail_server_uuid => $mail_server_uuid,
mail_server_address => $mail_server_address,
}});
$mail_servers_form .= $anvil->Template->get({file => "email.html", name => "mail-server-entry", variables => {
name => $mail_server_address,
uuid => $mail_server_uuid,
}});;
}
$mail_servers_form .= $anvil->Template->get({file => "email.html", name => "mail-server-entry-close"});;
}
# Outgoing mail server
my $outgoing_mail_server_class = $anvil->data->{cgi}{outgoing_mail_server}{alert} ? "input_alert" : "input_clear";
my $outgoing_mail_server_form = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => {
name => "outgoing_mail_server",
id => "outgoing_mail_server",
field => "#!string!striker_0185!#",
description => "#!string!striker_0169!#",
value => $outgoing_mail_server,
default_value => "",
class => $outgoing_mail_server_class,
extra => "",
}});
# Login name
my $login_name_class = $anvil->data->{cgi}{login_name}{alert} ? "input_alert" : "input_clear";
my $login_name_form = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => {
name => "login_name",
id => "login_name",
field => "#!string!striker_0170!#",
description => "#!string!striker_0171!#",
value => $login_name,
default_value => "",
class => $login_name_class,
extra => "",
}});
# Password
my $login_password_class = $anvil->data->{cgi}{login_password}{alert} ? "input_alert" : "input_clear";
my $login_password_form = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => {
name => "login_password",
id => "login_password",
field => "#!string!striker_0172!#",
description => "#!string!striker_0173!#",
value => $login_password,
default_value => "",
class => $login_password_class,
extra => "",
}});
# connection security
my $connection_security_select = $anvil->Template->select_form({
name => "connection_security",
options => [
"none#!#".$anvil->Words->string({key => "striker_0174"}),
"ssl_tls#!#".$anvil->Words->string({key => "striker_0175"}),
"starttls#!#".$anvil->Words->string({key => "striker_0176"})
],
blank => 0,
selected => $connection_security,
class => $anvil->data->{cgi}{connection_security}{alert} ? "input_alert" : "input_clear",
});
# Authentication method
my $authentication_method_select = $anvil->Template->select_form({
name => "authentication_method",
options => [
"normal_password#!#".$anvil->Words->string({key => "striker_0177"}),
"encrypted_password#!#".$anvil->Words->string({key => "striker_0178"}),
"kerberos_gssapi#!#".$anvil->Words->string({key => "striker_0179"}),
"ntlm#!#".$anvil->Words->string({key => "striker_0180"}),
"tls_certificate#!#".$anvil->Words->string({key => "striker_0181"}),
"oauth2#!#".$anvil->Words->string({key => "striker_0182"})
],
blank => 0,
selected => $authentication_method,
class => $anvil->data->{cgi}{authentication_method}{alert} ? "input_alert" : "input_clear",
});
# Show the menu.
$anvil->data->{form}{back_link} = "?email=true";
$anvil->data->{form}{refresh_link} = "?email=true&task=email_server";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "mail-server-menu", variables => {
mail_servers => $mail_servers_form,
outgoing_mail_server => $outgoing_mail_server_form,
login_name => $login_name_form,
login_password => $login_password_form,
connection_security => $connection_security_select,
authentication_method => $authentication_method_select,
mail_server_uuid => $mail_server_uuid,
port => $port,
}});
return(0);
}
# This handles the "Striker" menu items.
sub process_striker_menu
{
my ($anvil) = @_;
$anvil->data->{form}{back_link} = "?striker=true";
$anvil->data->{cgi}{task}{value} = "" if not defined $anvil->data->{cgi}{task}{value};
$anvil->data->{cgi}{action}{value} = "" if not defined $anvil->data->{cgi}{action}{value};
$anvil->data->{cgi}{save}{value} = "" if not defined $anvil->data->{cgi}{save}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"form::back_link" => $anvil->data->{form}{back_link},
"cgi::task::value" => $anvil->data->{cgi}{task}{value},
"cgi::action::value" => $anvil->data->{cgi}{action}{value},
"cgi::save::value" => $anvil->data->{cgi}{save}{value},
}});
if ($anvil->data->{cgi}{task}{value} eq "sync")
{
process_sync_page($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "reconfig")
{
process_reconfig_page($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "update")
{
process_update($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "install-target")
{
process_install_target($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "reboot")
{
process_power($anvil, "reboot");
}
elsif ($anvil->data->{cgi}{task}{value} eq "poweroff")
{
process_power($anvil, "poweroff");
}
elsif ($anvil->data->{cgi}{task}{value} eq "keys")
{
process_keys($anvil, "poweroff");
}
else
{
# What we show for the reboot icon and text depends on if a reboot is pending.
my $reboot_needed = $anvil->System->reboot_needed();
my $reboot_icon = $reboot_needed ? "reboot_needed_icon.png" : "reboot_icon.png";
my $reboot_message = $reboot_needed ? "#!string!striker_0093!#" : "#!string!striker_0092!#";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
reboot_needed => $reboot_needed,
reboot_icon => $reboot_icon,
reboot_message => $reboot_message,
}});
# What we show for the install target icon and text depends on if it is enabled or not.
my $install_target_title = "#!string!striker_0109!#";
my $install_target_icon = "install_target_disabled.png";
my $install_target_subtask = "unavailable";
my ($install_manifest_status, $variable_uuid, $modified_date) = $anvil->Database->read_variable({
variable_name => "install-target::enabled",
variable_source_uuid => $anvil->Get->host_uuid,
variable_source_table => "hosts",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
install_manifest_status => $install_manifest_status,
variable_uuid => $variable_uuid,
modified_date => $modified_date,
}});
if ($install_manifest_status eq "enabled")
{
# Offer the button to disable it.
$install_target_title = "#!string!striker_0108!#";
$install_target_icon = "install_target_enabled.png";
$install_target_subtask = "disable";
}
elsif ($install_manifest_status eq "disabled")
{
# Offer the button to enable it.
$install_target_title = "#!string!striker_0107!#";
$install_target_subtask = "enable";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
install_target_title => $install_target_title,
install_target_icon => $install_target_icon,
install_target_subtask => $install_target_subtask,
}});
# Are there any bad keys?
my $query = "SELECT state_uuid, state_note FROM states WHERE state_name LIKE 'host_key_changed::%';";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
results => $results,
count => $count,
}});
my $broken_key_icon = $count ? "broken_key_icon_on.png" : "broken_key_icon_off.png";
my $broken_key_message = $count ? "#!string!striker_0132!#" : "#!string!striker_0131!#";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
broken_key_icon => $broken_key_icon,
broken_key_message => $broken_key_message,
}});
# The 'back' goes home
$anvil->data->{form}{back_link} = "?";
$anvil->data->{form}{refresh_link} = "?striker=true";
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "striker-setup", variables => {
reboot_icon => $reboot_icon,
reboot_message => $reboot_message,
install_target_icon => $install_target_icon,
install_target_title => $install_target_title,
install_target_subtask => $install_target_subtask,
broken_key_icon => $broken_key_icon,
broken_key_message => $broken_key_message,
}});
}
return(0);
}
# This shows the user any running jobs.
sub process_jobs_menu
{
my ($anvil) = @_;
$anvil->data->{form}{refresh_link} = "?jobs=true";
$anvil->data->{form}{back_link} = "?striker=true";
$anvil->data->{cgi}{task}{value} = "" if not defined $anvil->data->{cgi}{task}{value};
$anvil->data->{cgi}{action}{value} = "" if not defined $anvil->data->{cgi}{action}{value};
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "jobs", variables => {
title_id => "",
message_id => "",
title => "#!string!striker_0096!#",
description => "#!string!striker_0115!#",
job_list => $anvil->Job->html_list({debug => 2, ended_within => 300}),
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'say::maintenance' => $anvil->data->{say}{maintenance} }});
return(0);
}
# This handles removing old keys.
sub process_keys
{
my ($anvil) = @_;
### NOTE: This doesn't update Striker (the Alteeve) stack yet, just the base OK.
my $show_list = 1;
$anvil->data->{cgi}{'delete'}{value} = "" if not defined $anvil->data->{cgi}{'delete'}{value};
if ($anvil->data->{cgi}{'delete'}{value})
{
# Record the job!
my $job_data = "";
foreach my $key (sort {$a cmp $b} keys %{$anvil->data->{cgi}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { key => $key }});
if ($key =~ /^state_uuid_(.*)$/)
{
my $state_uuid = $1;
$show_list = 0;
$job_data .= $state_uuid.",";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
state_uuid => $state_uuid,
show_list => $show_list,
job_data => $job_data,
}});
}
}
$job_data =~ s/,$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_data => $job_data }});
if ($job_data)
{
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
file => $THIS_FILE,
line => __LINE__,
job_command => $anvil->data->{path}{exe}{'anvil-manage-keys'}.$anvil->Log->switches,
job_data => $job_data,
job_name => "manage::broken_keys",
job_title => "job_0056",
job_description => "job_0057",
job_progress => 0,
job_host_uuid => $anvil->data->{sys}{host_uuid},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
# We don't need to store anything as hidden variables, we'll read it back from the database
# later.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => {
title_id => "",
message_id => "",
reload_url => "/cgi-bin/".$THIS_FILE,
title => "#!string!job_0056!#",
description => "#!string!job_0057!#",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }});
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { show_list => $show_list }});
if ($show_list)
{
# Get a list of bad keys we know about and ask the user which they want to remove
my $query = "
SELECT
a.state_uuid,
b.host_name,
a.state_name,
a.state_note
FROM
states a,
hosts b
WHERE
a.state_host_uuid = b.host_uuid
AND
a.state_name LIKE 'host_key_changed::%'
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
if (not $count)
{
# No bad keys found on this host.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "no-bad-keys"});
}
else
{
# Build a list of check-boxes / bad keys.
my $bad_key_list = "";
foreach my $row (@{$results})
{
my $state_uuid = $row->[0];
my $host_name = $row->[1];
my $state_name = $row->[2];
my $state_note = $row->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
state_uuid => $state_uuid,
host_name => $host_name,
state_name => $state_name,
state_note => $state_note,
}});
my $bad_file = "";
my $bad_line = "";
foreach my $pair (split/,/, $state_note)
{
my ($variable, $value) = ($pair =~ /^(.*?)=(.*)$/);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
pair => $pair,
variable => $variable,
value => $value,
}});
if ($variable eq "file")
{
$bad_file = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bad_file => $bad_file }});
}
if ($variable eq "line")
{
$bad_line = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bad_line => $bad_line }});
}
}
my ($target) = ($state_name =~ /host_key_changed::(.*)$/);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
target => $target,
bad_file => $bad_file,
bad_line => $bad_line,
}});
my $checkbox_key = "state_uuid_".$state_uuid;
my $checked = "";
if ((exists $anvil->data->{cgi}{$checkbox_key}) && ($anvil->data->{cgi}{$checkbox_key}{value}))
{
$checked = "checked";
}
$bad_key_list .= $anvil->Template->get({file => "striker.html", name => "broken-key-entry", variables => {
checkbox_name => $checkbox_key,
checkbox_checked => $checked,
target => $target,
file => $bad_file,
host => $host_name,
}});
}
#Show the screen the confirm the addition.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "broken-key-list", variables => {
bad_keys => $bad_key_list,
}});
}
}
return(0);
}
# This processes changes to files, including deletions (purges).
sub process_file_change
{
my ($anvil) = @_;
# First, clear the 'save' and 'confirm' buttons.
$anvil->data->{cgi}{save}{value} = "";
$anvil->data->{cgi}{confirm}{value} = "";
# Are we being asked to purge a file?
$anvil->Database->get_anvils();
$anvil->Database->get_files();
$anvil->Database->get_file_locations();
my $file_uuid = $anvil->data->{cgi}{file_uuid}{value};
my $file_name = $anvil->data->{files}{file_uuid}{$file_uuid}{file_name};
my $file_type = $anvil->data->{files}{file_uuid}{$file_uuid}{file_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
file_uuid => $file_uuid,
file_name => $file_name,
file_type => $file_type,
}});
if ($anvil->data->{cgi}{purge}{value})
{
# Update the file to set the file type to 'DELETED'.
my $old_file_type = $anvil->data->{files}{file_uuid}{$file_uuid}{file_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_file_type => $old_file_type }});
if ($old_file_type ne "DELETED")
{
my $query = "
UPDATE
files
SET
file_type = 'DELETED',
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
file_uuid = ".$anvil->Database->quote($file_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
}
# Register jobs on all systems to remove this file.
$anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => "all",
job_command => $anvil->data->{path}{exe}{'anvil-sync-shared'}.$anvil->Log->switches,
job_data => "file_uuid=".$file_uuid,
job_name => "storage::purge",
job_title => "job_0136",
job_description => "job_0137",
job_progress => 0,
});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => "#!string!ok_0012!#" }});
}
else
{
### Nope, we're doing other things. Possibly multiple things.
# Did the file name change?
my $ok_messages = "";
if (($anvil->data->{cgi}{new_file_name}{value}) && ($anvil->data->{cgi}{new_file_name}{value} ne $file_name))
{
# Rename the file.
my $old_file_name = $anvil->data->{files}{file_uuid}{$file_uuid}{file_name};
my $new_file_name = $anvil->data->{cgi}{new_file_name}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_file_name => $old_file_name,
new_file_name => $new_file_name,
}});
if ($old_file_name ne $new_file_name)
{
my $query = "
UPDATE
files
SET
file_name = ".$anvil->Database->quote($new_file_name).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
file_uuid = ".$anvil->Database->quote($file_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
}
$anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => "all",
job_command => $anvil->data->{path}{exe}{'anvil-sync-shared'}.$anvil->Log->switches,
job_data => "file_uuid=".$file_uuid."\nold_name=".$file_name."\nnew_name=".$anvil->data->{cgi}{new_file_name}{value},
job_name => "storage::rename",
job_title => "job_0138",
job_description => "job_0139",
job_progress => 0,
});
$ok_messages .= "#!string!ok_0013!# ";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ok_messages => $ok_messages }});
}
# Did the file type change?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::new_file_type::value" => $anvil->data->{cgi}{new_file_type}{value},
file_type => $file_type,
}});
if (($anvil->data->{cgi}{new_file_type}{value}) && ($anvil->data->{cgi}{new_file_type}{value} ne $file_type))
{
# Easy peasy, update the DBey.
my $query = "
UPDATE
files
SET
file_type = ".$anvil->Database->quote($anvil->data->{cgi}{new_file_type}{value}).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
file_uuid = ".$anvil->Database->quote($file_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
# Register a job on all machines (that have this file) to set the mode.
$anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => "all",
job_command => $anvil->data->{path}{exe}{'anvil-sync-shared'}.$anvil->Log->switches,
job_data => "file_uuid=".$file_uuid,
job_name => "storage::check_mode",
job_title => "job_0143",
job_description => "job_0144",
job_progress => 0,
});
$ok_messages .= "#!string!ok_0014!# ";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ok_messages => $ok_messages }});
}
# Loop through the Anvil! systems and see if any have changed from sync to remove or vice
# versa.
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{cgi}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable => $variable }});
if ($variable =~ /anvil_uuid::(.*?)::sync/)
{
my $anvil_uuid = $1;
my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
my $sync_value = $anvil->data->{cgi}{$variable}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
anvil_uuid => $anvil_uuid,
sync_value => $sync_value,
}});
# Coming from the CGI, sync will be 'true' or 'false', while the 'active'
# value from the database is '1' or '0'. We'll convert the database version
# for comparison versions.
my $file_location_uuid = $anvil->data->{file_locations}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_location_uuid};
my $old_file_location_active = $anvil->data->{file_locations}{file_location_uuid}{$file_location_uuid}{file_location_active} ? "true" : "false";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
file_location_uuid => $file_location_uuid,
old_file_location_active => $old_file_location_active,
}});
if ($sync_value ne $old_file_location_active)
{
# Update the database and create a job for the member nodes to purge
# the file.
my $new_active = "FALSE";
my $ok_key = "ok_0016";
my $job_type = "storage::purge";
my $job_title = "job_0136";
my $job_description = "job_0137";
if ($sync_value eq "true")
{
$new_active = "TRUE";
$ok_key = "ok_0015";
$job_type = "storage::pull_file";
$job_title = "job_0132";
$job_description = "job_0133";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
new_active => $new_active,
ok_key => $ok_key,
job_type => $job_type,
job_title => $job_title,
job_description => $job_description,
}});
$ok_messages .= $anvil->Words->string({key => $ok_key, variables => { anvil_name => $anvil_name }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ok_messages => $ok_messages }});
my $query = "
UPDATE
file_locations
SET
file_location_active = ".$anvil->Database->quote($new_active).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
file_location_uuid = ".$anvil->Database->quote($file_location_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
# Now create a job for each Anvil! member.
my $member_uuids = [];
push @{$member_uuids}, $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
push @{$member_uuids}, $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
if ($anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid})
{
push @{$member_uuids}, $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid};
}
foreach my $host_uuid (@{$member_uuids})
{
my $job_uuid = $anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => $host_uuid,
job_command => $anvil->data->{path}{exe}{'anvil-sync-shared'}.$anvil->Log->switches,
job_data => "file_uuid=".$file_uuid,
job_name => $job_type,
job_title => $job_title,
job_description => $job_description,
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
}
}
}
}
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_messages }});
}
return(0);
}
# This handles files.
sub process_file_menu
{
my ($anvil) = @_;
$anvil->data->{cgi}{action}{value} = "" if not defined $anvil->data->{cgi}{action}{value};
$anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{value};
$anvil->data->{cgi}{file_uuid}{value} = "" if not defined $anvil->data->{cgi}{file_uuid}{value};
$anvil->data->{cgi}{purge}{value} = "" if not defined $anvil->data->{cgi}{purge}{value};
$anvil->data->{cgi}{save}{value} = "" if not defined $anvil->data->{cgi}{save}{value};
$anvil->data->{cgi}{task}{value} = "" if not defined $anvil->data->{cgi}{task}{value};
$anvil->data->{form}{refresh_link} = "?files=true";
$anvil->Database->get_files();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::file_uuid::value" => $anvil->data->{cgi}{file_uuid}{value},
"cgi::save::value" => $anvil->data->{cgi}{save}{value},
"cgi::confirm::value" => $anvil->data->{cgi}{confirm}{value},
}});
if (($anvil->data->{cgi}{file_uuid}{value}) && ($anvil->data->{cgi}{save}{value}) && ($anvil->data->{cgi}{confirm}{value}))
{
process_file_change($anvil);
}
# Make sure that all files are registered with all Anvil! systems, This also (re)loads the data.
$anvil->Database->check_file_locations({debug => 2});
# Build the list of existing files.
my $file_list = $anvil->Template->get({file => "files.html", name => "open-file-list"});
foreach my $file_name (sort {$a cmp $b} keys %{$anvil->data->{files}{file_name}})
{
my $file_uuid = $anvil->data->{files}{file_name}{$file_name}{file_uuid};
my $file_size = $anvil->data->{files}{file_name}{$file_name}{file_size};
my $say_file_size = $anvil->Convert->bytes_to_human_readable({'bytes' => $file_size});
my $file_md5sum = $anvil->data->{files}{file_name}{$file_name}{file_md5sum};
my $file_type = $anvil->data->{files}{file_name}{$file_name}{file_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
file_name => $file_name,
file_uuid => $file_uuid,
file_size => $file_size." (".$say_file_size.")",
file_md5sum => $file_md5sum,
file_type => $file_type,
}});
$file_list .= $anvil->Template->get({file => "files.html", name => "file-list-entry", variables => {
file_uuid => $file_uuid,
file_name => $file_name,
file_type => $file_type,
file_size => $say_file_size,
md5sum => $file_md5sum,
}});
if ($anvil->data->{cgi}{file_uuid}{value} eq $file_uuid)
{
$anvil->data->{form}{refresh_link} = "?files=true&file_uuid=".$anvil->data->{cgi}{file_uuid}{value};
$anvil->data->{form}{back_link} = "?files=true";
$anvil->data->{cgi}{new_file_name}{value} = $file_name if not defined $anvil->data->{cgi}{new_file_name}{value};
$anvil->data->{cgi}{new_file_name}{alert} = "" if not defined $anvil->data->{cgi}{new_file_name}{alert};
$anvil->data->{cgi}{new_file_type}{value} = $file_type if not defined $anvil->data->{cgi}{new_file_type}{value};
# Build the file type select
my $file_type_options = [
"iso#!#".$anvil->Words->string({key => "type_0001"}),
"script#!#".$anvil->Words->string({key => "type_0002"}),
"other#!#".$anvil->Words->string({key => "type_0003"})
];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::new_file_type::value" => $anvil->data->{cgi}{new_file_type}{value} }});
my $select_file_type = $anvil->Template->select_form({
name => "new_file_type",
options => $file_type_options,
blank => 0,
'sort' => 1,
selected => $anvil->data->{cgi}{new_file_type}{value},
class => "input_clear",
style => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { select_file_type => $select_file_type }});
# Build the anvil list
$anvil->Database->get_anvils({debug => 3});
$anvil->Database->get_file_locations({debug => 3});
my $say_save_confirm = " ";
my $say_purge_confirm = " ";
my $anvil_list = "";
if (not exists $anvil->data->{anvils}{anvil_name})
{
$anvil_list .= $anvil->Template->get({file => "files.html", name => "file-list-manager-no-anvils"});
}
else
{
foreach my $anvil_name (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_name}})
{
my $anvil_uuid = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_uuid};
my $anvil_description = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_description};
my $file_location_uuid = $anvil->data->{file_locations}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_location_uuid};
my $synced = $anvil->data->{file_locations}{file_location_uuid}{$file_location_uuid}{file_location_active};
my $radio_key = "anvil_uuid::".$anvil_uuid."::sync";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:anvil_name" => $anvil_name,
"s2:anvil_uuid" => $anvil_uuid,
"s3:anvil_description" => $anvil_description,
"s4:file_location_uuid" => $file_location_uuid,
"s5:synced" => $synced,
"s6:radio_key" => $radio_key,
}});
$anvil->data->{cgi}{$radio_key}{value} = "" if not defined $anvil->data->{cgi}{$radio_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${radio_key}::value" => $anvil->data->{cgi}{$radio_key}{value},
}});
my $true_checked = "checked";
my $false_checked = "";
if ($anvil->data->{cgi}{$radio_key}{value})
{
if ($anvil->data->{cgi}{$radio_key}{value} eq "false")
{
$true_checked = "";
$false_checked = "checked";
}
}
elsif (not $synced)
{
$true_checked = "";
$false_checked = "checked";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:true_checked" => $true_checked,
"s2:false_checked" => $false_checked,
}});
if (($anvil->data->{cgi}{purge}{value}) && (not $anvil->data->{cgi}{confirm}{value}))
{
$say_purge_confirm = $anvil->Template->get({file => "files.html", name => "file-list-manager-confirm-purge-button", variables => {
url => "?files=true&file_uuid=".$file_uuid."&purge=true&&save=true&confirm=true",
}});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_save_confirm => $say_save_confirm }});
if (($anvil->data->{cgi}{save}{value}) && (not $anvil->data->{cgi}{confirm}{value}))
{
$say_save_confirm = $anvil->Template->get({file => "files.html", name => "file-list-manager-confirm-save-button"});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_save_confirm => $say_save_confirm }});
$anvil_list .= $anvil->Template->get({file => "files.html", name => "file-list-manager-anvil-entry", variables => {
anvil_name => $anvil_name,
anvil_description => $anvil_description,
radio_name => $radio_key,
true_checked => $true_checked,
false_checked => $false_checked,
}});
}
}
# Insert the file management section under the file entry.
$file_list .= $anvil->Template->get({file => "files.html", name => "file-list-manager", variables => {
file_uuid => $file_uuid,
new_file_name => $anvil->data->{cgi}{new_file_name}{value},
new_file_type => $select_file_type,
confirm_save_button => $say_save_confirm,
confirm_purge_button => $say_purge_confirm,
new_file_name_class => $anvil->data->{cgi}{new_file_name}{alert} ? "input_alert_fixed" : "input_clear_fixed",
anvil_list => $anvil_list,
}});
}
}
$file_list .= $anvil->Template->get({file => "files.html", name => "close-file-list"});
# The 'back' goes home
$anvil->data->{form}{back_link} = "?";
$anvil->data->{form}{body} = $anvil->Template->get({file => "files.html", name => "main-menu", variables => {
file_list => $file_list,
}});
return(0);
}
# This handles the "Anvil" menu items.
sub process_anvil_menu
{
my ($anvil) = @_;
$anvil->data->{form}{refresh_link} = "striker?anvil=true";
$anvil->data->{form}{back_link} = "?striker=true";
$anvil->data->{cgi}{task}{value} = "" if not defined $anvil->data->{cgi}{task}{value};
$anvil->data->{cgi}{action}{value} = "" if not defined $anvil->data->{cgi}{action}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
'cgi::task::value' => $anvil->data->{cgi}{task}{value},
'cgi::action::value' => $anvil->data->{cgi}{action}{value},
}});
if ($anvil->data->{cgi}{task}{value} eq "prep-host")
{
process_prep_host_page($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "prep-network")
{
process_prep_network($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "create")
{
# This handles the main "create an anvil" page.
process_create($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "fences")
{
process_fences($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "upses")
{
process_upses($anvil);
}
elsif ($anvil->data->{cgi}{task}{value} eq "manifests")
{
process_manifests($anvil);
}
else
{
# The 'back' goes home
$anvil->data->{form}{back_link} = "?";
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "main-menu", variables => {
}});
}
return(0);
}
# This handles all aspects of Install Manifests.
sub process_manifests
{
my ($anvil) = @_;
# Are we creating a new manifest?
$anvil->data->{cgi}{manifest_uuid}{value} = "" if not defined $anvil->data->{cgi}{manifest_uuid}{value};
$anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{alert};
$anvil->data->{cgi}{run}{value} = "" if not defined $anvil->data->{cgi}{run}{value};
$anvil->data->{cgi}{step}{value} = 1 if not defined $anvil->data->{cgi}{step}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
'cgi::manifest_uuid::value' => $anvil->data->{cgi}{manifest_uuid}{value},
}});
# Are we running a manifest, or creating/editing one?
if (($anvil->data->{cgi}{run}{value}) && ($anvil->Validate->uuid({uuid => $anvil->data->{cgi}{manifest_uuid}{value}})))
{
run_manifest($anvil);
}
else
{
handle_manifest($anvil);
}
return(0);
}
# This is an extension to 'handle_manifests' that specifically handles running an install manifest.
sub run_manifest
{
my ($anvil) = @_;
$anvil->data->{cgi}{description}{value} = "" if not defined $anvil->data->{cgi}{description}{value};
$anvil->data->{cgi}{description}{alert} = 0 if not defined $anvil->data->{cgi}{description}{alert};
$anvil->data->{cgi}{password}{value} = "" if not defined $anvil->data->{cgi}{password}{value};
$anvil->data->{cgi}{password}{alert} = 0 if not defined $anvil->data->{cgi}{password}{alert};
$anvil->Database->get_hosts({debug => 2});
my $manifest_uuid = $anvil->data->{cgi}{manifest_uuid}{value};
my $problem = $anvil->Striker->load_manifest({
debug => 2,
manifest_uuid => $manifest_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
manifest_uuid => $manifest_uuid,
problem => $problem,
}});
if ($problem)
{
# Report a problem and send the user back to the manifests page.
my $message = $anvil->Words->string({key => "warning_0046", variables => { uuid => $manifest_uuid }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
my $anvil_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{name};
my $prefix = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{prefix};
my $sequence = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{sequence};
my $domain = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{domain};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
anvil_name => $anvil_name,
prefix => $prefix,
sequence => $sequence,
domain => $domain,
}});
my $node1_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{name};
my $node2_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{name};
my $dr1_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{name};
if ($domain)
{
$node1_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{name}.".".$domain;
$node2_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{name}.".".$domain;
$dr1_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{name}.".".$domain;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
node1_name => $node1_name,
node2_name => $node2_name,
dr1_name => $dr1_name,
}});
my $bcn_count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{bcn};
my $sn_count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{sn};
my $ifn_count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{ifn};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
bcn_count => $bcn_count,
sn_count => $sn_count,
ifn_count => $ifn_count,
}});
# If confirmed, run!
$anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{value};
if ($anvil->data->{cgi}{confirm}{value})
{
# Make sure the passwords match.
my $problem = 0;
if (not $anvil->data->{cgi}{password1}{value})
{
# Didn't set a password
$problem = 1;
$anvil->data->{cgi}{password1}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => "#!string!warning_0047!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::password1::alert" => $anvil->data->{cgi}{password1}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
elsif (not $anvil->data->{cgi}{password2}{value})
{
# Missing both passwords
$problem = 1;
$anvil->data->{cgi}{password2}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => "#!string!warning_0048!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::password2::alert" => $anvil->data->{cgi}{password2}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
elsif ($anvil->data->{cgi}{password1}{value} ne $anvil->data->{cgi}{password2}{value})
{
$problem = 1;
$anvil->data->{cgi}{password1}{alert} = 1;
$anvil->data->{cgi}{password2}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => "#!string!warning_0049!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::password1::alert" => $anvil->data->{cgi}{password1}{alert},
"cgi::password2::alert" => $anvil->data->{cgi}{password2}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
# Check that the machines selected didn't get added to another anvil while looking.
my $node1_host_uuid = $anvil->data->{cgi}{node1_host}{value};
my $node1_host_name = $anvil->data->{sys}{hosts}{by_uuid}{$node1_host_uuid};
my $node1_anvil = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{anvil_name};
my $node2_host_uuid = $anvil->data->{cgi}{node2_host}{value};
my $node2_host_name = $anvil->data->{sys}{hosts}{by_uuid}{$node2_host_uuid};
my $node2_anvil = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{anvil_name};
my $dr1_host_uuid = $anvil->data->{cgi}{dr1_host}{value};
my $dr1_host_name = $dr1_host_uuid ? $anvil->data->{sys}{hosts}{by_uuid}{$dr1_host_uuid} : "";
my $dr1_anvil = $dr1_host_uuid ? $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}{anvil_name} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
node1_host_name => $node1_host_name,
node1_host_uuid => $node1_host_uuid,
node1_anvil => $node1_anvil,
node2_host_name => $node2_host_name,
node2_host_uuid => $node2_host_uuid,
node2_anvil => $node2_anvil,
dr1_host_name => $dr1_host_name,
dr1_host_uuid => $dr1_host_uuid,
dr1_anvil => $dr1_anvil,
}});
# Make sure the three options are unique.
if ($node1_host_uuid eq $node2_host_uuid)
{
my $message = $anvil->Words->string({key => "warning_0054"});
$problem = 1;
$anvil->data->{cgi}{node1_host}{alert} = 1;
$anvil->data->{cgi}{node2_host}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::node1_host::alert" => $anvil->data->{cgi}{node1_host}{alert},
"cgi::node2_host::alert" => $anvil->data->{cgi}{node2_host}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
if ($dr1_host_uuid)
{
if ($dr1_host_uuid eq $node1_host_uuid)
{
my $message = $anvil->Words->string({key => "warning_0055"});
$problem = 1;
$anvil->data->{cgi}{dr1_host}{alert} = 1;
$anvil->data->{cgi}{node1_host}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::dr1_host::alert" => $anvil->data->{cgi}{dr1_host}{alert},
"cgi::node1_host::alert" => $anvil->data->{cgi}{node1_host}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
elsif ($dr1_host_uuid eq $node2_host_uuid)
{
my $message = $anvil->Words->string({key => "warning_0056"});
$problem = 1;
$anvil->data->{cgi}{dr1_host}{alert} = 1;
$anvil->data->{cgi}{node2_host}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::dr1_host::alert" => $anvil->data->{cgi}{dr1_host}{alert},
"cgi::node2_host::alert" => $anvil->data->{cgi}{node2_host}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
}
if (($node1_anvil) && ($node1_anvil ne $anvil_name))
{
# The server belongs to another Anvil! system.
my $message = $anvil->Words->string({key => "warning_0050", variables => {
machine => $node1_host_name,
anvil => $anvil_name,
}});
$problem = 1;
$anvil->data->{cgi}{node1_host}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::node1_host::alert" => $anvil->data->{cgi}{node1_host}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
if (($node2_anvil) && ($node2_anvil ne $anvil_name))
{
# The server belongs to another Anvil! system.
my $message = $anvil->Words->string({key => "warning_0050", variables => {
machine => $node2_host_name,
anvil => $anvil_name,
}});
$problem = 1;
$anvil->data->{cgi}{node2_host}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::node2_host::alert" => $anvil->data->{cgi}{node2_host}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
if ($anvil->data->{cgi}{dr1_host}{value})
{
if (($dr1_anvil) && ($dr1_anvil ne $anvil_name))
{
# The server belongs to another Anvil! system.
my $message = $anvil->Words->string({key => "warning_0050", variables => {
machine => $dr1_host_name,
anvil => $anvil_name,
}});
$problem = 1;
$anvil->data->{cgi}{dr1_host}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::dr1_host::alert" => $anvil->data->{cgi}{dr1_host}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
}
if (not $problem)
{
# Record and entry in the 'anvils' table.
my ($anvil_uuid) = $anvil->Database->insert_or_update_anvils({
debug => 2,
anvil_description => $anvil->data->{cgi}{description}{value},
anvil_name => $anvil_name,
anvil_password => $anvil->data->{cgi}{password1}{value},
anvil_node1_host_uuid => $node1_host_uuid,
anvil_node2_host_uuid => $node2_host_uuid,
anvil_dr1_host_uuid => $dr1_host_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }});
# Save the jobs!
my ($node1_job_uuid) = $anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => $node1_host_uuid,
job_command => $anvil->data->{path}{exe}{'anvil-join-anvil'}.$anvil->Log->switches,
job_data => "as_machine=node1,manifest_uuid=".$manifest_uuid.",anvil_uuid=".$anvil_uuid,
job_name => "join_anvil::node1",
job_title => "job_0072",
job_description => "job_0073",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node1_job_uuid => $node1_job_uuid }});
my ($node2_job_uuid) = $anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => $node2_host_uuid,
job_command => $anvil->data->{path}{exe}{'anvil-join-anvil'}.$anvil->Log->switches,
job_data => "as_machine=node2,manifest_uuid=".$manifest_uuid.",anvil_uuid=".$anvil_uuid,
job_name => "join_anvil::node2",
job_title => "job_0072",
job_description => "job_0073",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node2_job_uuid => $node2_job_uuid }});
if ($anvil->data->{cgi}{dr1_host}{value})
{
my ($dr1_job_uuid) = $anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => $dr1_host_uuid,
job_command => $anvil->data->{path}{exe}{'anvil-join-anvil'}.$anvil->Log->switches,
job_data => "as_machine=dr1,manifest_uuid=".$manifest_uuid.",anvil_uuid=".$anvil_uuid,
job_name => "join_anvil::dr1",
job_title => "job_0072",
job_description => "job_0073",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { dr1_job_uuid => $dr1_job_uuid }});
}
# Tell them we're done and send them back to the main page.
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => "#!string!ok_0011!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::ok_message" => $anvil->data->{form}{ok_message} }});
process_create($anvil);
return(0);
}
}
# Ask the user to choose the targets and confirm the manifest settings.
my $nodes = [];
my $dr_hosts = [];
foreach my $host_uuid (keys %{$anvil->data->{hosts}{host_uuid}})
{
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
my $host_anvil = "";
if ((exists $anvil->data->{hosts}{host_uuid}{$host_uuid}) && ($anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_name} ne $anvil_name))
{
$host_anvil = $anvil_name;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid,
host_name => $host_name,
host_type => $host_type,
host_anvil => $host_anvil,
}});
# Does this host belong to another Anvil! already?
if (($host_anvil) && ($host_anvil ne $anvil_name))
{
# yup, ignore it.
next;
}
if ($host_type eq "node")
{
push @{$nodes}, $host_uuid."#!#".$host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }});
if ((not defined $anvil->data->{cgi}{node1_host}{value}) && ($host_name eq $node1_name))
{
$anvil->data->{cgi}{node1_host}{value} = $host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node1_host::value" => $anvil->data->{cgi}{node1_host}{value} }});
}
elsif ((not defined $anvil->data->{cgi}{node2_host}{value}) && ($host_name eq $node2_name))
{
$anvil->data->{cgi}{node2_host}{value} = $host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node2_host::value" => $anvil->data->{cgi}{node2_host}{value} }});
}
}
elsif ($host_type eq "dr")
{
push @{$dr_hosts}, $host_uuid."#!#".$host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }});
if ((not defined $anvil->data->{cgi}{dr1_host}{value}) && ($host_name eq $dr1_name))
{
$anvil->data->{cgi}{dr1_host}{value} = $host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::dr1_host::value" => $anvil->data->{cgi}{dr1_host}{value} }});
}
}
}
# We're going to need three selects; one for each node and one for DR. The DR is allowed to
# be unselected so it has an empty entry.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node1_host::value" => $anvil->data->{cgi}{node1_host}{value} }});
my $select_node1 = $anvil->Template->select_form({
debug => 2,
name => "node1_host",
options => $nodes,
blank => 0,
'sort' => 1,
selected => $anvil->data->{cgi}{node1_host}{value},
class => $anvil->data->{cgi}{node1_host}{alert} ? "input_alert" : "input_clear",
style => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { select_node1 => $select_node1 }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node2_host::value" => $anvil->data->{cgi}{node2_host}{value} }});
my $select_node2 = $anvil->Template->select_form({
debug => 2,
name => "node2_host",
options => $nodes,
blank => 0,
'sort' => 1,
selected => $anvil->data->{cgi}{node2_host}{value},
class => $anvil->data->{cgi}{node2_host}{alert} ? "input_alert" : "input_clear",
style => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { select_node2 => $select_node2 }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::dr1_host::value" => $anvil->data->{cgi}{dr1_host}{value} }});
my $select_dr1 = $anvil->Template->select_form({
debug => 2,
name => "dr1_host",
options => $dr_hosts,
blank => 1,
'sort' => 1,
selected => $anvil->data->{cgi}{dr1_host}{value},
class => $anvil->data->{cgi}{dr1_host}{alert} ? "input_alert" : "input_clear",
style => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { select_dr1 => $select_dr1 }});
# Show the networks.
my $networks = "";
my $default_seen = 0;
foreach my $network ("bcn", "sn", "ifn")
{
my $count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{$network};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network => $network,
count => $count,
}});
foreach my $i (1..$count)
{
my $network_name = $network.$i;
my $network_range = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{network};
my $subnet = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{subnet};
my $gateway = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{gateway};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_name => $network_name,
network_range => $network_range,
subnet => $subnet,
gateway => $gateway,
}});
my $say_default = "";
if (($network eq "ifn") && (not $default_seen) && ($gateway))
{
$default_seen = 1;
$say_default = "(#!string!striker_0249!#)";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
default_seen => $default_seen,
say_default => $say_default,
}});
}
my $network_key = "header_0036";
if ($network eq "sn") { $network_key = "header_0037"; }
elsif ($network eq "ifn") { $network_key = "header_0038"; }
$networks .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-network", variables => {
name => $anvil->Words->string({key => $network_key, variables => { number => $i }}),
network => $network_range,
subnet => $subnet,
gateway => $gateway ? $gateway : "--",
'default' => $say_default,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
}
# Pull out the IPs that will be assigned to servers.
my $machine_ips = "";
foreach my $network ("bcn", "sn", "ifn")
{
if ($network eq "sn")
{
# Inject the IPMI data.
my $node1_ipmi_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{ipmi_ip};
my $node2_ipmi_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{ipmi_ip};
my $dr1_ipmi_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{ipmi_ip};
$machine_ips .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-ip", variables => {
name => "#!string!striker_0258!#",
node1 => $node1_ipmi_ip ? $node1_ipmi_ip : "--",
node2 => $node2_ipmi_ip ? $node2_ipmi_ip : "--",
dr1 => $dr1_ipmi_ip ? $dr1_ipmi_ip : "--",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
my $count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{$network};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network => $network,
count => $count,
}});
foreach my $i (1..$count)
{
my $network_name = $network.$i;
my $node1_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{network}{$network_name}{ip};
my $node2_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{network}{$network_name}{ip};
my $dr1_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{network}{$network_name}{ip};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_name => $network_name,
node1_ip => $node1_ip,
node2_ip => $node2_ip,
dr1_ip => $dr1_ip,
}});
my $network_key = "header_0036";
if ($network eq "sn") { $network_key = "header_0037"; }
elsif ($network eq "ifn") { $network_key = "header_0038"; }
$machine_ips .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-ip", variables => {
name => $anvil->Words->string({key => $network_key, variables => { number => $i }}),
node1 => $node1_ip ? $node1_ip : "--",
node2 => $node2_ip ? $node2_ip : "--",
dr1 => $dr1_ip ? $dr1_ip : "--",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
}
my $dns = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{dns};
my $ntp = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{ntp};
my $mtu = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{mtu};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
dns => $dns,
ntp => $ntp,
mtu => $mtu,
}});
my $fences = "";
foreach my $fence_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{fence}})
{
my $node1_port = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{fence}{$fence_name}{port};
my $node2_port = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{fence}{$fence_name}{port};
my $dr1_port = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{fence}{$fence_name}{port};
$fences .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-fence", variables => {
name => $fence_name,
node1 => $node1_port ? $node1_port : "--",
node2 => $node2_port ? $node2_port : "--",
dr1 => $dr1_port ? $dr1_port : "--",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
my $upses = "";
foreach my $ups_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{ups}})
{
my $node1_uses = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{ups}{$ups_name}{used};
my $node2_uses = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{ups}{$ups_name}{used};
my $dr1_uses = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{ups}{$ups_name}{used};
$upses .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-ups", variables => {
name => $ups_name,
node1 => $node1_uses ? '#!string!unit_0001!#' : '#!string!unit_0002!#',
node2 => $node2_uses ? '#!string!unit_0001!#' : '#!string!unit_0002!#',
dr1 => $dr1_uses ? '#!string!unit_0001!#' : '#!string!unit_0002!#',
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
$anvil->data->{form}{back_link} = "?anvil=true&task=create";
$anvil->data->{form}{refresh_link} = "?anvil=true&task=manifests&run=true&manifest_uuid=".$anvil->data->{cgi}{manifest_uuid}{value};
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "run-manifest", variables => {
debug => 2,
title => $anvil->Words->string({key => "striker_0270", variables => { name => $anvil_name }}),
description => $anvil->data->{cgi}{description}{value},
description_class => $anvil->data->{cgi}{description}{alert} ? "input_alert" : "",
password => $anvil->data->{cgi}{password}{value},
password_class => $anvil->data->{cgi}{password}{alert} ? "input_alert" : "",
fences => $fences,
upses => $upses,
networks => $networks,
dns => $dns ? $dns : "8.8.8.8,8.8.4.4",
ntp => $ntp ? $ntp : "--",
mtu => $mtu ? $mtu : "1500",
select_node1 => $select_node1,
select_node2 => $select_node2,
select_dr1 => $select_dr1,
hostname_node1 => $node1_name,
hostname_node2 => $node2_name,
hostname_dr1 => $dr1_name,
machine_ips => $machine_ips,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
return(0);
}
# This handles creating or editing an Install Manifest.
sub handle_manifest
{
my ($anvil) = @_;
$anvil->data->{cgi}{step}{value} = 1 if not defined $anvil->data->{cgi}{step}{value};
$anvil->data->{cgi}{prefix}{value} = "" if not defined $anvil->data->{cgi}{prefix}{value};
$anvil->data->{cgi}{prefix}{alert} = 0 if not defined $anvil->data->{cgi}{prefix}{alert};
$anvil->data->{cgi}{domain}{value} = "" if not defined $anvil->data->{cgi}{domain}{value};
$anvil->data->{cgi}{domain}{alert} = 0 if not defined $anvil->data->{cgi}{domain}{alert};
$anvil->data->{cgi}{sequence}{value} = "" if not defined $anvil->data->{cgi}{sequence}{value};
$anvil->data->{cgi}{sequence}{alert} = 0 if not defined $anvil->data->{cgi}{sequence}{alert};
$anvil->data->{cgi}{bcn_count}{value} = 0 if not defined $anvil->data->{cgi}{bcn_count}{value};
$anvil->data->{cgi}{bcn_count}{alert} = 0 if not defined $anvil->data->{cgi}{bcn_count}{alert};
$anvil->data->{cgi}{sn_count}{value} = 0 if not defined $anvil->data->{cgi}{sn_count}{value};
$anvil->data->{cgi}{sn_count}{alert} = 0 if not defined $anvil->data->{cgi}{sn_count}{alert};
$anvil->data->{cgi}{ifn_count}{value} = 0 if not defined $anvil->data->{cgi}{ifn_count}{value};
$anvil->data->{cgi}{ifn_count}{alert} = 0 if not defined $anvil->data->{cgi}{ifn_count}{alert};
$anvil->data->{cgi}{dns}{value} = "8.8.8.8,8.8.4.4" if not defined $anvil->data->{cgi}{dns}{value};
$anvil->data->{cgi}{dns}{alert} = 0 if not defined $anvil->data->{cgi}{dns}{alert};
$anvil->data->{cgi}{ntp}{value} = "" if not defined $anvil->data->{cgi}{ntp}{value};
$anvil->data->{cgi}{ntp}{alert} = 0 if not defined $anvil->data->{cgi}{ntp}{alert};
$anvil->data->{cgi}{mtu}{value} = 1500 if not defined $anvil->data->{cgi}{mtu}{value};
$anvil->data->{cgi}{mtu}{alert} = 0 if not defined $anvil->data->{cgi}{mtu}{alert};
$anvil->data->{cgi}{'delete'}{value} = "" if not defined $anvil->data->{cgi}{'delete'}{alert};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::step::value" => $anvil->data->{cgi}{step}{value},
"cgi::prefix::value" => $anvil->data->{cgi}{prefix}{value},
"cgi::domain::value" => $anvil->data->{cgi}{domain}{value},
"cgi::sequence::value" => $anvil->data->{cgi}{sequence}{value},
"cgi::bcn_count::value" => $anvil->data->{cgi}{bcn_count}{value},
"cgi::sn_count::value" => $anvil->data->{cgi}{sn_count}{value},
"cgi::ifn_count::value" => $anvil->data->{cgi}{ifn_count}{value},
"cgi::dns::value" => $anvil->data->{cgi}{dns}{value},
"cgi::ntp::value" => $anvil->data->{cgi}{ntp}{value},
"cgi::mtu::value" => $anvil->data->{cgi}{mtu}{value},
"cgi::delete::value" => $anvil->data->{cgi}{'delete'}{value},
}});
# Are we deleting a manifest?
if (($anvil->data->{cgi}{'delete'}{value}) && ($anvil->data->{cgi}{manifest_uuid}{value}))
{
# Verify that the UUID is valid.
$anvil->Database->get_manifests({debug => 2, include_deleted => 1});
my $manifest_uuid = $anvil->data->{cgi}{manifest_uuid}{value};
my $manifest_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{manifest_name};
my $manifest_last_ran = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{manifest_last_ran};
my $manifest_xml = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{manifest_xml};
my $manifest_note = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{manifest_note};
if (not exists $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid})
{
# Doesn't exist.
my $message = $anvil->Words->string({key => "warning_0043", variables => { uuid => $manifest_uuid }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
elsif ($anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{manifest_note} eq "DELETED")
{
# Already deleted.
my $message = $anvil->Words->string({key => "warning_0044", variables => {
name => $manifest_name,
uuid => $manifest_uuid,
}});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
# Has the user confirmed?
if ($anvil->data->{cgi}{confirm}{value})
{
# Delete it
my ($manifest_uuid) = $anvil->Database->insert_or_update_manifests({
debug => 2,
manifest_uuid => $manifest_uuid,
manifest_name => $manifest_name,
manifest_last_ran => $manifest_last_ran,
manifest_xml => $manifest_xml,
manifest_note => "DELETED",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { manifest_uuid => $manifest_uuid }});
if ($manifest_uuid)
{
# Deleted successfully
my $message = $anvil->Words->string({key => "ok_0010", variables => { name => $manifest_name }});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::ok_message" => $anvil->data->{form}{ok_message} }});
}
else
{
# Something went wrong.
my $message = $anvil->Words->string({key => "warning_0045", variables => {
name => $manifest_name,
uuid => $manifest_uuid,
}});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
# Go back to the main page.
process_create($anvil);
return(0);
}
else
{
# Ask the user to confirm.
my $say_manifest = $manifest_name;
if ($manifest_note)
{
$say_manifest = $manifest_name." : ".$manifest_note;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_manifest => $say_manifest }});
$anvil->data->{form}{back_link} = "?anvil=true&task=create";
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "manifest-delete-confirm", variables => {
name => $manifest_name,
say_manifest => $say_manifest,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'form::body' => $anvil->data->{form}{body} }});
return(0);
}
}
if ($anvil->data->{cgi}{step}{value} > 1)
{
my ($sane) = sanity_check_manifest_step1($anvil);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }});
if (not $sane)
{
# Go back to the first page
$anvil->data->{cgi}{step}{value} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::step::value" => $anvil->data->{cgi}{step}{value} }});
}
elsif ($anvil->data->{cgi}{step}{value} > 2)
{
my ($sane) = sanity_check_manifest_step2($anvil);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }});
if (not $sane)
{
# Go back to the second page
$anvil->data->{cgi}{step}{value} = 2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::step::value" => $anvil->data->{cgi}{step}{value} }});
}
elsif ($anvil->data->{cgi}{step}{value} > 3)
{
my ($sane) = sanity_check_manifest_step3($anvil);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }});
if (not $sane)
{
# Go back to the third page
$anvil->data->{cgi}{step}{value} = 3;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::step::value" => $anvil->data->{cgi}{step}{value} }});
}
else
{
# Save the manifest!
my ($manifest_uuid, $manifest_name) = $anvil->Striker->generate_manifest({debug => 2});
if ($manifest_uuid)
{
# Success!
my $message = $anvil->Words->string({key => "ok_0009", variables => { name => $manifest_name }});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::ok_message" => $anvil->data->{form}{ok_message} }});
# Go back to the main page.
process_create($anvil);
return(0);
}
else
{
# Something went wrong, go back to the third page
$anvil->data->{cgi}{step}{value} = 3;
my $message = $anvil->Words->string({key => "warning_0041"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
}
}
}
}
# If we have an actual manifest_uuid, load it and preset values.
if ((exists $anvil->data->{cgi}{manifest_uuid}) && ($anvil->data->{cgi}{manifest_uuid}{value} ne "new"))
{
my $manifest_uuid = $anvil->data->{cgi}{manifest_uuid}{value};
my $failed = $anvil->Striker->load_manifest({
debug => 2,
manifest_uuid => $manifest_uuid,
});
if (not $failed)
{
# Walk through the parsed manifest and set any undefined CGI.
if ($anvil->data->{cgi}{step}{value} eq "1")
{
if ($anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{name} =~ /^(.*?)-anvil-(\d+)$/)
{
my $prefix = $1;
my $sequence = $2;
$sequence =~ s/^0+//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
prefix => $prefix,
sequence => $sequence,
}});
if (not $anvil->data->{cgi}{prefix}{value})
{
$anvil->data->{cgi}{prefix}{value} = $prefix;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::prefix::value" => $anvil->data->{cgi}{prefix}{value} }});
}
if (not $anvil->data->{cgi}{sequence}{value})
{
$anvil->data->{cgi}{sequence}{value} = $sequence;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::sequence::value" => $anvil->data->{cgi}{sequence}{value} }});
}
}
if (not $anvil->data->{cgi}{domain}{value})
{
$anvil->data->{cgi}{domain}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{domain};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::domain::value" => $anvil->data->{cgi}{domain}{value} }});
}
if (not $anvil->data->{cgi}{ifn_count}{value})
{
$anvil->data->{cgi}{ifn_count}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{ifn};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::ifn_count::value" => $anvil->data->{cgi}{ifn_count}{value} }});
}
if (not $anvil->data->{cgi}{sn_count}{value})
{
$anvil->data->{cgi}{sn_count}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{sn};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::sn_count::value" => $anvil->data->{cgi}{sn_count}{value} }});
}
if (not $anvil->data->{cgi}{bcn_count}{value})
{
$anvil->data->{cgi}{bcn_count}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{bcn};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::bcn_count::value" => $anvil->data->{cgi}{bcn_count}{value} }});
}
}
elsif ($anvil->data->{cgi}{step}{value} eq "2")
{
if (not $anvil->data->{cgi}{dns}{value})
{
$anvil->data->{cgi}{dns}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{dns};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::dns::value" => $anvil->data->{cgi}{dns}{value} }});
}
if (not $anvil->data->{cgi}{ntp}{value})
{
$anvil->data->{cgi}{ntp}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{ntp};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::ntp::value" => $anvil->data->{cgi}{ntp}{value} }});
}
if (not $anvil->data->{cgi}{mtu}{value})
{
$anvil->data->{cgi}{mtu}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{mtu};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::mtu::value" => $anvil->data->{cgi}{mtu}{value} }});
}
foreach my $network ("bcn", "sn", "ifn")
{
my $count_key = $network."_count";
foreach my $i (1..$anvil->data->{cgi}{$count_key}{value})
{
my $network_name = $network.$i;
my $network_key = $network_name."_network";
my $subnet_key = $network_name."_subnet";
my $gateway_key = $network_name."_gateway";
if (not defined $anvil->data->{cgi}{$network_key}{value})
{
$anvil->data->{cgi}{$network_key}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{network};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value} }});
}
if (not defined $anvil->data->{cgi}{$subnet_key}{value})
{
$anvil->data->{cgi}{$subnet_key}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{subnet};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value} }});
}
if (not defined $anvil->data->{cgi}{$gateway_key}{value})
{
$anvil->data->{cgi}{$gateway_key}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{gateway};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value} }});
}
}
}
}
elsif ($anvil->data->{cgi}{step}{value} eq "3")
{
foreach my $machine ("node1", "node2", "dr1")
{
my $ipmi_ip_key = $machine."_ipmi_ip";
if (not defined $anvil->data->{cgi}{$ipmi_ip_key}{value})
{
$anvil->data->{cgi}{$ipmi_ip_key}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ipmi_ip};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${ipmi_ip_key}::value" => $anvil->data->{cgi}{$ipmi_ip_key}{value} }});
}
foreach my $network ("bcn", "sn", "ifn")
{
my $count_key = $network."_count";
foreach my $i (1..$anvil->data->{cgi}{$count_key}{value})
{
my $network_name = $network.$i;
my $ip_key = $machine."_".$network_name."_ip";
if (not defined $anvil->data->{cgi}{$ip_key}{value})
{
$anvil->data->{cgi}{$ip_key}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{network}{$network_name}{ip};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${ip_key}::value" => $anvil->data->{cgi}{$ip_key}{value} }});
}
}
}
# UPSes
foreach my $ups_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ups}})
{
my $checked = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ups}{$ups_name}{used} ? "checked" : "";
my $ups_key = $machine."_ups_".$ups_name;
if (not defined $anvil->data->{cgi}{$ups_key}{value})
{
$anvil->data->{cgi}{$ups_key}{value} = $checked;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${ups_key}::value" => $anvil->data->{cgi}{$ups_key}{value} }});
}
}
# Fences
foreach my $fence_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{fence}})
{
my $fence_key = $machine."_fence_".$fence_name;
if (not defined $anvil->data->{cgi}{$fence_key}{value})
{
$anvil->data->{cgi}{$fence_key}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{fence}{$fence_name}{port};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${fence_key}::value" => $anvil->data->{cgi}{$fence_key}{value} }});
}
}
}
}
}
}
# Step 1 is to ask for the sequence number, prefix, and the number of IFNs (and later, BCNs)
if ($anvil->data->{cgi}{step}{value} eq "1")
{
if ($anvil->data->{cgi}{manifest_uuid}{value} eq "new")
{
# Pre-load values
if (not $anvil->data->{cgi}{prefix}{value})
{
$anvil->data->{cgi}{prefix}{value} = $anvil->Get->short_host_name() =~ /-/ ? $anvil->Get->short_host_name() : "xx";
$anvil->data->{cgi}{prefix}{value} =~ s/-.*$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::prefix::value" => $anvil->data->{cgi}{prefix}{value} }});
}
if (not $anvil->data->{cgi}{domain}{value})
{
$anvil->data->{cgi}{domain}{value} = $anvil->Get->host_name() =~ /\./ ? $anvil->Get->host_name() : "example.com";
$anvil->data->{cgi}{domain}{value} =~ s/^.*?\.//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::domain::value" => $anvil->data->{cgi}{domain}{value} }});
}
if (not $anvil->data->{cgi}{sequence}{value})
{
# Default to 1
$anvil->data->{cgi}{sequence}{value} = 1;
# Count the number of existing manifests! systems with the default prefix to guess the next sequence.
my $query = "SELECT manifest_name FROM manifests WHERE manifest_name LIKE ".$anvil->Database->quote($anvil->data->{cgi}{prefix}{value}."-%")." ORDER BY manifest_name ASC;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
if ($count)
{
# Yup, key has changed.
foreach my $row (@{$results})
{
my $manifest_name = $row->[0];
my $this_sequence = ($manifest_name =~ /-(\d+)$/)[0];
$this_sequence =~ s/^0//g;
$this_sequence = 0 if not $this_sequence;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
manifest_name => $manifest_name,
this_sequence => $this_sequence,
}});
if ($this_sequence >= $anvil->data->{cgi}{sequence}{value})
{
$anvil->data->{cgi}{sequence}{value} = $this_sequence + 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::sequence::value" => $anvil->data->{cgi}{sequence}{value} }});
}
}
}
}
if (not $anvil->data->{cgi}{ifn_count}{value})
{
$anvil->data->{cgi}{ifn_count}{value} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::ifn_count::value" => $anvil->data->{cgi}{ifn_count}{value} }});
}
# NOTE: The user can't choose the BCN or SN yet, but that might change so we treat it as configurable now.
if (not $anvil->data->{cgi}{sn_count}{value})
{
$anvil->data->{cgi}{sn_count}{value} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::sn_count::value" => $anvil->data->{cgi}{sn_count}{value} }});
}
if (not $anvil->data->{cgi}{bcn_count}{value})
{
$anvil->data->{cgi}{bcn_count}{value} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::bcn_count::value" => $anvil->data->{cgi}{bcn_count}{value} }});
}
}
# Step 1 menu.
$anvil->data->{form}{back_link} = "?anvil=true&task=create";
$anvil->data->{form}{refresh_link} = "?anvil=true&task=manifests&manifest_uuid=".$anvil->data->{cgi}{manifest_uuid}{value}."&step=".$anvil->data->{cgi}{step}{value};
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "manifest-step1", variables => {
title => $anvil->Words->string({key => "striker_0226", variables => { number => 1 }}),
prefix => $anvil->data->{cgi}{prefix}{value},
prefix_class => $anvil->data->{cgi}{prefix}{alert} ? "input_alert" : "",
domain => $anvil->data->{cgi}{domain}{value},
domain_class => $anvil->data->{cgi}{domain}{alert} ? "input_alert" : "",
sequence => $anvil->data->{cgi}{sequence}{value},
sequence_class => $anvil->data->{cgi}{sequence}{alert} ? "input_alert" : "",
ifn_count => $anvil->data->{cgi}{ifn_count}{value},
ifn_count_class => $anvil->data->{cgi}{ifn_count}{alert} ? "input_alert" : "",
sn_count => $anvil->data->{cgi}{sn_count}{value},
sn_count_class => $anvil->data->{cgi}{sn_count}{alert} ? "input_alert" : "",
bcn_count => $anvil->data->{cgi}{bcn_count}{value},
bcn_count_class => $anvil->data->{cgi}{bcn_count}{alert} ? "input_alert" : "",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
}
elsif ($anvil->data->{cgi}{step}{value} eq "2")
{
### Ask for the network ranges.
# Eventually, we'll support user-set BCN count. So for now, we treat as such even though it
# will always be '1' for now.
my $network_form = "";
foreach my $i (1..$anvil->data->{cgi}{bcn_count}{value})
{
my $say_bcn = $anvil->Words->string({key => "striker_0018", variables => { number => $i }});
my $network_key = "bcn".$i."_network";
my $subnet_key = "bcn".$i."_subnet";
my $gateway_key = "bcn".$i."_gateway";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_bcn => $say_bcn,
network_key => $network_key,
subnet_key => $subnet_key,
gateway_key => $gateway_key,
}});
$anvil->data->{cgi}{$network_key}{value} = "10.20".$i.".0.0" if not defined $anvil->data->{cgi}{$network_key}{value};
$anvil->data->{cgi}{$network_key}{alert} = 0 if not defined $anvil->data->{cgi}{$network_key}{alert};
$anvil->data->{cgi}{$subnet_key}{value} = "255.255.0.0" if not defined $anvil->data->{cgi}{$subnet_key}{value};
$anvil->data->{cgi}{$subnet_key}{alert} = 0 if not defined $anvil->data->{cgi}{$subnet_key}{alert};
$anvil->data->{cgi}{$gateway_key}{value} = "" if not defined $anvil->data->{cgi}{$gateway_key}{value};
$anvil->data->{cgi}{$gateway_key}{alert} = 0 if not defined $anvil->data->{cgi}{$gateway_key}{alert};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
}});
my $select = $anvil->Template->select_form({
name => $subnet_key,
options => "subnet",
blank => 0,
'sort' => 0,
selected => $anvil->data->{cgi}{$subnet_key}{value},
class => $anvil->data->{cgi}{$subnet_key}{alert} ? "input_alert" : "input_clear",
style => "width: 15em;",
});
$network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step2-network-entry", variables => {
network => $say_bcn,
network_name => $network_key,
network_class => $anvil->data->{cgi}{$network_key}{alert} ? "input_alert" : "",
network_value => $anvil->data->{cgi}{$network_key}{value},
subnet => $select,
}});
}
# There's only ever 1 SN. Just in case we change our mind later, we'll set it up as if it's
# variable.
foreach my $i (1..$anvil->data->{cgi}{bcn_count}{value})
{
my $say_sn = $anvil->Words->string({key => "striker_0020", variables => { number => '1' }});
my $network_key = "sn".$i."_network";
my $subnet_key = "sn".$i."_subnet";
my $gateway_key = "sn".$i."_gateway";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_sn => $say_sn,
network_key => $network_key,
subnet_key => $subnet_key,
gateway_key => $gateway_key,
}});
$anvil->data->{cgi}{$network_key}{value} = "10.10".$i.".0.0" if not defined $anvil->data->{cgi}{$network_key}{value};
$anvil->data->{cgi}{$network_key}{alert} = 0 if not defined $anvil->data->{cgi}{$network_key}{alert};
$anvil->data->{cgi}{$subnet_key}{value} = "255.255.0.0" if not defined $anvil->data->{cgi}{$subnet_key}{value};
$anvil->data->{cgi}{$subnet_key}{alert} = 0 if not defined $anvil->data->{cgi}{$subnet_key}{alert};
$anvil->data->{cgi}{$gateway_key}{value} = "" if not defined $anvil->data->{cgi}{$gateway_key}{value};
$anvil->data->{cgi}{$gateway_key}{alert} = 0 if not defined $anvil->data->{cgi}{$gateway_key}{alert};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::sn1_network::value" => $anvil->data->{cgi}{sn1_network}{value} }});
$network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step2-network-entry", variables => {
network => $say_sn,
network_name => $network_key,
network_class => $anvil->data->{cgi}{$network_key}{alert} ? "input_alert" : "",
network_value => $anvil->data->{cgi}{$network_key}{value},
subnet => '255.255.0.0 ',
}});
}
# Now IFNs
foreach my $i (1..$anvil->data->{cgi}{ifn_count}{value})
{
my $say_ifn = $anvil->Words->string({key => "striker_0022", variables => { number => $i }});
my $network_key = "ifn".$i."_network";
my $subnet_key = "ifn".$i."_subnet";
my $gateway_key = "ifn".$i."_gateway";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_bcn => $say_ifn,
network_key => $network_key,
subnet_key => $subnet_key,
gateway_key => $gateway_key,
}});
$anvil->data->{cgi}{$network_key}{value} = "" if not defined $anvil->data->{cgi}{$network_key}{value};
$anvil->data->{cgi}{$network_key}{alert} = 0 if not defined $anvil->data->{cgi}{$network_key}{alert};
$anvil->data->{cgi}{$subnet_key}{value} = "255.255.0.0" if not defined $anvil->data->{cgi}{$subnet_key}{value};
$anvil->data->{cgi}{$subnet_key}{alert} = 0 if not defined $anvil->data->{cgi}{$subnet_key}{alert};
$anvil->data->{cgi}{$gateway_key}{value} = "" if not defined $anvil->data->{cgi}{$gateway_key}{value};
$anvil->data->{cgi}{$gateway_key}{alert} = 0 if not defined $anvil->data->{cgi}{$gateway_key}{alert};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
}});
my $select = $anvil->Template->select_form({
name => $subnet_key,
options => "subnet",
blank => 0,
'sort' => 0,
selected => $anvil->data->{cgi}{$subnet_key}{value},
class => $anvil->data->{cgi}{$subnet_key}{alert} ? "input_alert" : "input_clear",
style => "width: 15em;",
});
$network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step2-network-entry-gateway", variables => {
network => $say_ifn,
network_name => $network_key,
network_class => $anvil->data->{cgi}{$network_key}{alert} ? "input_alert" : "",
network_value => $anvil->data->{cgi}{$network_key}{value},
subnet => $select,
gateway_name => $gateway_key,
gateway_class => $anvil->data->{cgi}{$gateway_key}{alert} ? "input_alert" : "",
gateway_value => $anvil->data->{cgi}{$gateway_key}{value},
}});
}
my $back_link = $anvil->data->{sys}{cgi_string};
$back_link =~ s/step=2/step=1/;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { back_link => $back_link}});
$anvil->data->{form}{back_link} = $back_link;
$anvil->data->{form}{refresh_link} = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "manifest-step2", variables => {
title => $anvil->Words->string({key => "striker_0226", variables => { number => 2 }}),
networks => $network_form,
dns => $anvil->data->{cgi}{dns}{value},
dns_class => $anvil->data->{cgi}{dns}{alert} ? "input_alert" : "",
ntp => $anvil->data->{cgi}{ntp}{value},
ntp_class => $anvil->data->{cgi}{ntp}{alert} ? "input_alert" : "",
mtu => $anvil->data->{cgi}{mtu}{value},
mtu_class => $anvil->data->{cgi}{mtu}{alert} ? "input_alert" : "",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
}
elsif ($anvil->data->{cgi}{step}{value} eq "3")
{
# Build and show the main manifest page!
$anvil->data->{cgi}{node1_ipmi_ip}{value} = "" if not defined $anvil->data->{cgi}{node1_ipmi_ip}{value};
$anvil->data->{cgi}{node1_ipmi_ip}{alert} = 0 if not defined $anvil->data->{cgi}{node1_ipmi_ip}{alert};
$anvil->data->{cgi}{node2_ipmi_ip}{value} = "" if not defined $anvil->data->{cgi}{node2_ipmi_ip}{value};
$anvil->data->{cgi}{node2_ipmi_ip}{alert} = 0 if not defined $anvil->data->{cgi}{node2_ipmi_ip}{alert};
$anvil->data->{cgi}{dr1_ipmi_ip}{value} = "" if not defined $anvil->data->{cgi}{dr1_ipmi_ip}{value};
$anvil->data->{cgi}{dr1_ipmi_ip}{alert} = 0 if not defined $anvil->data->{cgi}{dr1_ipmi_ip}{alert};
my $sequence = $anvil->data->{cgi}{sequence}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sequence => $sequence }});
my $network_form = "";
my $network_note = "";
foreach my $network ("bcn", "sn", "ifn")
{
if ($network eq "sn")
{
# We've finished BCN, inject the IPMI.
$network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-ipmi-entry", variables => {
node1_value => $anvil->data->{cgi}{node1_ipmi_ip}{value},
node1_class => $anvil->data->{cgi}{node1_ipmi_ip}{alert} ? "input_alert" : "",
node2_value => $anvil->data->{cgi}{node2_ipmi_ip}{value},
node2_class => $anvil->data->{cgi}{node2_ipmi_ip}{alert} ? "input_alert" : "",
dr1_value => $anvil->data->{cgi}{dr1_ipmi_ip}{value},
dr1_class => $anvil->data->{cgi}{dr1_ipmi_ip}{alert} ? "input_alert" : "",
}});
}
my $count_key = $network."_count";
foreach my $i (1..$anvil->data->{cgi}{$count_key}{value})
{
my $say_network_code = "striker_0018";
if ($network eq "sn") { $say_network_code = "striker_0020"; }
elsif ($network eq "ifn") { $say_network_code = "striker_0022"; }
my $say_network = $anvil->Words->string({key => $say_network_code, variables => { number => $i }});
my $network_key = $network.$i."_network";
my $subnet_key = $network.$i."_subnet";
my $gateway_key = $network.$i."_gateway";
my $node1_ip_key = "node1_".$network.$i."_ip";
my $node2_ip_key = "node2_".$network.$i."_ip";
my $dr1_ip_key = "dr1_".$network.$i."_ip";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_bcn => $say_network,
network_key => $network_key,
subnet_key => $subnet_key,
gateway_key => $gateway_key,
node1_ip_key => $node1_ip_key,
node2_ip_key => $node2_ip_key,
dr1_ip_key => $dr1_ip_key,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
}});
# The note also shows the network range.
my $message = $anvil->Words->string({key => "striker_0267", variables => { network => $anvil->data->{cgi}{$network_key}{value}."/".$anvil->data->{cgi}{$subnet_key}{value} }});
$network_note .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-network-note-entry", variables => {
name => $say_network,
message => $message,
}});
# On the BCN and SN, we can confidently take the first two octets from
# 'network' and add our guesses to the last two octets. We only guess the IFN
# if it's /16 or a larger subnet.
if ($anvil->data->{cgi}{$network_key}{value} =~ /^(\d{1,3}\.\d{1,3})\.0\.0/)
{
my $first_two_octets = $1;
my $ip_third_octet = 8 + (2 * $sequence); # Thanks to Leigh Nunan (@leighnunan) for this elegant sequence formula
my $host_ip = $first_two_octets.".".$ip_third_octet;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
first_two_octets => $first_two_octets,
ip_third_octet => $ip_third_octet,
host_ip => $host_ip,
}});
$anvil->data->{cgi}{$node1_ip_key}{value} = $host_ip.".1" if not defined $anvil->data->{cgi}{$node1_ip_key}{value};
$anvil->data->{cgi}{$node2_ip_key}{value} = $host_ip.".2" if not defined $anvil->data->{cgi}{$node2_ip_key}{value};
$anvil->data->{cgi}{$dr1_ip_key}{value} = $host_ip.".3" if not defined $anvil->data->{cgi}{$dr1_ip_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${node1_ip_key}::value" => $anvil->data->{cgi}{$node1_ip_key}{value},
"cgi::${node2_ip_key}::value" => $anvil->data->{cgi}{$node2_ip_key}{value},
"cgi::${dr1_ip_key}::value" => $anvil->data->{cgi}{$dr1_ip_key}{value},
}});
# If this is the BCN and $i = 1, build the IPMI IP guess.
if (($network eq "bcn") && ($i == 1))
{
my $ipmi_third_octet = 8 + (2 * $sequence) + 1;
my $ipmi_ip_guess = $first_two_octets.".".$ipmi_third_octet;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ipmi_third_octet => $ipmi_third_octet,
ipmi_ip_guess => $ipmi_ip_guess,
}});
$anvil->data->{cgi}{node1_ipmi_ip}{value} = $ipmi_ip_guess.".1" if not $anvil->data->{cgi}{node1_ipmi_ip}{value};
$anvil->data->{cgi}{node2_ipmi_ip}{value} = $ipmi_ip_guess.".2" if not $anvil->data->{cgi}{node2_ipmi_ip}{value};
$anvil->data->{cgi}{dr1_ipmi_ip}{value} = $ipmi_ip_guess.".3" if not $anvil->data->{cgi}{dr1_ipmi_ip}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::node1_ipmi_ip::value" => $anvil->data->{cgi}{node1_ipmi_ip}{value},
"cgi::node2_ipmi_ip::value" => $anvil->data->{cgi}{node2_ipmi_ip}{value},
"cgi::dr1_ipmi_ip::value" => $anvil->data->{cgi}{dr1_ipmi_ip}{value},
}});
}
}
# It should never happen, but in case the regex missed, set the guessed IPs to empty strings.
$anvil->data->{cgi}{$node1_ip_key}{value} = "" if not $anvil->data->{cgi}{$node1_ip_key}{value};
$anvil->data->{cgi}{$node2_ip_key}{value} = "" if not $anvil->data->{cgi}{$node2_ip_key}{value};
$anvil->data->{cgi}{$dr1_ip_key}{value} = "" if not $anvil->data->{cgi}{$dr1_ip_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${node1_ip_key}::value" => $anvil->data->{cgi}{$node1_ip_key}{value},
"cgi::${node2_ip_key}::value" => $anvil->data->{cgi}{$node2_ip_key}{value},
"cgi::${dr1_ip_key}::value" => $anvil->data->{cgi}{$dr1_ip_key}{value},
}});
$network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-network-entry", variables => {
network => $say_network,
network_name => $network_key,
network_value => $anvil->data->{cgi}{$network_key}{value},
subnet_name => $subnet_key,
subnet_value => $anvil->data->{cgi}{$subnet_key}{value},
gateway_name => $gateway_key,
gateway_value => $anvil->data->{cgi}{$gateway_key}{value},
node1_ip_name => $node1_ip_key,
node1_ip_value => $anvil->data->{cgi}{$node1_ip_key}{value},
node1_ip_class => $anvil->data->{cgi}{$node1_ip_key}{alert} ? "input_alert" : "",
node2_ip_name => $node2_ip_key,
node2_ip_value => $anvil->data->{cgi}{$node2_ip_key}{value},
node2_ip_class => $anvil->data->{cgi}{$node2_ip_key}{alert} ? "input_alert" : "",
dr1_ip_name => $dr1_ip_key,
dr1_ip_value => $anvil->data->{cgi}{$dr1_ip_key}{value},
dr1_ip_class => $anvil->data->{cgi}{$dr1_ip_key}{alert} ? "input_alert" : "",
}});
}
}
# List any known fence devices.
my $fence_form = "";
$anvil->Database->get_fences({});
foreach my $fence_name (sort {$a cmp $b} keys %{$anvil->data->{fences}{fence_name}})
{
### NOTE: For now, we don't care about DR fencing. As such, the code to track it is
### commented out (in case we decide to track it someday down the road).
my $fence_uuid = $anvil->data->{fences}{fence_name}{$fence_name}{fence_uuid};
my $node1_fence_key = "node1_fence_".$fence_name;
my $node2_fence_key = "node2_fence_".$fence_name;
#my $dr1_fence_key = "dr1_fence_".$fence_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
fence_name => $fence_name,
fence_uuid => $fence_uuid,
node1_fence_key => $node1_fence_key,
node2_fence_key => $node2_fence_key,
# dr1_fence_key => $dr1_fence_key,
}});
$anvil->data->{cgi}{$node1_fence_key}{value} = "" if not defined $anvil->data->{cgi}{$node1_fence_key}{value};
$anvil->data->{cgi}{$node1_fence_key}{alert} = 0 if not defined $anvil->data->{cgi}{$node1_fence_key}{alert};
$anvil->data->{cgi}{$node2_fence_key}{value} = "" if not defined $anvil->data->{cgi}{$node2_fence_key}{value};
$anvil->data->{cgi}{$node2_fence_key}{alert} = 0 if not defined $anvil->data->{cgi}{$node2_fence_key}{alert};
#$anvil->data->{cgi}{$dr1_fence_key}{value} = "" if not defined $anvil->data->{cgi}{$dr1_fence_key}{value};
#$anvil->data->{cgi}{$dr1_fence_key}{alert} = 0 if not defined $anvil->data->{cgi}{$dr1_fence_key}{alert};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${node1_fence_key}::value" => $anvil->data->{cgi}{$node1_fence_key}{value},
"cgi::${node1_fence_key}::alert" => $anvil->data->{cgi}{$node1_fence_key}{alert},
"cgi::${node2_fence_key}::value" => $anvil->data->{cgi}{$node2_fence_key}{value},
"cgi::${node2_fence_key}::alert" => $anvil->data->{cgi}{$node2_fence_key}{alert},
# "cgi::${dr1_fence_key}::value" => $anvil->data->{cgi}{$dr1_fence_key}{value},
# "cgi::${dr1_fence_key}::alert" => $anvil->data->{cgi}{$dr1_fence_key}{alert},
}});
$fence_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-fence-entry", variables => {
name => $fence_name,
fence_uuid_name => "fence_".$fence_name,
fence_uuid_value => $fence_uuid,
node1_fence_name => $node1_fence_key,
node1_fence_value => $anvil->data->{cgi}{$node1_fence_key}{value},
node1_fence_class => $anvil->data->{cgi}{$node1_fence_key}{alert} ? "input_alert" : "",
node2_fence_name => $node2_fence_key,
node2_fence_value => $anvil->data->{cgi}{$node2_fence_key}{value},
node2_fence_class => $anvil->data->{cgi}{$node2_fence_key}{alert} ? "input_alert" : "",
# dr1_fence_name => $dr1_fence_key,
# dr1_fence_value => $anvil->data->{cgi}{$dr1_fence_key}{value},
# dr1_fence_class => $anvil->data->{cgi}{$dr1_fence_key}{alert} ? "input_alert" : "",
}});
}
my $ups_form = "";
$anvil->Database->get_upses({});
my $ups_count = keys %{$anvil->data->{upses}{ups_name}};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ups_count => $ups_count }});
if (not $ups_count)
{
# No UPSes, add a blank entry.
$ups_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-ups-null-entry"});
}
foreach my $ups_name (sort {$a cmp $b} keys %{$anvil->data->{upses}{ups_name}})
{
### NOTE: For now, we don't care about DR UPSes. As such, the code to track it is
### commented out (in case we decide to track it someday down the road).
my $ups_uuid = $anvil->data->{upses}{ups_name}{$ups_name}{ups_uuid};
my $node1_ups_key = "node1_ups_".$ups_name;
my $node2_ups_key = "node2_ups_".$ups_name;
#my $dr1_ups_key = "dr1_ups_".$ups_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ups_name => $ups_name,
ups_uuid => $ups_uuid,
node1_ups_key => $node1_ups_key,
node2_ups_key => $node2_ups_key,
# dr1_ups_key => $dr1_ups_key,
}});
# Checkboxes that are not checked do not return anything at all. To deal with this,
# if we're reloading, we use 'undefined' as "not checked". Otherwise, "undefined" is
# "checked" (default).
if ((exists $anvil->data->{cgi}{reload}) && ($anvil->data->{cgi}{reload}{value}))
{
$anvil->data->{cgi}{$node1_ups_key}{value} = "" if not defined $anvil->data->{cgi}{$node1_ups_key}{value};
$anvil->data->{cgi}{$node2_ups_key}{value} = "" if not defined $anvil->data->{cgi}{$node2_ups_key}{value};
#$anvil->data->{cgi}{$dr1_ups_key}{value} = "" if not defined $anvil->data->{cgi}{$dr1_ups_key}{value};
}
else
{
$anvil->data->{cgi}{$node1_ups_key}{value} = "checked" if not defined $anvil->data->{cgi}{$node1_ups_key}{value};
$anvil->data->{cgi}{$node2_ups_key}{value} = "checked" if not defined $anvil->data->{cgi}{$node2_ups_key}{value};
#$anvil->data->{cgi}{$dr1_ups_key}{value} = "" if not defined $anvil->data->{cgi}{$dr1_ups_key}{value};
}
$anvil->data->{cgi}{$node1_ups_key}{value} = "checked" if $anvil->data->{cgi}{$node1_ups_key}{value} eq "on";
$anvil->data->{cgi}{$node2_ups_key}{value} = "checked" if $anvil->data->{cgi}{$node2_ups_key}{value} eq "on";
#$anvil->data->{cgi}{$dr1_ups_key}{value} = "checked" if $anvil->data->{cgi}{$dr1_ups_key}{value} eq "on";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${node1_ups_key}::value" => $anvil->data->{cgi}{$node1_ups_key}{value},
"cgi::${node2_ups_key}::value" => $anvil->data->{cgi}{$node2_ups_key}{value},
# "cgi::${dr1_ups_key}::value" => $anvil->data->{cgi}{$dr1_ups_key}{value},
}});
$ups_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-ups-entry", variables => {
name => $ups_name,
ups_uuid_name => "ups_".$ups_name,
ups_uuid_value => $ups_uuid,
node1_ups_name => $node1_ups_key,
node1_ups_checked => $anvil->data->{cgi}{$node1_ups_key}{value},
node2_ups_name => $node2_ups_key,
node2_ups_checked => $anvil->data->{cgi}{$node2_ups_key}{value},
# dr1_ups_name => $dr1_ups_key,
# dr1_ups_checked => $anvil->data->{cgi}{$dr1_ups_key}{value},
}});
}
my $back_link = $anvil->data->{sys}{cgi_string};
$back_link =~ s/step=3/step=2/;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { back_link => $back_link}});
$anvil->data->{form}{back_link} = $back_link;
$anvil->data->{form}{refresh_link} = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "manifest-step3", variables => {
title => $anvil->Words->string({key => "striker_0226", variables => { number => 3 }}),
networks => $network_form,
fences => $fence_form,
upses => $ups_form,
network_note => $network_note,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
}
return(0);
}
sub sanity_check_manifest_step3
{
my ($anvil) = @_;
my $sane = 1;
# Check the IPMI values. They're allowed to be blank. If they're set, they need to be in a BCN or
# IFN network.
foreach my $machine ("node1", "node2", "dr1")
{
my $key = $machine."_ipmi_ip";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
machine => $machine,
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
}});
if ($anvil->data->{cgi}{$key}{value})
{
# Is it a valid IPv4 address?
if (not $anvil->Validate->ipv4({ip => $anvil->data->{cgi}{$key}{value}}))
{
# Bad subnet
my $say_network = "#!string!striker_0255!#";
if ($machine eq "node2") { $say_network = "#!string!striker_0256!#"; }
elsif ($machine eq "dr1") { $say_network = "#!string!striker_0257!#"; }
my $message = $anvil->Words->string({key => "error_0125", variables => { network => $say_network }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${key}::alert" => $anvil->data->{cgi}{$key}{alert},
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
}});
}
else
{
# It's a valid IP. Does it match any BCN or IFN network?
my $match_found = 0;
foreach my $network ("bcn", "sn", "ifn")
{
my $count_key = $network."_count";
foreach my $i (1..$anvil->data->{cgi}{$count_key}{value})
{
next if $match_found;
my $network_key = $network.$i."_network";
my $subnet_key = $network.$i."_subnet";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
}});
$match_found = $anvil->Network->is_ip_in_network({
debug => 2,
ip => $anvil->data->{cgi}{$key}{value},
network => $anvil->data->{cgi}{$network_key}{value},
subnet_mask => $anvil->data->{cgi}{$subnet_key}{value},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_found => $match_found }});
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_found => $match_found }});
if (not $match_found)
{
# IP is valid, but not in any of the networks.
my $message = $anvil->Words->string({key => "error_0124", variables => { ip => $anvil->data->{cgi}{$key}{value} }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${key}::alert" => $anvil->data->{cgi}{$key}{alert},
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
}});
}
}
}
# Now check that the IPs are sane.
foreach my $network ("bcn", "sn", "ifn")
{
my $count_key = $network."_count";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network => $network,
count_key => $count_key,
"cgi::${count_key}::value" => $anvil->data->{cgi}{$count_key}{value},
}});
foreach my $i (1..$anvil->data->{cgi}{$count_key}{value})
{
my $say_network_code = "striker_0018";
if ($network eq "sn") { $say_network_code = "striker_0020"; }
elsif ($network eq "ifn") { $say_network_code = "striker_0022"; }
my $say_network = $anvil->Words->string({key => $say_network_code, variables => { number => $i }});
my $network_key = $network.$i."_network";
my $subnet_key = $network.$i."_subnet";
my $machine_ip_key = $machine."_".$network.$i."_ip";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_network => $say_network,
network_key => $network_key,
subnet_key => $subnet_key,
machine_ip_key => $machine_ip_key,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${machine_ip_key}::value" => $anvil->data->{cgi}{$machine_ip_key}{value},
"cgi::${machine_ip_key}::alert" => $anvil->data->{cgi}{$machine_ip_key}{alert},
}});
# Is the IP valid?
if (not $anvil->Validate->ipv4({ip => $anvil->data->{cgi}{$machine_ip_key}{value}, debug => 2}))
{
# Bad subnet
my $say_network = "#!string!striker_0255!#";
if ($machine eq "node2") { $say_network = "#!string!striker_0256!#"; }
elsif ($machine eq "dr1") { $say_network = "#!string!striker_0257!#"; }
my $message = $anvil->Words->string({key => "error_0016", variables => { network => $say_network }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$machine_ip_key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${machine_ip_key}::alert" => $anvil->data->{cgi}{$machine_ip_key}{alert},
"cgi::${machine_ip_key}::value" => $anvil->data->{cgi}{$machine_ip_key}{value},
}});
}
else
{
# It's a valid IP. Is it in the network?
my $match_found = $anvil->Network->is_ip_in_network({
debug => 2,
ip => $anvil->data->{cgi}{$machine_ip_key}{value},
network => $anvil->data->{cgi}{$network_key}{value},
subnet_mask => $anvil->data->{cgi}{$subnet_key}{value},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_found => $match_found }});
if (not $match_found)
{
# IP is valid, but not in any of the networks.
my $message = $anvil->Words->string({key => "error_0126", variables => {
ip => $anvil->data->{cgi}{$key}{value},
network => $anvil->data->{cgi}{$network_key}{value}."/".$anvil->data->{cgi}{$subnet_key}{value},
}});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${key}::alert" => $anvil->data->{cgi}{$key}{alert},
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
}});
}
}
}
}
}
### TODO: We can't (at least yet) validate ports. They could be numeric or strings... To sanity check
### this, we'll need to look up the fence agent, look up the port type, and use that to decide
### how to check. That's more than we can do for 3.0.
return($sane);
}
sub sanity_check_manifest_step2
{
my ($anvil) = @_;
my $sane = 1;
foreach my $i (1..$anvil->data->{cgi}{bcn_count}{value})
{
my $say_bcn = $anvil->Words->string({key => "striker_0018", variables => { number => $i }});
my $network_key = "bcn".$i."_network";
my $subnet_key = "bcn".$i."_subnet";
my $gateway_key = "bcn".$i."_gateway";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_key => $network_key,
subnet_key => $subnet_key,
gateway_key => $gateway_key,
}});
# The BCN doesn't support setting the netmask (for now, anyway), so we'll set it here to /16.
# If later support is added, this will pick it up.
$anvil->data->{cgi}{$subnet_key}{value} = "255.255.0.0" if not defined $anvil->data->{cgi}{$subnet_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
}});
$sane = check_network($anvil, $sane, $say_bcn, $network_key, $subnet_key, $gateway_key);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }});
}
# There's only ever 1 SN
my $say_sn = $anvil->Words->string({key => "striker_0020", variables => { number => '1' }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_sn => $say_sn }});
# The storage network always uses the subnet /16 and has no gateway.
$anvil->data->{cgi}{sn1_subnet}{value} = "255.255.0.0" if not defined $anvil->data->{cgi}{sn1_subnet}{value};
$anvil->data->{cgi}{sn1_gateway}{value} = "" if not defined $anvil->data->{cgi}{sn1_gateway}{value};
$sane = check_network($anvil, $sane, $say_sn, "sn1_network", "sn1_subnet", "sn1_gateway");
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }});
# Now IFNs
foreach my $i (1..$anvil->data->{cgi}{ifn_count}{value})
{
my $say_ifn = $anvil->Words->string({key => "striker_0022", variables => { number => $i }});
my $network_key = "ifn".$i."_network";
my $subnet_key = "ifn".$i."_subnet";
my $gateway_key = "ifn".$i."_gateway";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_bcn => $say_ifn,
network_key => $network_key,
subnet_key => $subnet_key,
gateway_key => $gateway_key,
}});
$anvil->data->{cgi}{$network_key}{value} = "" if not defined $anvil->data->{cgi}{$network_key}{value};
$anvil->data->{cgi}{$network_key}{alert} = 0 if not defined $anvil->data->{cgi}{$network_key}{alert};
$anvil->data->{cgi}{$subnet_key}{value} = "255.255.0.0" if not defined $anvil->data->{cgi}{$subnet_key}{value};
$anvil->data->{cgi}{$subnet_key}{alert} = 0 if not defined $anvil->data->{cgi}{$subnet_key}{alert};
$anvil->data->{cgi}{$gateway_key}{value} = "" if not defined $anvil->data->{cgi}{$gateway_key}{value};
$anvil->data->{cgi}{$gateway_key}{alert} = 0 if not defined $anvil->data->{cgi}{$gateway_key}{alert};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
}});
$sane = check_network($anvil, $sane, $say_ifn, $network_key, $subnet_key, $gateway_key);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }});
}
# If DNS is specified, make sure it/they are valid.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::dns::value" => $anvil->data->{cgi}{dns}{value} }});
if ($anvil->data->{cgi}{dns}{value})
{
foreach my $ip (split/,/, $anvil->data->{cgi}{dns}{value})
{
$ip =~ s/^\s+//;
$ip =~ s/\s+$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ip => $ip }});
if (not $anvil->Validate->ipv4({ip => $ip}))
{
# Bad network
my $message = $anvil->Words->string({key => "error_0015"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{dns}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
ip => $ip,
"cgi::dns::alert" => $anvil->data->{cgi}{dns}{alert},
"cgi::dns::value" => $anvil->data->{cgi}{dns}{value},
}});
}
}
}
# If NTP is specified, make sure it/they are valid.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::ntp::value" => $anvil->data->{cgi}{ntp}{value} }});
if ($anvil->data->{cgi}{ntp}{value})
{
foreach my $ip (split/,/, $anvil->data->{cgi}{ntp}{value})
{
$ip =~ s/^\s+//;
$ip =~ s/\s+$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ip => $ip }});
if (not $anvil->Validate->ipv4({ip => $ip}))
{
# Bad network
my $message = $anvil->Words->string({key => "error_0122"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{ntp}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
ip => $ip,
"cgi::ntp::alert" => $anvil->data->{cgi}{ntp}{alert},
"cgi::ntp::value" => $anvil->data->{cgi}{ntp}{value},
}});
}
}
}
# Make sure the MTU is sane
if (not $anvil->Validate->positive_integer({number => $anvil->data->{cgi}{mtu}{value}}))
{
my $message = $anvil->Words->string({key => "error_0123"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{mtu}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::mtu::alert" => $anvil->data->{cgi}{mtu}{alert},
"cgi::mtu::value" => $anvil->data->{cgi}{mtu}{value},
}});
}
return($sane);
}
### TODO: Make this a Validate module
sub check_network
{
my ($anvil, $sane, $say_network, $network_key, $subnet_key, $gateway_key) = @_;
# Make sure the network and subnet are valid
my $local_sane = 1;
if (not $anvil->Validate->ipv4({ip => $anvil->data->{cgi}{$network_key}{value}}))
{
# Bad network
my $message = $anvil->Words->string({key => "error_0020", variables => { field => $say_network." - #!string!striker_0149!#" }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$network_key}{alert} = 1;
$sane = 0;
$local_sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
local_sane => $local_sane,
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
}});
}
if (not $anvil->Validate->ipv4({ip => $anvil->data->{cgi}{$subnet_key}{value}}))
{
# Bad subnet
my $message = $anvil->Words->string({key => "error_0020", variables => { field => $say_network." - #!string!striker_0025!#" }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$subnet_key}{alert} = 1;
$sane = 0;
$local_sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
local_sane => $local_sane,
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
}});
}
# The gateway can be blank
if (($anvil->data->{cgi}{$gateway_key}{value}) && (not $anvil->Validate->ipv4({ip => $anvil->data->{cgi}{$gateway_key}{value}})))
{
# It's not a valid IP.
my $message = $anvil->Words->string({key => "error_0118", variables => { ip => $anvil->data->{cgi}{$gateway_key}{value} }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$gateway_key}{alert} = 1;
$sane = 0;
$local_sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
local_sane => $local_sane,
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
}});
}
# If I'm still sane, make sure that the network is actually the bottom of the subnet.
if ($local_sane)
{
my $test_network = $anvil->Network->get_network({ip => $anvil->data->{cgi}{$network_key}{value}, subnet_mask => $anvil->data->{cgi}{$subnet_key}{value}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { test_network => $test_network }});
if (not $test_network)
{
# Something is invalid.
my $message = $anvil->Words->string({key => "error_0120", variables => {
network => $anvil->data->{cgi}{$network_key}{value},
subnet => $anvil->data->{cgi}{$subnet_key}{value},
}});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$network_key}{alert} = 1;
$anvil->data->{cgi}{$subnet_key}{alert} = 1;
$sane = 0;
$local_sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
local_sane => $local_sane,
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
}});
}
elsif ($test_network ne $anvil->data->{cgi}{$network_key}{value})
{
# The user didn't give the base IP of the network.
my $message = $anvil->Words->string({key => "error_0119", variables => {
name => $say_network,
ip => $test_network,
}});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$network_key}{alert} = 1;
$sane = 0;
$local_sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
local_sane => $local_sane,
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
}});
}
# Lastly, if we've got a gateway, make sure it's in the network.
if (($local_sane) && ($anvil->data->{cgi}{$gateway_key}{value}))
{
my $base_ip = $anvil->Network->get_network({ip => $anvil->data->{cgi}{$gateway_key}{value}, subnet_mask => $anvil->data->{cgi}{$subnet_key}{value}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { base_ip => $base_ip }});
if ($base_ip ne $anvil->data->{cgi}{$network_key}{value})
{
# The gateway is not in the subnet
my $message = $anvil->Words->string({key => "error_0121", variables => {
gateway => $anvil->data->{cgi}{$gateway_key}{value},
network => $anvil->data->{cgi}{$network_key}{value},
subnet => $anvil->data->{cgi}{$subnet_key}{value},
}});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$gateway_key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
}});
}
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }});
return($sane);
}
sub sanity_check_manifest_step1
{
my ($anvil) = @_;
my $sane = 1;
if ((not $anvil->Validate->alphanumeric({string => $anvil->data->{cgi}{prefix}{value}})) or (length($anvil->data->{cgi}{prefix}{value}) > 5))
{
my $message = $anvil->Words->string({key => "error_0020", variables => { field => "#!string!striker_0228!#" }});
if ($anvil->data->{cgi}{prefix}{value})
{
$message = $anvil->Words->string({key => "error_0021"});
}
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{prefix}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::prefix::alert" => $anvil->data->{cgi}{prefix}{alert},
"cgi::prefix::value" => $anvil->data->{cgi}{prefix}{value},
}});
}
# We can use Validate to check the domain.
if (not $anvil->Validate->domain_name({name => $anvil->data->{cgi}{domain}{value}, debug => 2}))
{
my $message = $anvil->Words->string({key => "error_0020", variables => { field => "#!string!striker_0007!#" }});
if ($anvil->data->{cgi}{domain}{value})
{
$message = $anvil->Words->string({key => "error_0117", variables => { name => $anvil->data->{cgi}{domain}{value} }});
}
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{domain}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::domain::alert" => $anvil->data->{cgi}{domain}{alert},
"cgi::domain::value" => $anvil->data->{cgi}{domain}{value},
}});
}
# The sequence and IFN count need to be integers.
if (not $anvil->Validate->positive_integer({number => $anvil->data->{cgi}{sequence}{value}}))
{
my $message = $anvil->Words->string({key => "error_0020", variables => { field => "#!string!striker_0009!#" }});
if ($anvil->data->{cgi}{sequence}{value})
{
$message = $anvil->Words->string({key => "error_0022", variables => { field => "#!string!striker_0009!#" }});
}
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{sequence}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::sequence::alert" => $anvil->data->{cgi}{sequence}{alert},
"cgi::sequence::value" => $anvil->data->{cgi}{sequence}{value},
}});
}
if (not $anvil->Validate->positive_integer({number => $anvil->data->{cgi}{ifn_count}{value}}))
{
my $message = $anvil->Words->string({key => "error_0020", variables => { field => "#!string!striker_0230!#" }});
if ($anvil->data->{cgi}{ifn_count}{value})
{
$message = $anvil->Words->string({key => "error_0022", variables => { field => "#!string!striker_0230!#" }});
}
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{ifn_count}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::ifn_count::alert" => $anvil->data->{cgi}{ifn_count}{alert},
"cgi::ifn_count::value" => $anvil->data->{cgi}{ifn_count}{value},
}});
}
return($sane);
}
# Show the create manifest (and Fence devices and UPSes) menu
sub process_create
{
my ($anvil) = @_;
# Show existing manifests.
$anvil->Database->get_manifests();
my $manifest_template = "";
foreach my $manifest_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_name}})
{
my $manifest_uuid = $anvil->data->{manifests}{manifest_name}{$manifest_name}{manifest_uuid};
my $manifest_last_ran = $anvil->data->{manifests}{manifest_name}{$manifest_name}{manifest_last_ran};
my $manifest_xml = $anvil->data->{manifests}{manifest_name}{$manifest_name}{manifest_xml};
my $manifest_note = $anvil->data->{manifests}{manifest_name}{$manifest_name}{manifest_note};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
manifest_uuid => $manifest_uuid,
manifest_name => $manifest_name,
manifest_last_ran => $manifest_last_ran,
manifest_xml => $manifest_xml,
manifest_note => $manifest_note,
}});
$manifest_template .= $anvil->Template->get({file => "anvil.html", name => "create-menu-existing-manifest-entry", variables => {
manifest_uuid => $manifest_uuid,
manifest_name => $manifest_name,
}});
}
# Store the previous CGI variables and display the new fields.
$anvil->data->{form}{back_link} = "?anvil=true";
$anvil->data->{form}{refresh_link} = "?anvil=true&task=create";
$anvil->data->{cgi}{task}{value} = "" if not defined $anvil->data->{cgi}{task}{value};
$anvil->data->{cgi}{subtask}{value} = "" if not defined $anvil->data->{cgi}{subtask}{value};
$anvil->data->{cgi}{action}{value} = "" if not defined $anvil->data->{cgi}{action}{value};
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "create-menu", variables => {
existing_manifests => $manifest_template,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
return(0);
}
# This allows the user to tell us about upses.
sub process_upses
{
my ($anvil) = @_;
# Pull the data of supported UPSes out of the specual 'ups_X' strings.
$anvil->Striker->get_ups_data({debug => 3});
foreach my $key (sort {$a cmp $b} keys %{$anvil->data->{ups_data}})
{
my $agent = $anvil->data->{ups_data}{$key}{agent};
my $brand = $anvil->data->{ups_data}{$key}{brand};
my $description = $anvil->data->{ups_data}{$key}{description};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"s1:key" => $key,
"s2:agent" => $anvil->data->{ups_data}{$key}{agent},
"s3:brand" => $anvil->data->{ups_data}{$key}{brand},
"s4:description" => $anvil->data->{ups_data}{$key}{description},
}});
}
$anvil->data->{cgi}{ups_agent}{value} = "" if not defined $anvil->data->{cgi}{ups_agent}{value};
$anvil->data->{cgi}{ups_count}{value} = 1 if not defined $anvil->data->{cgi}{ups_count}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::ups_agent::value" => $anvil->data->{cgi}{ups_agent}{value},
"cgi::ups_count::value" => $anvil->data->{cgi}{ups_count}{value},
}});
# Are we going back to the form?
if ($anvil->data->{cgi}{back}{value})
{
$anvil->data->{cgi}{save}{value} = "";
$anvil->data->{cgi}{confirm}{value} = "";
$anvil->data->{cgi}{delete_ups_uuid}{value} = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::save::value" => $anvil->data->{cgi}{save}{value},
"cgi::confirm::value" => $anvil->data->{cgi}{confirm}{value},
"cgi::delete_ups_uuid::value" => $anvil->data->{cgi}{delete_ups_uuid}{value},
}});
}
# Are we deleting an agent?
if ((exists $anvil->data->{cgi}{delete_ups_uuid}) && ($anvil->data->{cgi}{delete_ups_uuid}{value}))
{
# Verify that the UUID is valid.
$anvil->Database->get_upses({debug => 2, include_deleted => 1});
my $ups_uuid = $anvil->data->{cgi}{delete_ups_uuid}{value};
my $ups_name = $anvil->data->{upses}{ups_uuid}{$ups_uuid}{ups_name};
my $ups_agent = $anvil->data->{upses}{ups_uuid}{$ups_uuid}{ups_agent};
if (not exists $anvil->data->{upses}{ups_uuid}{$ups_uuid})
{
# Doesn't exist.
my $message = $anvil->Words->string({key => "warning_0036", variables => { uuid => $ups_uuid }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
elsif ($anvil->data->{upses}{ups_uuid}{$ups_uuid}{ups_ip_address} eq "DELETED")
{
# Already deleted.
my $message = $anvil->Words->string({key => "warning_0037", variables => {
name => $ups_name,
uuid => $ups_uuid,
}});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
# Has the user confirmed?
if ((exists $anvil->data->{cgi}{confirm}) && ($anvil->data->{cgi}{confirm}{value}))
{
# Delete it
my ($ups_uuid) = $anvil->Database->insert_or_update_upses({
debug => 2,
ups_uuid => $ups_uuid,
ups_name => $ups_name,
ups_agent => $ups_agent,
ups_ip_address => "DELETED",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ups_uuid => $ups_uuid }});
if ($ups_uuid)
{
# Deleted successfully
my $message = $anvil->Words->string({key => "ok_0008", variables => { name => $ups_name }});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::ok_message" => $anvil->data->{form}{ok_message} }});
}
else
{
# Something went wrong.
my $message = $anvil->Words->string({key => "warning_0040", variables => {
name => $ups_name,
uuid => $ups_uuid,
}});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
# Show the main menu and return.
show_ups_config_main_menu($anvil);
return(0);
}
else
{
# Ask the user to confirm.
my $ups_name = $anvil->data->{upses}{ups_uuid}{$ups_uuid}{ups_name};
my $ups_ip_address = $anvil->data->{upses}{ups_uuid}{$ups_uuid}{ups_ip_address};
my $say_ups_device = $ups_name." - ".$ups_ip_address." (".$anvil->data->{ups_agent}{$ups_agent}{brand}.")";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ups_uuid => $ups_uuid,
ups_agent => $ups_agent,
ups_ip_address => $ups_ip_address,
say_ups_device => $say_ups_device,
}});
# Are we asking the user to confirm one or more?
$anvil->data->{form}{back_link} = "?anvil=true&task=upses";
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "ups-delete-confirm", variables => {
name => $ups_name,
say_device => $say_ups_device,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
return(0);
}
}
# Are we configuring an agent/device?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::save::value" => $anvil->data->{cgi}{save}{value},
"cgi::confirm::value" => $anvil->data->{cgi}{confirm}{value},
}});
if ($anvil->data->{cgi}{save}{value})
{
# Confirmed?
if ($anvil->data->{cgi}{confirm}{value})
{
# Confirmed.
my $success = 1;
my $message = "";
foreach my $i (1..$anvil->data->{cgi}{ups_count}{value})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { i => $i }});
my $ups_uuid_key = "ups_uuid_".$i;
my $ups_name_key = "ups_name_".$i;
my $ups_agent_key = "ups_agent_".$i;
my $ups_ip_address_key = "ups_ip_address_".$i;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ups_uuid_key => $ups_uuid_key,
ups_name_key => $ups_name_key,
ups_agent_key => $ups_agent_key,
ups_ip_address_key => $ups_ip_address_key,
}});
my $ups_uuid = $anvil->data->{cgi}{$ups_uuid_key}{value};
my $ups_name = $anvil->data->{cgi}{$ups_name_key}{value};
my $ups_agent = $anvil->data->{cgi}{$ups_agent_key}{value};
my $ups_ip_address = $anvil->data->{cgi}{$ups_ip_address_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:ups_uuid' => $ups_uuid,
's2:ups_name' => $ups_name,
's3:ups_agent' => $ups_agent,
's4:ups_ip_address' => $ups_ip_address,
}});
# Save it
($ups_uuid) = $anvil->Database->insert_or_update_upses({
debug => 2,
ups_uuid => $ups_uuid,
ups_name => $ups_name,
ups_agent => $ups_agent,
ups_ip_address => $ups_ip_address,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ups_uuid => $ups_uuid }});
if ($ups_uuid)
{
$message .= $anvil->Words->string({key => "ok_0007", variables => { name => $ups_name }})."
";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { message => $message }});
# Clear CGI values so the form isn't pre-filled below.
foreach my $key (sort {$a cmp $b} keys %{$anvil->data->{cgi}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { key => $key }});
if ($key =~ /_$i$/)
{
$anvil->data->{cgi}{$key}{value} = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${key}::value" => $anvil->data->{cgi}{$key}{value} }});
}
}
}
else
{
# Something went wrong.
$success = 0;
$message .= $anvil->Words->string({key => "warning_0038", variables => { name => $ups_name }})."
";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:success' => $success,
's2:message' => $message,
}});
}
}
# Show it in the top-center.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { success => $success }});
if ($success)
{
# Woot!
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::ok_message" => $anvil->data->{form}{ok_message} }});
# Show the main menu and return.
show_ups_config_main_menu($anvil);
return(0);
}
else
{
# Something went wrong.
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
}
else
{
# Loop through the UPSes and ask for confirmation.
my $sane = 1;
my $upses_form = "";
foreach my $i (1..$anvil->data->{cgi}{ups_count}{value})
{
my $say_device = $anvil->Words->string({key => "striker_0239", variables => { number => $i }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
i => $i,
say_device => $say_device,
}});
my $ups_uuid_key = "ups_uuid_".$i;
my $ups_name_key = "ups_name_".$i;
my $ups_agent_key = "ups_agent_".$i;
my $ups_ip_address_key = "ups_ip_address_".$i;
my $agent = $anvil->data->{cgi}{$ups_agent_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ups_uuid_key => $ups_uuid_key,
ups_name_key => $ups_name_key,
ups_agent_key => $ups_agent_key,
ups_ip_address_key => $ups_ip_address_key,
agent => $agent,
}});
# Are any values insane?
if (not $anvil->Validate->host_name({name => $anvil->data->{cgi}{$ups_name_key}{value}, debug => 2}))
{
# Bad host name
$sane = 0;
$anvil->data->{cgi}{$ups_name_key}{alert} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${ups_name_key}::alert" => $anvil->data->{cgi}{$ups_name_key}{alert},
sane => $sane,
}});
}
if (not $anvil->Validate->ipv4({ip => $anvil->data->{cgi}{$ups_ip_address_key}{value}}))
{
# Bad IP address.
$sane = 0;
$anvil->data->{cgi}{$ups_name_key}{alert} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${ups_name_key}::alert" => $anvil->data->{cgi}{$ups_name_key}{alert},
sane => $sane,
}});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }});
if ($sane)
{
$upses_form .= $anvil->Template->get({file => "anvil.html", name => "ups-option-menu-confirm", variables => {
device => $say_device,
name_key => $ups_name_key,
name => $anvil->data->{cgi}{$ups_name_key}{value},
agent_key => $ups_agent_key,
agent => $anvil->data->{cgi}{$ups_agent_key}{value},
say_agent => $anvil->data->{ups_agent}{$agent}{brand},
ip_address_key => $ups_ip_address_key,
ip_address => $anvil->data->{cgi}{$ups_ip_address_key}{value},
ups_uuid_key => $ups_uuid_key,
ups_uuid => $anvil->data->{cgi}{$ups_uuid_key}{value},
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { upses_form => $upses_form }});
}
}
if ($sane)
{
$anvil->data->{form}{back_link} = "?anvil=true&task=upses";
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "ups-configuration-confirm", variables => {
upses => $upses_form,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
return(0);
}
else
{
# Send the user back to the form.
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => "#!string!warning_0039!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }});
}
}
}
if ($anvil->data->{cgi}{ups_agent}{value})
{
my $ups_agent = $anvil->data->{cgi}{ups_agent}{value};
my $ups_brand = $anvil->data->{ups_agent}{$ups_agent}{brand};
my $ups_description = $anvil->data->{ups_agent}{$ups_agent}{description};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ups_agent => $ups_agent,
ups_brand => $ups_brand,
ups_description => $ups_description,
}});
# Are we going back to the form?
if ($anvil->data->{cgi}{back}{value})
{
$anvil->data->{cgi}{save}{value} = "";
$anvil->data->{cgi}{confirm}{value} = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::save::value" => $anvil->data->{cgi}{save}{value},
"cgi::confirm::value" => $anvil->data->{cgi}{confirm}{value},
}});
}
# This will be used in forms
my $brands = [];
my $description_form = "";
foreach my $key (sort {$a cmp $b} keys %{$anvil->data->{ups_data}})
{
my $agent = $anvil->data->{ups_data}{$key}{agent};
my $brand = $anvil->data->{ups_data}{$key}{brand};
my $description = $anvil->data->{ups_data}{$key}{description};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:key" => $key,
"s2:agent" => $anvil->data->{ups_data}{$key}{agent},
"s3:brand" => $anvil->data->{ups_data}{$key}{brand},
"s4:description" => $anvil->data->{ups_data}{$key}{description},
}});
push @{$brands}, $agent."#!#".$brand;
}
# Walk through the list of UPSes
$anvil->Database->get_upses({debug => 3});
my $upses_form = "";
if ((not exists $anvil->data->{cgi}{ups_brand}) or (not defined $anvil->data->{cgi}{ups_brand}{value}))
{
$anvil->data->{cgi}{ups_brand}{value} = $ups_brand;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::ups_brand::value" => $anvil->data->{cgi}{ups_brand}{value},
}});
}
foreach my $i (1..$anvil->data->{cgi}{ups_count}{value})
{
my $say_device = $anvil->Words->string({key => "striker_0239", variables => { number => $i }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
i => $i,
say_device => $say_device,
}});
my $ups_uuid_key = "ups_uuid_".$i;
my $ups_name_key = "ups_name_".$i;
my $ups_agent_key = "ups_agent_".$i;
my $ups_ip_address_key = "ups_ip_address_".$i;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ups_uuid_key => $ups_uuid_key,
ups_name_key => $ups_name_key,
ups_agent_key => $ups_agent_key,
ups_ip_address_key => $ups_ip_address_key
}});
# Make sure we don't get any undefined warnings
if ((not exists $anvil->data->{cgi}{$ups_name_key}) or (not defined $anvil->data->{cgi}{$ups_name_key}{value}))
{
$anvil->data->{cgi}{$ups_name_key}{value} = "";
}
if ((not exists $anvil->data->{cgi}{$ups_agent_key}) or (not defined $anvil->data->{cgi}{$ups_agent_key}{value}))
{
$anvil->data->{cgi}{$ups_agent_key}{value} = "";
}
if ((not exists $anvil->data->{cgi}{$ups_uuid_key}) or (not defined $anvil->data->{cgi}{$ups_uuid_key}{value}))
{
$anvil->data->{cgi}{$ups_uuid_key}{value} = "";
}
# If we have a ups_uuid_X, read in the details.
if ($anvil->data->{cgi}{$ups_uuid_key}{value})
{
my $ups_uuid = $anvil->data->{cgi}{$ups_uuid_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ups_uuid => $ups_uuid }});
if (exists $anvil->data->{upses}{ups_uuid}{$ups_uuid})
{
my $old_ups_name = $anvil->data->{upses}{ups_uuid}{$ups_uuid}{ups_name};
my $old_ups_agent = $anvil->data->{upses}{ups_uuid}{$ups_uuid}{ups_agent};
my $old_ups_ip_address = $anvil->data->{upses}{ups_uuid}{$ups_uuid}{ups_ip_address};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_ups_name => $old_ups_name,
old_ups_agent => $old_ups_agent,
old_ups_ip_address => $old_ups_ip_address,
ups_name_key => $ups_name_key,
ups_agent_key => $ups_agent_key,
ups_ip_address_key => $ups_ip_address_key,
}});
# Now if we don't have a value in CGI but do from the database, set the CGI.
if ((not $anvil->data->{cgi}{$ups_name_key}{value}) && ($old_ups_name))
{
$anvil->data->{cgi}{$ups_name_key}{value} = $old_ups_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${ups_name_key}::value" => $anvil->data->{cgi}{$ups_name_key}{value},
}});
}
if ((not $anvil->data->{cgi}{$ups_agent_key}{value}) && ($old_ups_agent))
{
$anvil->data->{cgi}{$ups_agent_key}{value} = $old_ups_agent;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${ups_agent_key}::value" => $anvil->data->{cgi}{$ups_agent_key}{value},
}});
}
if ((not $anvil->data->{cgi}{$ups_ip_address_key}{value}) && ($old_ups_ip_address))
{
$anvil->data->{cgi}{$ups_ip_address_key}{value} = $old_ups_ip_address;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${ups_ip_address_key}::value" => $anvil->data->{cgi}{$ups_ip_address_key}{value},
}});
}
}
}
my $ups_agent_select = $anvil->Template->select_form({
name => $ups_agent_key,
options => $brands,
blank => 0,
'sort' => 1,
selected => $anvil->data->{cgi}{$ups_agent_key}{value} ? $anvil->data->{cgi}{$ups_agent_key}{value} : $anvil->data->{cgi}{ups_agent}{value},
class => "input_clear",
});
$upses_form .= $anvil->Template->get({file => "anvil.html", name => "ups-option-menu", variables => {
device => $say_device,
name_key => $ups_name_key,
name => $anvil->data->{cgi}{$ups_name_key}{value},
agent => $ups_agent_select,
ip_address_key => $ups_ip_address_key,
ip_address => $anvil->data->{cgi}{$ups_ip_address_key}{value},
ups_uuid_key => $ups_uuid_key,
ups_uuid => $anvil->data->{cgi}{$ups_uuid_key}{value},
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { upses_form => $upses_form }});
}
$anvil->data->{form}{back_link} = "?anvil=true&task=upses";
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "ups-configuration", variables => {
description => $ups_description,
upses => $upses_form,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'form::body' => $anvil->data->{form}{body} }});
}
else
{
# Show the main menu
show_ups_config_main_menu($anvil);
}
return(0);
}
sub show_ups_config_main_menu
{
my ($anvil) = @_;
# Read in known UPSes
$anvil->Database->get_upses({debug => 3});
# Get a list of current ups agents.
my $existing_upses = "";
if (exists $anvil->data->{upses}{ups_uuid})
{
# How many do we have?
my $ups_count = keys %{$anvil->data->{upses}{ups_name}};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ups_count => $ups_count }});
if ($ups_count)
{
# We've got devices.
my $ups_devices = "";
foreach my $ups_name (sort {$a cmp $b} keys %{$anvil->data->{upses}{ups_name}})
{
my $ups_uuid = $anvil->data->{upses}{ups_name}{$ups_name}{ups_uuid};
my $ups_agent = $anvil->data->{upses}{ups_name}{$ups_name}{ups_agent};
my $ups_ip_address = $anvil->data->{upses}{ups_name}{$ups_name}{ups_ip_address};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ups_uuid => $ups_uuid,
ups_agent => $ups_agent,
ups_ip_address => $ups_ip_address,
}});
$ups_devices .= $anvil->Template->get({file => "anvil.html", name => "existing-ups-entry", variables => {
name => $ups_name,
ip_address => $ups_ip_address,
ups_agent => $ups_agent,
ups_uuid => $ups_uuid,
}});
}
$existing_upses .= $anvil->Template->get({file => "anvil.html", name => "existing-upses", variables => {
upses => $ups_devices,
}});
}
}
# For each agent, we'll create a
\n"; $new_desctiption .= $line."\n"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { new_desctiption => $new_desctiption }}); } elsif ($break_number == 2) { $in_pre = 0; $new_desctiption .= $line."\n"; $new_desctiption .= "\n"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { new_desctiption => $new_desctiption }}); } else { $new_desctiption .= $line."\n"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { new_desctiption => $new_desctiption }}); } $break_number++; } else { if ($in_pre) { $line =~ s/