You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5279 lines
222 KiB
5279 lines
222 KiB
#!/usr/bin/perl |
|
# |
|
# Exit codes; |
|
# 0 == OK |
|
# 1 == Host UUID not available yet. |
|
# |
|
# TODO: |
|
# * Make the BCN count a thing, remove Striker user and make it statically 'admin'. |
|
# |
|
|
|
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 }}); |
|
|
|
### TODO: Something is causing fairly frequent resyncs, which results in Striker going in and out of |
|
### 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_units = defined $anvil->data->{cgi}{recipient_units}{value} ? $anvil->data->{cgi}{recipient_units}{value} : "metric"; |
|
my $recipient_new_level = defined $anvil->data->{cgi}{recipient_new_level}{value} ? $anvil->data->{cgi}{recipient_new_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_units => $recipient_units, |
|
recipient_new_level => $recipient_new_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_units, |
|
recipient_new_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_units = $row->[3]; |
|
$recipient_new_level = $row->[4]; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
recipient_name => $recipient_name, |
|
recipient_email => $recipient_email, |
|
recipient_language => $recipient_language, |
|
recipient_units => $recipient_units, |
|
recipient_new_level => $recipient_new_level, |
|
}}); |
|
|
|
if ($delete) |
|
{ |
|
# Has the user confirmed? |
|
if ($confirm) |
|
{ |
|
# Delete. |
|
$anvil->Database->insert_or_update_recipientss({ |
|
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_units = "metric"; |
|
$recipient_new_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->is_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_units => $recipient_units, |
|
recipient_new_level => $recipient_new_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_units = "metric"; |
|
$recipient_new_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 |
|
{ |
|
my $say_recipient_units = "#!string!unit_0027!#"; |
|
if ($recipient_language eq "imperial") |
|
{ |
|
$say_recipient_units = "#!string!unit_0028!#"; |
|
} |
|
# Ignore |
|
my $say_recipient_new_level = "#!string!unit_0023!#"; |
|
if ($recipient_new_level eq "1") |
|
{ |
|
# Critical |
|
$say_recipient_new_level = "#!string!unit_0024!#"; |
|
} |
|
elsif ($recipient_new_level eq "2") |
|
{ |
|
# Warning |
|
$say_recipient_new_level = "#!string!unit_0025!#"; |
|
} |
|
elsif ($recipient_new_level eq "3") |
|
{ |
|
# Notice |
|
$say_recipient_new_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_units => $recipient_units, |
|
say_recipient_units => $say_recipient_units, |
|
recipient_new_level => $recipient_new_level, |
|
say_recipient_new_level => $say_recipient_new_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", |
|
}); |
|
|
|
# Units (select) |
|
my $recipient_units_select = $anvil->Template->select_form({ |
|
name => "recipient_units", |
|
options => [ |
|
"metric#!#".$anvil->Words->string({key => "unit_0027"}), |
|
"imperial#!#".$anvil->Words->string({key => "unit_0028"}), |
|
], |
|
blank => 0, |
|
selected => $recipient_units, |
|
class => $anvil->data->{cgi}{recipient_units}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
|
|
# Log Level (select) |
|
my $recipient_new_level_select = $anvil->Template->select_form({ |
|
name => "recipient_new_level", |
|
options => [ |
|
"0#!#".$anvil->Words->string({key => "unit_0023"}), |
|
"1#!#".$anvil->Words->string({key => "unit_0024"}), |
|
"2#!#".$anvil->Words->string({key => "unit_0025"}), |
|
"3#!#".$anvil->Words->string({key => "unit_0026"}), |
|
], |
|
blank => 0, |
|
selected => $recipient_new_level, |
|
class => $anvil->data->{cgi}{recipient_new_level}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
|
|
# Show the menu. |
|
$anvil->data->{form}{back_link} = "?"; |
|
$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, |
|
units => $recipient_units_select, |
|
new_level => $recipient_new_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 '143' unless $connection_security is 'ssl_tls' |
|
$port = 143; |
|
if ($connection_security eq "ssl_tls") |
|
{ |
|
$port = 993; |
|
} |
|
$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->_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->is_ipv4({ip => $test_outgoing_mail_server})) and |
|
(not $anvil->Validate->is_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->is_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} = "?"; |
|
$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'}, |
|
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 handles files. |
|
sub process_file_menu |
|
{ |
|
my ($anvil) = @_; |
|
|
|
$anvil->data->{form}{refresh_link} = "striker?files=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}; |
|
|
|
if ($anvil->data->{cgi}{task}{value} eq "upload") |
|
{ |
|
#process_upload_page($anvil); |
|
} |
|
else |
|
{ |
|
# The 'back' goes home |
|
$anvil->data->{form}{back_link} = "?"; |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "files.html", name => "main-menu", variables => { |
|
}}); |
|
} |
|
|
|
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 "fences") |
|
{ |
|
process_fences($anvil); |
|
} |
|
elsif ($anvil->data->{cgi}{task}{value} eq "create") |
|
{ |
|
if ($anvil->data->{cgi}{subtask}{value} eq "manifest") |
|
{ |
|
#process_manifest($anvil); |
|
} |
|
else |
|
{ |
|
process_create($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); |
|
} |
|
|
|
sub handle_new_manifest |
|
{ |
|
my ($anvil) = @_; |
|
|
|
|
|
|
|
return(0); |
|
} |
|
|
|
# This sanity checks the fence agent forms. |
|
sub sanity_check_fence_agent_form |
|
{ |
|
my ($anvil, $fence_agent) = @_; |
|
|
|
### TODO: Left off here. Make the confirm form a table; |
|
### Any set options that matches the default gets set to 'subtle'. |
|
=cut |
|
Fence Agent: $fence_agent |
|
Devices: |
|
| option | default | 1 | 2 | ... |
|
+--------+---------+-------+-------+----- |
|
| foo | bar | bar | baz | |
|
=cut |
|
my $sane = 1; |
|
my $confirn_form = ""; |
|
foreach my $i (1..$anvil->data->{cgi}{fence_count}{value}) |
|
{ |
|
|
|
} |
|
|
|
return($sane); |
|
} |
|
|
|
# This allows the user to tell us about fence devices. |
|
sub process_fences |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# Read/process the unified fences metadata. |
|
$anvil->Striker->get_fence_data({debug => 3}); |
|
|
|
$anvil->data->{cgi}{fence_agent}{value} = "" if not defined $anvil->data->{cgi}{fence_agent}{value}; |
|
$anvil->data->{cgi}{fence_count}{value} = 2 if not defined $anvil->data->{cgi}{fence_count}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"cgi::fence_agent::value" => $anvil->data->{cgi}{fence_agent}{value}, |
|
"cgi::fence_count::value" => $anvil->data->{cgi}{fence_count}{value}, |
|
}}); |
|
|
|
# Are we configuring an agent/device? |
|
if ($anvil->data->{cgi}{fence_agent}{value}) |
|
{ |
|
my $fence_agent = $anvil->data->{cgi}{fence_agent}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { fence_agent => $fence_agent }}); |
|
|
|
# Are we saving? |
|
if ($anvil->data->{cgi}{save}{value}) |
|
{ |
|
# Sanity check |
|
my $sane = sanity_check_fence_agent_form($anvil, $fence_agent); |
|
} |
|
|
|
my $agent_description = format_fence_description($anvil, $fence_agent, $anvil->data->{fences}{$fence_agent}{description}); |
|
|
|
# Walk through the list of options |
|
my $option_form = ""; |
|
foreach my $i (1..$anvil->data->{cgi}{fence_count}{value}) |
|
{ |
|
my $say_device = $anvil->Words->string({key => "striker_0216", variables => { number => $i }}); |
|
my $device_options = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
i => $i, |
|
say_device => $say_device, |
|
}}); |
|
|
|
foreach my $name (sort {$a cmp $b} keys %{$anvil->data->{fences}{$fence_agent}{parameters}}) |
|
{ |
|
# We don't show deprecated or replaced options. |
|
next if $anvil->data->{fences}{$fence_agent}{parameters}{$name}{replacement}; |
|
next if $anvil->data->{fences}{$fence_agent}{parameters}{$name}{deprecated}; |
|
my $option_key = $name."_".$i; |
|
my $unique = $anvil->data->{fences}{$fence_agent}{parameters}{$name}{unique}; |
|
my $required = $anvil->data->{fences}{$fence_agent}{parameters}{$name}{required}; |
|
my $description = $anvil->data->{fences}{$fence_agent}{parameters}{$name}{description}; |
|
my $type = $anvil->data->{fences}{$fence_agent}{parameters}{$name}{content_type}; |
|
my $default = exists $anvil->data->{fences}{$fence_agent}{parameters}{$name}{'default'} ? $anvil->data->{fences}{$fence_agent}{parameters}{$name}{'default'} : ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
option_key => $option_key, |
|
unique => $unique, |
|
required => $required, |
|
description => $description, |
|
type => $type, |
|
'default' => $default, |
|
}}); |
|
|
|
# Set the cgi variable to the default, if not already set. |
|
$anvil->data->{cgi}{$option_key}{alert} = "" if not defined $anvil->data->{cgi}{$option_key}{alert}; |
|
$anvil->data->{cgi}{$option_key}{value} = $default if not defined $anvil->data->{cgi}{$option_key}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"cgi::".$option_key."::value" => $anvil->data->{cgi}{$option_key}{value}, |
|
}}); |
|
|
|
# Set the CGI default if not already set. |
|
$anvil->data->{cgi}{$option_key}{value} = $default if not exists $anvil->data->{cgi}{$option_key}{value}; |
|
if ($type eq "select") |
|
{ |
|
# Build the select box |
|
my $options = []; |
|
foreach my $option (sort {$a cmp $b} @{$anvil->data->{fences}{$fence_agent}{parameters}{$name}{options}}) |
|
{ |
|
push @{$options}, $option; |
|
} |
|
|
|
my $select_options = $anvil->Template->select_form({ |
|
name => $option_key, |
|
options => $options, |
|
blank => $required ? 0 : 1, |
|
'sort' => 1, |
|
selected => $anvil->data->{cgi}{$option_key}{value}, |
|
class => $anvil->data->{cgi}{$option_key}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { select_options => $select_options }}); |
|
|
|
# Build the entry |
|
my $select_form .= $anvil->Template->get({file => "anvil.html", name => "fence-agent-option-entry", variables => { |
|
name_class => $required ? "say_required" : "", |
|
name => $name, |
|
option => $select_options, |
|
description => $description, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { select_form => $select_form }}); |
|
|
|
$device_options .= $select_form; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { device_options => $device_options }}); |
|
} |
|
elsif ($type eq "boolean") |
|
{ |
|
# Build the entry |
|
my $checkbox_form .= $anvil->Template->get({file => "anvil.html", name => "fence-agent-checkbox-entry", variables => { |
|
name => $name, |
|
name_class => $required ? "say_required" : "", |
|
checkbox_name => $option_key, |
|
checkbox_checked => $anvil->data->{cgi}{$option_key}{value} ? "checked" : "", |
|
description => $description, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { checkbox_form => $checkbox_form }}); |
|
|
|
$device_options .= $checkbox_form; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { device_options => $device_options }}); |
|
} |
|
else |
|
{ |
|
### String, Second or Integer. |
|
# Build the entry |
|
my $string_options .= $anvil->Template->get({file => "anvil.html", name => "fence-agent-input-entry", variables => { |
|
name => $name, |
|
key => $option_key, |
|
value => $anvil->data->{cgi}{$option_key}{value}, |
|
'default' => $default, |
|
name_class => $required ? "say_required" : "", |
|
input_class => $anvil->data->{cgi}{$option_key}{alert} ? "input_alert" : "input_clear", |
|
description => $description, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { string_options => $string_options }}); |
|
|
|
$device_options .= $string_options; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { device_options => $device_options }}); |
|
} |
|
} |
|
|
|
$option_form .= $anvil->Template->get({file => "anvil.html", name => "fence-agent-option-menu", variables => { |
|
device_name => $say_device, |
|
device_options => $device_options, |
|
}}); |
|
} |
|
|
|
$anvil->data->{form}{back_link} = "?anvil=true&task=fences"; |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "fence-agent-configuration", variables => { |
|
description => $agent_description, |
|
options => $option_form, |
|
note => $anvil->Words->string({key => "striker_0218", variables => { name => $fence_agent }}), |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }}); |
|
} |
|
else |
|
{ |
|
# For each agent, we'll create a <div> with it's options that will be shown/hidden basen on the agent |
|
# select box. |
|
my $agents = []; |
|
my $description_form = ""; |
|
foreach my $fence_agent (sort {$a cmp $b} keys %{$anvil->data->{fences}}) |
|
{ |
|
# We don't care about IPMI-based fence agents here. |
|
next if $fence_agent eq "fence_drac5"; |
|
next if $fence_agent eq "fence_idrac"; |
|
next if $fence_agent =~ /^fence_ilo/; |
|
next if $fence_agent eq "fence_imm"; |
|
next if $fence_agent eq "fence_ipmilan"; |
|
next if $fence_agent eq "fence_redfish"; |
|
next if $fence_agent eq "fence_rsa"; |
|
|
|
push @{$agents}, $fence_agent; |
|
|
|
my $agent_description = format_fence_description($anvil, $fence_agent, $anvil->data->{fences}{$fence_agent}{description}); |
|
|
|
$description_form .= $anvil->Template->get({file => "anvil.html", name => "fence-agent-description", variables => { |
|
name => $fence_agent, |
|
description => $agent_description, |
|
}}); |
|
} |
|
|
|
my $fence_agent_select = $anvil->Template->select_form({ |
|
name => "fence_agent", |
|
options => $agents, |
|
blank => 0, |
|
'sort' => 1, |
|
selected => $anvil->data->{cgi}{fence_agent}{value} ? $anvil->data->{cgi}{fence_agent}{value} : "fence_apc_snmp", |
|
class => "input_clear", |
|
}); |
|
my $fence_count_select = $anvil->Template->select_form({ |
|
name => "fence_count", |
|
options => [1, 2, 3, 4], |
|
blank => 0, |
|
'sort' => 0, |
|
selected => $anvil->data->{cgi}{fence_count}{value}, |
|
class => "input_clear", |
|
}); |
|
|
|
$anvil->data->{form}{back_link} = "?anvil=true&task=create"; |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "fence-agent-menu", variables => { |
|
fence_select => $fence_agent_select, |
|
fence_count => $fence_count_select, |
|
descriptions => $description_form, |
|
existing_fences => "", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }}); |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
sub format_fence_description |
|
{ |
|
my ($anvil, $fence_agent, $agent_description) = @_; |
|
|
|
# Replace newlines with <br /> elements. |
|
$agent_description =~ s/\n/<br \/>/gs; |
|
$agent_description =~ s/<br \/>/<br \/>\n/gs; |
|
|
|
# Handle fence_azure_arm. |
|
if ($fence_agent eq "fence_azure_arm") |
|
{ |
|
my $in_pre = 0; |
|
my $break_number = 0; |
|
my $new_desctiption = ""; |
|
foreach my $line (split/\n/, $agent_description) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); |
|
if ($line =~ /\+---/) |
|
{ |
|
$line =~ s/<br \/>//g; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { break_number => $break_number }}); |
|
if (not $break_number) |
|
{ |
|
$in_pre = 1; |
|
$new_desctiption .= "<pre>\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 .= "</pre>\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/<br \/>//g; |
|
} |
|
$new_desctiption .= $line."\n"; |
|
} |
|
} |
|
$agent_description = $new_desctiption; |
|
} |
|
|
|
return($agent_description); |
|
} |
|
|
|
# This handles creating an Anvil! from an existing manifest |
|
sub process_create |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# Are we creating a new manifest? |
|
if ($anvil->data->{cgi}{task}{value}) |
|
{ |
|
handle_new_manifest($anvil); |
|
} |
|
|
|
# Show existing manifests. |
|
my $query = " |
|
SELECT |
|
manifest_uuid, |
|
manifest_name, |
|
manifest_last_ran, |
|
manifest_xml, |
|
manifest_note |
|
FROM |
|
manifests |
|
ORDER BY |
|
manifest_name ASC;"; |
|
$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 $manifest_template = ""; |
|
if ($count) |
|
{ |
|
foreach my $row (@{$results}) |
|
{ |
|
my $manifest_uuid = $row->[0]; |
|
my $manifest_name = $row->[1]; |
|
my $manifest_last_ran = $row->[2]; |
|
my $manifest_xml = $row->[3]; |
|
my $manifest_note = $row->[4]; |
|
$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 => "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->{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 handles configuring a remote target's network interfaces (renaming them, bonding and bridging them). |
|
sub process_prep_network |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# Do I know which machine we're configuring? |
|
if (not $anvil->data->{cgi}{host_uuid}{value}) |
|
{ |
|
# Nope, send the user back. |
|
$anvil->data->{cgi}{task}{value} = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::task::value" => $anvil->data->{cgi}{task}{value} }}); |
|
process_anvil_menu($anvil); |
|
return(0); |
|
} |
|
|
|
# Pull the host's data out of the JSON file. |
|
$anvil->Striker->parse_all_status_json(); |
|
|
|
my $host_name = ""; |
|
foreach my $host (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}}) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"cgi::host_uuid::value" => $anvil->data->{cgi}{host_uuid}{value}, |
|
"json::all_status::hosts::${host}::host_uuid" => $anvil->data->{json}{all_status}{hosts}{$host}{host_uuid}, |
|
}}); |
|
if ($anvil->data->{cgi}{host_uuid}{value} eq $anvil->data->{json}{all_status}{hosts}{$host}{host_uuid}) |
|
{ |
|
# Found it. |
|
$host_name = $host; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { host_name => $host_name }}); |
|
last; |
|
} |
|
} |
|
if (not $host_name) |
|
{ |
|
# Didn't find it. |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0014", variables => { host_uuid => $anvil->data->{cgi}{host_uuid}{value} } }) }}); |
|
$anvil->data->{cgi}{task}{value} = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"cgi::task::value" => $anvil->data->{cgi}{task}{value}, |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
}}); |
|
process_anvil_menu($anvil); |
|
return(0); |
|
} |
|
|
|
# Is the user going back to the form? |
|
if (($anvil->data->{cgi}{save}{value} eq "true") && ($anvil->data->{cgi}{back}{value})) |
|
{ |
|
# User is going back. |
|
$anvil->data->{cgi}{save}{value} = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::save::value" => $anvil->data->{cgi}{save}{value} }}); |
|
} |
|
|
|
# How many actual interfaces do we have? We need at least six. For each two above that, we'll add an |
|
# additional bond option per network. |
|
my $interfaces = {}; |
|
my $interface_options = []; |
|
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}}) |
|
{ |
|
# if any interfaces are called 'virbrX-nic', ignore it as it will be removed. Likewise, ignore any 'vnetX' devices. |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface => $interface }}); |
|
if (($interface =~ /^virbr\d+-nic/) or ($interface =~ /^vnet\d+/)) |
|
{ |
|
# Ignore it. |
|
next; |
|
} |
|
|
|
# Store the mac used in the select box |
|
my $mac_address = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface}{mac_address}; |
|
push @{$interface_options}, $mac_address."#!#".$interface." (".$mac_address.")"; |
|
|
|
# Store the mac address . |
|
$interfaces->{$interface} = $mac_address; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "interfaces->{".$interface."}" => $interfaces->{$interface} }}); |
|
} |
|
|
|
# Get the interface count |
|
my $interface_count = keys %{$interfaces}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface_count => $interface_count }}); |
|
|
|
if ($interface_count < 6) |
|
{ |
|
# Not enough interfaces. |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0015", variables => { interface_count => $interface_count } }) }}); |
|
$anvil->data->{cgi}{task}{value} = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"cgi::task::value" => $anvil->data->{cgi}{task}{value}, |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
}}); |
|
process_anvil_menu($anvil); |
|
} |
|
|
|
# TODO: For now, we're only allowing one BCN and SN. So at this time, we'll show one BCN pair, one SN |
|
# pair and N-IFN pairs. |
|
my $bcn_pair_count = 1; |
|
my $sn_pair_count = 1; |
|
my $ifn_pair_count = int(($interface_count - 4) / 2); |
|
$ifn_pair_count = 1 if $ifn_pair_count < 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
bcn_pair_count => $bcn_pair_count, |
|
sn_pair_count => $sn_pair_count, |
|
ifn_pair_count => $ifn_pair_count, |
|
}}); |
|
|
|
### NOTE: The weird 'form::config_step2::<x>::value is from reusing the logic used back when |
|
### Striker's config was made. It's not the best, but it does the job. Would be nice to redo |
|
### the logic later. |
|
# Are we saving? |
|
if ($anvil->data->{cgi}{save}{value} eq "true") |
|
{ |
|
# Clear the network map variable. |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "config::map_network", |
|
variable_value => 0, |
|
variable_default => 0, |
|
variable_description => "striker_0202", |
|
variable_section => "config", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
|
|
# Is the form sane? |
|
my $sane = 1; |
|
my $interfaces = ""; |
|
my $error = 0; |
|
my $gateway_interface = ""; |
|
if ($anvil->data->{cgi}{host_name}{value}) |
|
{ |
|
# Is the host name sane? |
|
if (not $anvil->Validate->is_domain_name({name => $anvil->data->{cgi}{host_name}{value}})) |
|
{ |
|
# Nope |
|
my $error_message = $anvil->Words->string({key => "error_0012", variables => { host_name => $anvil->data->{cgi}{host_name}{value} }}); |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); |
|
$anvil->data->{cgi}{host_name}{alert} = 1; |
|
} |
|
else |
|
{ |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::host_name::value", |
|
variable_value => $anvil->data->{cgi}{host_name}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0159", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
} |
|
|
|
if ($anvil->data->{cgi}{gateway}{value}) |
|
{ |
|
# Is if valid? |
|
if (not $anvil->Validate->is_ipv4({ip => $anvil->data->{cgi}{gateway}{value}})) |
|
{ |
|
# Bad IP |
|
my $error_message = $anvil->Words->string({key => "warning_0010", variables => { ip_address => $anvil->data->{cgi}{gateway}{value} }}); |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); |
|
$anvil->data->{cgi}{gateway}{alert} = 1; |
|
} |
|
else |
|
{ |
|
# It's sane, record it. |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step2::gateway::value", |
|
variable_value => $anvil->data->{cgi}{gateway}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0036", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
} |
|
if ($anvil->data->{cgi}{dns}{value}) |
|
{ |
|
foreach my $dns (split/,/, $anvil->data->{cgi}{dns}{value}) |
|
{ |
|
$dns =~ s/^\s+//; |
|
$dns =~ s/\s+$//; |
|
if (not $anvil->Validate->is_ipv4({ip => $dns})) |
|
{ |
|
# Bad IP |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0010", variables => { ip_address => $anvil->data->{cgi}{dns}{value} }}) }}); |
|
$anvil->data->{cgi}{dns}{alert} = 1; |
|
} |
|
last if $anvil->data->{cgi}{dns}{alert}; |
|
} |
|
if (not $anvil->data->{cgi}{dns}{alert}) |
|
{ |
|
# It's sane, record it. |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step2::dns::value", |
|
variable_value => $anvil->data->{cgi}{dns}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0038", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
} |
|
foreach my $network ("bcn", "sn", "ifn") |
|
{ |
|
my $count_key = $network."_count"; |
|
my $loops = $anvil->data->{cgi}{$count_key}{value}; |
|
|
|
# Store the network counts. |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step1::".$count_key."::value", |
|
variable_value => $anvil->data->{cgi}{$count_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0163", |
|
variable_section => "config_step1", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
|
|
foreach my $i (1..$loops) |
|
{ |
|
my $this_network = $network.$i; |
|
my $bridge_key = $this_network."_create_bridge"; |
|
my $ip_key = $this_network."_ip"; |
|
my $subnet_key = $this_network."_subnet_mask"; |
|
my $link1_key = $this_network."_link1_mac_to_set"; |
|
my $link2_key = $this_network."_link2_mac_to_set"; |
|
my $say_network = $anvil->Words->string({key => "striker_0018", variables => { number => $i }}); |
|
if ($network eq "sn") |
|
{ |
|
$say_network = $anvil->Words->string({key => "striker_0020", variables => { number => $i }}); |
|
} |
|
elsif ($network eq "ifn") |
|
{ |
|
$say_network = $anvil->Words->string({key => "striker_0022", variables => { number => $i }}); |
|
} |
|
my $link1_interface = ""; |
|
my $link2_interface = ""; |
|
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}}) |
|
{ |
|
my $mac_address = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface}{mac_address}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
interface => $interface, |
|
mac_address => $mac_address, |
|
}}); |
|
if ($mac_address eq $anvil->data->{cgi}{$link1_key}{value}) |
|
{ |
|
$link1_interface = $interface; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { link1_interface => $link1_interface }}); |
|
} |
|
elsif ($mac_address eq $anvil->data->{cgi}{$link2_key}{value}) |
|
{ |
|
$link2_interface = $interface; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { link2_interface => $link2_interface }}); |
|
} |
|
last if (($link1_interface) && ($link2_interface)); |
|
} |
|
my $say_bridge = "#!string!unit_0002!#"; |
|
if ($anvil->data->{cgi}{$bridge_key}{value}) |
|
{ |
|
# We're making a bridge. |
|
$say_bridge = "#!string!unit_0001!#"; |
|
} |
|
my $say_ip_address = "#!string!striker_0152!#"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_ip_address => $say_ip_address }}); |
|
if (($anvil->data->{cgi}{$ip_key}{value}) && (not $anvil->Validate->is_ipv4({ip => $anvil->data->{cgi}{$ip_key}{value}}))) |
|
{ |
|
# Bad IP |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0010", variables => { ip_address => $anvil->data->{cgi}{$ip_key}{value} }}) }}); |
|
$anvil->data->{cgi}{$ip_key}{alert} = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
"cgi::${ip_key}::alert" => $anvil->data->{cgi}{$ip_key}{alert}, |
|
}}); |
|
} |
|
elsif (($anvil->data->{cgi}{$subnet_key}{value}) && (not $anvil->Validate->is_subnet_mask({subnet_mask => $anvil->data->{cgi}{$subnet_key}{value}}))) |
|
{ |
|
# Bad subnet |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0017"}) }}); |
|
$anvil->data->{cgi}{$subnet_key}{alert} = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert}, |
|
}}); |
|
} |
|
elsif (($anvil->data->{cgi}{$ip_key}{value}) && (not $anvil->data->{cgi}{$subnet_key}{value})) |
|
{ |
|
# IP without a subnet |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0018"}) }}); |
|
$anvil->data->{cgi}{$subnet_key}{alert} = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert}, |
|
}}); |
|
} |
|
else |
|
{ |
|
### Things are sane. |
|
# Does this network have an IP or is it dhcp? |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "cgi::${ip_key}::value" => $anvil->data->{cgi}{$ip_key}{value} }}); |
|
if ($anvil->data->{cgi}{$ip_key}{value}) |
|
{ |
|
$say_ip_address = $anvil->data->{cgi}{$ip_key}{value}."/".$anvil->data->{cgi}{$subnet_key}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_ip_address => $say_ip_address }}); |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step2::".$ip_key."::value", |
|
variable_value => $anvil->data->{cgi}{$ip_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0153,!!say_network!".$say_network."!!", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step2::".$subnet_key."::value", |
|
variable_value => $anvil->data->{cgi}{$subnet_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0154,!!say_network!".$say_network."!!", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# Is this the network with the subnet mask? |
|
if ((not $gateway_interface) && |
|
($anvil->data->{cgi}{gateway}{value}) && |
|
(not $anvil->data->{cgi}{gateway}{alert}) && |
|
($anvil->data->{cgi}{$ip_key}{value})) |
|
{ |
|
my $match = $anvil->Network->match_gateway({ |
|
ip_address => $anvil->data->{cgi}{$ip_key}{value}, |
|
subnet_mask => $anvil->data->{cgi}{$subnet_key}{value}, |
|
gateway => $anvil->data->{cgi}{gateway}{value}, |
|
}); |
|
|
|
# Found the match! |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { match => $match }}); |
|
if ($match) |
|
{ |
|
if ($anvil->data->{cgi}{$ip_key}{value}) |
|
{ |
|
$say_ip_address .= ",<br /> #!string!striker_0026!#: ".$anvil->data->{cgi}{gateway}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_ip_address => $say_ip_address }}); |
|
} |
|
|
|
# DNS? |
|
if (($anvil->data->{cgi}{dns}{value}) && (not $anvil->data->{cgi}{dns}{alert}) && ($anvil->data->{cgi}{$ip_key}{value})) |
|
{ |
|
$say_ip_address .= ",<br /> #!string!striker_0037!#: ".$anvil->data->{cgi}{dns}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_ip_address => $say_ip_address }}); |
|
} |
|
|
|
$gateway_interface = $this_network; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { gateway_interface => $gateway_interface }}); |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step2::gateway_interface::value", |
|
variable_value => $gateway_interface, |
|
variable_default => "", |
|
variable_description => "striker_0155", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
} |
|
} |
|
|
|
if (not $anvil->data->{cgi}{$ip_key}{value}) |
|
{ |
|
# Record this as DHCP. |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step2::".$ip_key."::value", |
|
variable_value => "dhcp", |
|
variable_default => "", |
|
variable_description => "striker_0160", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# Last check, are the interfaces defined? All $i == 1 interfaces need to be |
|
# defined. Any 2+ are allowed to be ignored, _IF_ neither link is selected |
|
# AND neither the IP/subnet are blank. |
|
if ((not $anvil->data->{cgi}{$link1_key}{value}) && (not $anvil->data->{cgi}{$link2_key}{value})) |
|
{ |
|
# If this is network 1, both are required. |
|
if ($i == 1) |
|
{ |
|
# Required. |
|
my $error_message = $anvil->Words->string({key => "warning_0021"}); |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); |
|
$anvil->data->{cgi}{$link1_key}{value} = 1; |
|
$anvil->data->{cgi}{$link2_key}{value} = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
"cgi::${link1_key}::alert" => $anvil->data->{cgi}{$link1_key}{alert}, |
|
"cgi::${link2_key}::alert" => $anvil->data->{cgi}{$link2_key}{alert}, |
|
}}); |
|
} |
|
} |
|
elsif (not $anvil->data->{cgi}{$link1_key}{value}) |
|
{ |
|
# link 1 is missing. |
|
my $error_message = $anvil->Words->string({key => "warning_0022"}); |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); |
|
$anvil->data->{cgi}{$link1_key}{value} = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
"cgi::${link1_key}::alert" => $anvil->data->{cgi}{$link1_key}{alert}, |
|
}}); |
|
} |
|
elsif (not $anvil->data->{cgi}{$link2_key}{value}) |
|
{ |
|
# link 2 is missing. |
|
my $error_message = $anvil->Words->string({key => "warning_0022"}); |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); |
|
$anvil->data->{cgi}{$link2_key}{value} = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
"cgi::${link2_key}::alert" => $anvil->data->{cgi}{$link2_key}{alert}, |
|
}}); |
|
} |
|
elsif (($anvil->data->{cgi}{$ip_key}{value}) && (not $anvil->data->{cgi}{$link1_key}{value})) |
|
{ |
|
# There's an IP address but no interfaces selected. |
|
my $error_message = $anvil->Words->string({key => "warning_0022"}); |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); |
|
$anvil->data->{cgi}{$link1_key}{value} = 1; |
|
$anvil->data->{cgi}{$link2_key}{value} = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
"cgi::${link1_key}::alert" => $anvil->data->{cgi}{$link1_key}{alert}, |
|
"cgi::${link2_key}::alert" => $anvil->data->{cgi}{$link2_key}{alert}, |
|
}}); |
|
} |
|
|
|
# Now save the link info, if selected. |
|
if ($anvil->data->{cgi}{$link1_key}{value}) |
|
{ |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step2::".$link1_key."::value", |
|
variable_value => $anvil->data->{cgi}{$link1_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0156", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
if ($anvil->data->{cgi}{$link2_key}{value}) |
|
{ |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step2::".$link2_key."::value", |
|
variable_value => $anvil->data->{cgi}{$link2_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0157", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# Store the bridge key |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step2::".$bridge_key."::value", |
|
variable_value => $anvil->data->{cgi}{$bridge_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0158", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
|
|
$interfaces .= $anvil->Template->get({file => "anvil.html", name => "interface-entry", variables => { |
|
network => $say_network, |
|
primary => $link1_interface." (".$anvil->data->{cgi}{$link1_key}{value}.")", |
|
link1_key => $link1_key, |
|
link1_value => $anvil->data->{cgi}{$link1_key}{value}, |
|
secondary => $link2_interface." (".$anvil->data->{cgi}{$link2_key}{value}.")", |
|
link2_key => $link2_key, |
|
link2_value => $anvil->data->{cgi}{$link2_key}{value}, |
|
bridge => $say_bridge, |
|
say_ip => $say_ip_address, |
|
ip_key => $ip_key, |
|
ip_address => $anvil->data->{cgi}{$ip_key}{value}, |
|
subnet_key => $subnet_key, |
|
subnet_mask => $anvil->data->{cgi}{$subnet_key}{value}, |
|
bridge_key => $bridge_key, |
|
bridge_value => $anvil->data->{cgi}{$bridge_key}{value}, |
|
}}); |
|
} |
|
} |
|
|
|
# Did we see an error? |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }}); |
|
if ($anvil->data->{form}{error_massage}) |
|
{ |
|
# Yup, not sane, send the user back to the form. |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }}); |
|
} |
|
|
|
# Confirmed? |
|
if (($anvil->data->{cgi}{confirm}{value}) && ($sane)) |
|
{ |
|
# Yes, save the job. |
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ |
|
debug => 3, |
|
file => $THIS_FILE, |
|
line => __LINE__, |
|
job_host_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
job_command => $anvil->data->{path}{exe}{'anvil-configure-host'}, |
|
job_data => "form::config_step2", |
|
job_name => "configure::network", |
|
job_title => "job_0001", |
|
job_description => "job_0071", |
|
job_progress => 0, |
|
}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, 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 => "network_job_recorded", variables => { |
|
reload_url => "/cgi-bin/".$THIS_FILE."?anvil=true", |
|
title => "#!string!striker_0044!#", |
|
description => "#!string!striker_0045!#", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
return(0); |
|
} |
|
else |
|
{ |
|
# Show the confirmation box. |
|
$anvil->data->{form}{back_link} = $anvil->data->{sys}{cgi_string}; |
|
$anvil->data->{form}{back_link} =~ s/step=step2//; |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "config-network-confirm", variables => { |
|
host_name => $host_name, |
|
host_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
gateway_interface => $gateway_interface, |
|
interfaces => $interfaces, |
|
bcn_count => $bcn_pair_count, |
|
sn_count => $sn_pair_count, |
|
ifn_count => $ifn_pair_count, |
|
gateway => $anvil->data->{cgi}{gateway}{value}, |
|
dns => $anvil->data->{cgi}{dns}{value}, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }}); |
|
return(0); |
|
} |
|
} |
|
else |
|
{ |
|
# We're mapping |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "config::map_network", |
|
variable_value => 1, |
|
variable_default => 0, |
|
variable_description => "striker_0202", |
|
variable_section => "config", |
|
variable_source_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
my $interface_form = ""; |
|
# NOTE: We don't assign IPs at this point, unless the user manually sets one. We'll set all to 'dhcp' |
|
# until set during the Anvil! build later. |
|
foreach my $network ("bcn", "sn", "ifn") |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network => $network }}); |
|
my $name_key = ""; |
|
my $description_key = ""; |
|
my $count = 1; |
|
if ($network eq "bcn") |
|
{ |
|
$name_key = "striker_0018"; |
|
$description_key = "striker_0019"; |
|
$count = $bcn_pair_count; |
|
} |
|
elsif ($network eq "sn") |
|
{ |
|
$name_key = "striker_0020"; |
|
$description_key = "striker_0021"; |
|
$count = $sn_pair_count; |
|
} |
|
elsif ($network eq "ifn") |
|
{ |
|
$name_key = "striker_0022"; |
|
$description_key = "striker_0023"; |
|
$count = $ifn_pair_count; |
|
} |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
name_key => $name_key, |
|
description_key => $description_key, |
|
count => $count, |
|
}}); |
|
foreach my $i (1..$count) |
|
{ |
|
my $this_ip_key = $network.$i."_ip"; |
|
my $this_subnet_mask_key = $network.$i."_subnet_mask"; |
|
my $this_iface1_key = $network.$i."_link1_mac_to_set"; |
|
my $this_iface2_key = $network.$i."_link2_mac_to_set"; |
|
my $this_ip = exists $anvil->data->{cgi}{$this_ip_key}{value} ? $anvil->data->{cgi}{$this_ip_key}{value} : "dhcp"; |
|
my $this_ip_class = $anvil->data->{cgi}{$this_ip_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_subnet_mask_class = $anvil->data->{cgi}{$this_subnet_mask_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_iface1_class = $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_iface2_class = $anvil->data->{cgi}{$this_iface2_key}{alert} ? "input_alert" : "input_clear"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
this_ip_key => $this_ip_key, |
|
this_subnet_mask_key => $this_subnet_mask_key, |
|
this_iface1_key => $this_iface1_key, |
|
this_iface2_key => $this_iface2_key, |
|
this_ip => $this_ip, |
|
this_ip_class => $this_ip_class, |
|
this_subnet_mask_class => $this_subnet_mask_class, |
|
this_iface1_class => $this_iface1_class, |
|
this_iface2_class => $this_iface2_class, |
|
}}); |
|
|
|
# Build the interface select boxes... |
|
my $this_iface1_form = $anvil->Template->select_form({ |
|
name => $this_iface1_key, |
|
options => $interface_options, |
|
blank => 1, |
|
'sort' => 0, |
|
selected => defined $anvil->data->{cgi}{$this_iface1_key}{value} ? $anvil->data->{cgi}{$this_iface1_key}{value} : "", |
|
class => $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
my $this_iface2_form = $anvil->Template->select_form({ |
|
name => $this_iface2_key, |
|
options => $interface_options, |
|
blank => 1, |
|
'sort' => 0, |
|
selected => defined $anvil->data->{cgi}{$this_iface2_key}{value} ? $anvil->data->{cgi}{$this_iface2_key}{value} : "", |
|
class => $anvil->data->{cgi}{$this_iface2_key}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
|
|
# Assemble the form |
|
$interface_form .= $anvil->Template->get({file => "anvil.html", name => "network_interface_form", variables => { |
|
field => $anvil->Words->string({key => $name_key, variables => { number => $i }}), |
|
description => "#!string!".$description_key."!#", |
|
ip_key => $this_ip_key, |
|
ip_value => defined $anvil->data->{cgi}{$this_ip_key}{value} ? $anvil->data->{cgi}{$this_ip_key}{value} : "", |
|
ip_value_default => $this_ip, |
|
ip_class => $this_ip_class, |
|
subnet_mask_key => $this_subnet_mask_key, |
|
subnet_mask_value => defined $anvil->data->{cgi}{$this_subnet_mask_key}{value} ? $anvil->data->{cgi}{$this_subnet_mask_key}{value} : "", |
|
subnet_mask_value_default => $anvil->data->{defaults}{network}{bcn}{subnet_mask}, |
|
subnet_mask_class => $this_subnet_mask_class, |
|
iface1_select => $this_iface1_form, |
|
iface2_select => $this_iface2_form, |
|
network_name => $network.$i, |
|
create_bridge => $network eq "sn" ? 0 : 1, |
|
}}); |
|
} |
|
} |
|
|
|
# Host name |
|
my $say_host_name = defined $anvil->data->{cgi}{host_name}{value} ? $anvil->data->{cgi}{host_name}{value} : $host_name; |
|
my $host_name_class = $anvil->data->{cgi}{host_name}{alert} ? "input_alert" : "input_clear"; |
|
my $host_name_form = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "host_name", |
|
id => "host_name", |
|
field => "#!string!striker_0016!#", |
|
description => "#!string!striker_0143!#", |
|
value => defined $anvil->data->{cgi}{host_name}{value} ? $anvil->data->{cgi}{host_name}{value} : $say_host_name, |
|
default_value => "", |
|
class => $host_name_class, |
|
extra => "", |
|
}}); |
|
|
|
### NOTE: We'll figure out the IFN this belongs to by matching the DG to one of the IFN IPs. |
|
# Gateway |
|
my $gateway_class = $anvil->data->{cgi}{gateway}{alert} ? "input_alert" : "input_clear"; |
|
my $say_gateway = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "gateway", |
|
id => "gateway", |
|
field => "#!string!striker_0035!#", |
|
description => "#!string!striker_0144!#", |
|
value => defined $anvil->data->{cgi}{gateway}{value} ? $anvil->data->{cgi}{gateway}{value} : "", |
|
default_value => "", |
|
class => $gateway_class, |
|
extra => "", |
|
}}); |
|
|
|
# DNS |
|
my $dns_class = $anvil->data->{cgi}{dns}{alert} ? "input_alert" : "input_clear"; |
|
my $say_dns = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "dns", |
|
id => "dns", |
|
field => "#!string!striker_0037!#", |
|
description => "#!string!striker_0038!#", |
|
value => defined $anvil->data->{cgi}{dns}{value} ? $anvil->data->{cgi}{dns}{value} : "", |
|
default_value => $anvil->data->{defaults}{network}{dns}, |
|
class => $dns_class, |
|
extra => "", |
|
}}); |
|
|
|
# Store the previous CGI variables and display the new fields. |
|
$anvil->data->{form}{back_link} = "?anvil=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 => "anvil.html", name => "config-network-main", variables => { |
|
interface_form => $interface_form, |
|
gateway_form => $say_gateway, |
|
dns_form => $say_dns, |
|
host_name_form => $host_name_form, |
|
bcn_count => $bcn_pair_count, |
|
sn_count => $sn_pair_count, |
|
ifn_count => $ifn_pair_count, |
|
host_uuid => $anvil->data->{cgi}{host_uuid}{value}, |
|
host_name => $host_name, # This is the current host name, used to find the data in the all_status.json |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }}); |
|
|
|
return(0); |
|
} |
|
|
|
# This handles installing our repo, installing the appropriate 'anvil-X' rpm, running OS updates if selected |
|
# and configuring the network on a machine destined to be an Anvil! node or DR host. |
|
sub process_prep_host_page |
|
{ |
|
my ($anvil) = @_; |
|
|
|
my $host_name = defined $anvil->data->{cgi}{host_name}{value} ? $anvil->data->{cgi}{host_name}{value} : ""; |
|
my $host_uuid = defined $anvil->data->{cgi}{host_uuid}{value} ? $anvil->data->{cgi}{host_uuid}{value} : ""; |
|
my $default_host_name = defined $anvil->data->{cgi}{default_host_name}{value} ? $anvil->data->{cgi}{default_host_name}{value} : ""; |
|
my $host_ip_address = defined $anvil->data->{cgi}{host_ip_address}{value} ? $anvil->data->{cgi}{host_ip_address}{value} : ""; |
|
my $host_password = defined $anvil->data->{cgi}{host_password}{value} ? $anvil->data->{cgi}{host_password}{value} : ""; |
|
my $rh_user = defined $anvil->data->{cgi}{rh_user}{value} ? $anvil->data->{cgi}{rh_user}{value} : ""; |
|
my $rh_password = defined $anvil->data->{cgi}{rh_password}{value} ? $anvil->data->{cgi}{rh_password}{value} : ""; |
|
my $type = defined $anvil->data->{cgi}{type}{value} ? $anvil->data->{cgi}{type}{value} : ""; |
|
my $connect = defined $anvil->data->{cgi}{'connect'}{value} ? $anvil->data->{cgi}{'connect'}{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 => { |
|
host_name => $host_name, |
|
host_uuid => $host_uuid, |
|
default_host_name => $default_host_name, |
|
host_ip_address => $host_ip_address, |
|
host_password => $anvil->Log->is_secure($host_password), |
|
rh_user => $rh_user, |
|
rh_password => $anvil->Log->is_secure($rh_password), |
|
type => $type, |
|
'connect' => $connect, |
|
confirm => $confirm, |
|
}}); |
|
|
|
# Is the IP or host name valid? |
|
my $ssh_port = 22; |
|
if ($host_ip_address =~ /:(\d+)$/) |
|
{ |
|
$ssh_port = $1; |
|
$host_ip_address =~ s/:(\d+)$//; |
|
} |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
ssh_port => $ssh_port, |
|
host_ip_address => $host_ip_address, |
|
}}); |
|
|
|
# If we've been passed 'connect', verify we can connect. |
|
if (($connect) && ($confirm)) |
|
{ |
|
# Save the job |
|
my $job_command = $anvil->data->{path}{exe}{'striker-initialize-host'}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
job_command => $job_command, |
|
password => $anvil->Log->is_secure($host_password), |
|
}}); |
|
|
|
# Update the database to mark this machine as unconfigured (in case we're rebuilding a |
|
# previously known system). This is needed to get the netweork link state info updating. |
|
if ($host_uuid) |
|
{ |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "system::configured", |
|
variable_source_uuid => $host_uuid, |
|
variable_source_table => "hosts", |
|
variable_value => 0, |
|
update_value_only => 1, |
|
}); |
|
} |
|
|
|
# Are we setting a host name? |
|
my $say_host_name = "host_name=\n"; |
|
if (($host_name) && ($host_name ne $default_host_name)) |
|
{ |
|
$say_host_name = "host_name=".$host_name."\n"; |
|
} |
|
|
|
# Store the peer's password as the job data |
|
my $job_data = "password=".$host_password."\n"; |
|
$job_data .= "rh_password=".$rh_password."\n"; |
|
$job_data .= "rh_user=".$rh_user."\n"; |
|
$job_data .= "host_ip_address=".$host_ip_address."\n"; |
|
$job_data .= "ssh_port=".$ssh_port."\n"; |
|
$job_data .= "type=".$type."\n"; |
|
$job_data .= $say_host_name; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { job_data => $job_data }}); |
|
|
|
# Store the job |
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ |
|
debug => 3, |
|
file => $THIS_FILE, |
|
line => __LINE__, |
|
job_command => $job_command, |
|
job_data => $job_data, |
|
job_name => "initialize::".$type."::".$host_ip_address, |
|
job_title => $type eq "dr" ? "job_0021" : "job_0020", |
|
job_description => "job_0022", |
|
job_progress => 0, |
|
}); |
|
$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."?anvil=true&", |
|
title => "#!string!striker_0044!#", |
|
description => "#!string!striker_0129!#", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
} |
|
elsif ($connect) |
|
{ |
|
if (not $anvil->Validate->is_ipv4({ip => $host_ip_address})) |
|
{ |
|
# Bad IP |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0010", variables => { ip_address => $host_ip_address }}) }}); |
|
} |
|
elsif (($ssh_port < 1) or ($ssh_port > 65535)) |
|
{ |
|
# Bad port |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0011"}) }}); |
|
} |
|
else |
|
{ |
|
# Can we connect? |
|
my $target_host_name = ""; |
|
my $target_host_uuid = ""; |
|
my $has_internet = 0; |
|
my ($connected, $data) = $anvil->Striker->get_peer_data({ |
|
debug => 2, |
|
target => $host_ip_address, |
|
password => $host_password, |
|
port => $ssh_port, |
|
}); |
|
foreach my $key (sort {$a cmp $b} keys %{$data}) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "data->{$key}" => $data->{$key} }}); |
|
} |
|
if ($data->{host_name}) |
|
{ |
|
# We collect this, but apparently not for any real reason... |
|
$target_host_name = $data->{host_name}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target_host_name => $target_host_name }}); |
|
} |
|
if ($data->{host_uuid}) |
|
{ |
|
$target_host_uuid = $data->{host_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target_host_uuid => $target_host_uuid }}); |
|
} |
|
if ($data->{internet}) |
|
{ |
|
$has_internet = $data->{internet}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { has_internet => $has_internet }}); |
|
} |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
target_host_name => $target_host_name, |
|
target_host_uuid => $target_host_uuid, |
|
}}); |
|
|
|
# If the target is RHEL and it is not registered, offer the user to provide the RH user and password. |
|
my $redhat_message = ""; |
|
my $redhat_form = ""; |
|
if (($data->{host_os} =~ /^rhel/) && ($data->{os_registered} ne "yes")) |
|
{ |
|
# If we don't have internet access, tell the user they can register later. |
|
if ($has_internet) |
|
{ |
|
$redhat_message = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-message", variables => { message => "#!string!message_0148!#" }}); |
|
$redhat_form = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-form", variables => { |
|
rh_user => $rh_user, |
|
rh_password => $rh_password, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
redhat_form => $redhat_form, |
|
redhat_message => $redhat_message, |
|
}}); |
|
} |
|
else |
|
{ |
|
$redhat_message = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-message", variables => { message => "#!string!message_0151!#" }}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { redhat_message => $redhat_message }}); |
|
} |
|
} |
|
elsif (not $has_internet) |
|
{ |
|
$redhat_message = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-message", variables => { message => "#!string!message_01512#" }}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { redhat_message => $redhat_message }}); |
|
} |
|
|
|
# Did we connect? |
|
if (not $connected) |
|
{ |
|
# Nope. Is it because the target's key is bad or has changed? |
|
my $query = "SELECT state_uuid, state_note FROM states WHERE state_name LIKE ".$anvil->Database->quote("host_key_changed::".$host_ip_address).";"; |
|
$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. |
|
my $state_uuid = $results->[0]->[0]; |
|
my $state_note = $results->[0]->[1]; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
state_uuid => $state_uuid, |
|
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 $error_message = $anvil->Words->string({key => "warning_0013", variables => { |
|
file => $bad_file, |
|
line => $bad_line, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { error_message => $error_message }}); |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); |
|
} |
|
else |
|
{ |
|
# Nope, some other issue |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0012"}) }}); |
|
} |
|
} |
|
elsif (not $target_host_uuid) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0005", variables => { uuid => $target_host_uuid }}) }}); |
|
} |
|
else |
|
{ |
|
# Connected! Ask th euser to confirm. |
|
my $new_host_name = "#!string!striker_0139!#"; |
|
if ((exists $anvil->data->{cgi}{host_name}) && ($anvil->data->{cgi}{host_name}{value})) |
|
{ |
|
$new_host_name = $anvil->data->{cgi}{host_name}{value}; |
|
} |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_host_name => $new_host_name }}); |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "confirm-initialize-host", variables => { |
|
'package' => $type eq "dr" ? "anvil-dr" : "anvil-node", |
|
redhat_message => $redhat_message, |
|
redhat_form => $redhat_form, |
|
access => "root\@".$host_ip_address.":".$ssh_port, |
|
current_host_name => $target_host_name, |
|
new_host_name => $new_host_name, |
|
host_uuid => $target_host_uuid, |
|
default_host_name => $default_host_name, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
} |
|
} |
|
} |
|
|
|
if ((not $anvil->data->{form}{body}) or ($anvil->data->{form}{error_massage})) |
|
{ |
|
my $node_checked = "checked"; |
|
my $dr_checked = ""; |
|
if ($type eq "dr") |
|
{ |
|
$node_checked = ""; |
|
$dr_checked = "checked"; |
|
} |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
node_checked => $node_checked, |
|
dr_checked => $dr_checked, |
|
}}); |
|
|
|
my $host_name = $anvil->_host_name; |
|
$host_name =~ s/striker\d\d/xxx/; |
|
my $default_host_name = $host_name; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
default_host_name => $default_host_name, |
|
host_name => $host_name, |
|
}}); |
|
if ((exists $anvil->data->{cgi}{host_name}) && ($anvil->data->{cgi}{host_name}{value})) |
|
{ |
|
$host_name = $anvil->data->{cgi}{host_name}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }}); |
|
} |
|
|
|
my $form_body = $anvil->Template->get({file => "anvil.html", name => "host-setup-menu1", variables => { |
|
host_name => $host_name, |
|
default_host_name => $default_host_name, |
|
host_ip_address => $host_ip_address, |
|
node_checked => $node_checked, |
|
dr_checked => $dr_checked, |
|
}}); |
|
|
|
$anvil->data->{form}{refresh_link} = "?anvil=true&task=prep-host"; |
|
$anvil->data->{form}{back_link} = "?anvil=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 => "anvil.html", name => "prep-host-main", variables => { |
|
form => $form_body, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }}); |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
# This enables or disables the Install Target feature |
|
sub process_install_target |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# NOTE: We don't ask for confirmation, it's a low risk task. |
|
# What are we doing? |
|
$anvil->data->{cgi}{subtask}{value} = "" if not defined $anvil->data->{cgi}{subtask}{value}; |
|
if (($anvil->data->{cgi}{subtask}{value} eq "enable") or ($anvil->data->{cgi}{subtask}{value} eq "disable")) |
|
{ |
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ |
|
file => $THIS_FILE, |
|
line => __LINE__, |
|
job_command => $anvil->data->{path}{exe}{'striker-manage-install-target'}." --".$anvil->data->{cgi}{subtask}{value}, |
|
job_data => "", |
|
job_name => "install-target::".$anvil->data->{cgi}{task}{value}, |
|
job_title => "job_0015", |
|
job_description => "job_0016", |
|
job_progress => 0, |
|
}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }}); |
|
|
|
# Show the use that the job has been saved. |
|
my $message = "striker_0111"; |
|
if ($anvil->data->{cgi}{subtask}{value} eq "enable") |
|
{ |
|
$message = "striker_0112"; |
|
} |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => { |
|
title_id => "", |
|
message_id => "", |
|
reload_url => "/cgi-bin/".$THIS_FILE."?striker=true", |
|
title => "#!string!striker_0044!#", |
|
description => "#!string!".$message."!#", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
} |
|
else |
|
{ |
|
# Just ignore it, someone's mucking with the subask value. |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0009"}) }}); |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
# This handles powering off or rebooting this machine |
|
sub process_power |
|
{ |
|
my ($anvil, $task) = @_; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { task => $task }}); |
|
|
|
$anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{value}; |
|
if ($anvil->data->{cgi}{confirm}{value}) |
|
{ |
|
# Record the job! |
|
my $job_command = $anvil->data->{path}{exe}{'anvil-manage-power'}." --reboot -y"; |
|
my $job_title = "job_0009"; |
|
my $job_description = "job_0006"; |
|
my $say_title = "#!string!job_0005!#"; |
|
my $say_description = "#!string!job_0006!#"; |
|
if ($task eq "poweroff") |
|
{ |
|
$job_command = $anvil->data->{path}{exe}{'anvil-manage-power'}." --poweroff -y"; |
|
$job_title = "job_0010"; |
|
$job_description = "job_0008"; |
|
$say_title = "#!string!job_0007!#"; |
|
$say_description = "#!string!job_0008!#"; |
|
} |
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ |
|
file => $THIS_FILE, |
|
line => __LINE__, |
|
job_command => $job_command, |
|
job_data => "", |
|
job_name => "reboot::system", |
|
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 }}); |
|
|
|
# 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 => $say_title, |
|
description => $say_description, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
|
|
# Log the user out, just to be safe. |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0215"}); |
|
$anvil->Account->logout({debug => 2}); |
|
} |
|
else |
|
{ |
|
# Show the screen the confirm the addition. |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "confirm-action", variables => { |
|
title => $task eq "poweroff" ? "#!string!job_0007!#" : "#!string!job_0005!#", |
|
message => $task eq "poweroff" ? "#!string!striker_0101!#" : "#!string!striker_0100!#", |
|
hidden_fields => "", |
|
}}); |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
# This handles updating this Striker. |
|
sub process_update |
|
{ |
|
my ($anvil) = @_; |
|
|
|
$anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{value}; |
|
if ($anvil->data->{cgi}{confirm}{value}) |
|
{ |
|
# Record the job! |
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ |
|
debug => 1, |
|
file => $THIS_FILE, |
|
line => __LINE__, |
|
job_command => $anvil->data->{path}{exe}{'anvil-update-system'}, |
|
job_data => "", |
|
job_name => "update::system", |
|
job_title => "job_0003", |
|
job_description => "job_0004", |
|
job_progress => 0, |
|
}); |
|
$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!striker_0044!#", |
|
description => "#!string!striker_0088!#", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
|
|
# Set maintenance mode. |
|
$anvil->System->maintenance_mode({set => 1}); |
|
} |
|
else |
|
{ |
|
# Show the screen the confirm the addition. |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "confirm-action", variables => { |
|
title => "#!string!striker_0078!#", |
|
message => "#!string!striker_0086!#", |
|
hidden_fields => "", |
|
}}); |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
# This handles reconfiguring the Striker system. |
|
sub process_reconfig_page |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# Later, this will let each piece be recondigured. For now, it simple reset the "configured flag so |
|
# the next load will trigger the initial config again. |
|
$anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{value}; |
|
if ($anvil->data->{cgi}{confirm}{value}) |
|
{ |
|
# Update the configured variable |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "system::configured", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
variable_value => 0, |
|
update_value_only => 1, |
|
}); |
|
|
|
# Done. |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "reconfig-done"}); |
|
} |
|
else |
|
{ |
|
# Show the screen the confirm the addition. |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "confirm-reconfig"}); |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
# This handles tasks related to setting up peer Strikers. |
|
sub process_sync_page |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# Setup some CGI values we might use. |
|
$anvil->data->{cgi}{new_peer_access}{value} = "" if not defined $anvil->data->{cgi}{new_peer_access}{value}; |
|
$anvil->data->{cgi}{new_peer_password}{value} = "" if not defined $anvil->data->{cgi}{new_peer_password}{value}; |
|
$anvil->data->{cgi}{save}{value} = "" if not defined $anvil->data->{cgi}{save}{value}; |
|
$anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{value}; |
|
|
|
# This handles checkboxes |
|
if (defined $anvil->data->{cgi}{new_peer_ping}{value}) |
|
{ |
|
$anvil->data->{cgi}{new_peer_ping}{value} = "" if $anvil->data->{cgi}{new_peer_ping}{value} ne "on"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::new_peer_ping::value" => $anvil->data->{cgi}{new_peer_ping}{value} }}); |
|
} |
|
else |
|
{ |
|
$anvil->data->{cgi}{new_peer_ping}{value} = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::new_peer_ping::value" => $anvil->data->{cgi}{new_peer_ping}{value} }}); |
|
} |
|
if (defined $anvil->data->{cgi}{new_peer_bidirection}{value}) |
|
{ |
|
$anvil->data->{cgi}{new_peer_bidirection}{value} = "" if $anvil->data->{cgi}{new_peer_bidirection}{value} ne "on"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::new_peer_bidirection::value" => $anvil->data->{cgi}{new_peer_bidirection}{value} }}); |
|
} |
|
else |
|
{ |
|
$anvil->data->{cgi}{new_peer_bidirection}{value} = ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::new_peer_bidirection::value" => $anvil->data->{cgi}{new_peer_bidirection}{value} }}); |
|
} |
|
|
|
# Are we deleting or adding a new peer? |
|
if ($anvil->data->{cgi}{'delete'}{value}) |
|
{ |
|
delete_sync_peer($anvil); |
|
} |
|
elsif (($anvil->data->{cgi}{new_peer_access}{value}) && ($anvil->data->{cgi}{new_peer_password}{value} ne "")) |
|
{ |
|
add_sync_peer($anvil); |
|
} |
|
|
|
# If we've got a body now, return. |
|
if ($anvil->data->{form}{body}) |
|
{ |
|
# We're done |
|
return(0); |
|
} |
|
|
|
my $host_uuid = $anvil->Get->host_uuid; |
|
$anvil->Network->get_ips(); |
|
|
|
# We'll want to show the user way to access the local machine. For that, we'll loop through our own IPs. |
|
my $inbound_table = ""; |
|
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}}) |
|
{ |
|
next if (($interface !~ /^bcn/) && ($interface !~ /^ifn/)); |
|
next if not $anvil->Validate->is_ipv4({ip => $anvil->data->{network}{'local'}{interface}{$interface}{ip}}); |
|
next if not $anvil->Validate->is_subnet_mask({subnet_mask => $anvil->data->{network}{'local'}{interface}{$interface}{subnet_mask}}); |
|
my ($network_type, $network_number) = ($interface =~ /^(.*?)(\d+)_/); |
|
|
|
my $database_user = $anvil->data->{database}{$host_uuid}{user} ? $anvil->data->{database}{$host_uuid}{user} : $anvil->data->{sys}{database}{user}; |
|
my $database_port = $anvil->data->{database}{$host_uuid}{port}; |
|
my $network_key = $network_type eq "bcn" ? "striker_0018" : "striker_0022"; |
|
my $say_network = $anvil->Words->string({key => $network_key, variables => { number => $network_number }}); |
|
|
|
# The user 'admin' and the port 5432 are default, so only show them if they're non-standard. |
|
my $access_string = $database_user."\@".$anvil->data->{network}{'local'}{interface}{$interface}{ip}.":".$database_port; |
|
if (($database_port eq "5432") && ($database_user eq "admin")) |
|
{ |
|
$access_string = $anvil->data->{network}{'local'}{interface}{$interface}{ip}; |
|
} |
|
elsif ($database_port eq "5432") |
|
{ |
|
$access_string = $database_user."\@".$anvil->data->{network}{'local'}{interface}{$interface}{ip}; |
|
} |
|
elsif ($database_user eq "admin") |
|
{ |
|
$access_string = $anvil->data->{network}{'local'}{interface}{$interface}{ip}.":".$database_port; |
|
} |
|
$inbound_table .= $anvil->Template->get({file => "striker.html", name => "striker-sync-inbound", variables => { |
|
access => $access_string, |
|
note => $say_network, |
|
}}); |
|
} |
|
|
|
# This needs to be loaded into a hash by target, the sorted. We'll build the table on sort. |
|
my $peer_table = ""; |
|
foreach my $uuid (keys %{$anvil->data->{database}}) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid => $uuid }}); |
|
|
|
next if not $anvil->Validate->is_uuid({uuid => $uuid}); |
|
next if $uuid eq $host_uuid; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid => $uuid }}); |
|
|
|
my $host = $anvil->data->{database}{$uuid}{host} ? $anvil->data->{database}{$uuid}{host} : ""; # This should fail |
|
my $port = $anvil->data->{database}{$uuid}{port} ? $anvil->data->{database}{$uuid}{port} : 5432; |
|
my $name = $anvil->data->{database}{$uuid}{name} ? $anvil->data->{database}{$uuid}{name} : $anvil->data->{sys}{database}{name}; |
|
my $user = $anvil->data->{database}{$uuid}{user} ? $anvil->data->{database}{$uuid}{user} : $anvil->data->{sys}{database}{user}; |
|
my $ping = $anvil->data->{database}{$uuid}{ping} ? $anvil->data->{database}{$uuid}{ping} : 1; |
|
my $password = $anvil->data->{database}{$uuid}{password} ? $anvil->data->{database}{$uuid}{password} : ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
host => $host, |
|
port => $port, |
|
name => $name, |
|
user => $user, |
|
ping => $ping, |
|
password => $anvil->Log->is_secure($password), |
|
}}); |
|
|
|
# Store it by name. |
|
$anvil->data->{peers}{$host}{port} = $port; |
|
$anvil->data->{peers}{$host}{name} = $name; |
|
$anvil->data->{peers}{$host}{user} = $user; |
|
$anvil->data->{peers}{$host}{ping} = $ping; |
|
$anvil->data->{peers}{$host}{uuid} = $uuid; |
|
$anvil->data->{peers}{$host}{password} = $password; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"peers::${host}::port" => $anvil->data->{peers}{$host}{port}, |
|
"peers::${host}::name" => $anvil->data->{peers}{$host}{name}, |
|
"peers::${host}::ping" => $anvil->data->{peers}{$host}{ping}, |
|
"peers::${host}::uuid" => $anvil->data->{peers}{$host}{uuid}, |
|
"peers::${host}::password" => $anvil->Log->is_secure($anvil->data->{peers}{$host}{password}), |
|
}}); |
|
} |
|
|
|
# Now peers are sortable by host name. |
|
foreach my $host (sort {$a cmp $b} keys %{$anvil->data->{peers}}) |
|
{ |
|
my $port = $anvil->data->{peers}{$host}{port}; |
|
my $name = $anvil->data->{peers}{$host}{name}; |
|
my $user = $anvil->data->{peers}{$host}{user}; |
|
my $ping = $anvil->data->{peers}{$host}{ping}; |
|
my $uuid = $anvil->data->{peers}{$host}{uuid}; |
|
my $password = $anvil->data->{peers}{$host}{password}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
host => $host, |
|
port => $port, |
|
name => $name, |
|
user => $user, |
|
ping => $ping, |
|
uuid => $uuid, |
|
password => $anvil->Log->is_secure($password), |
|
}}); |
|
|
|
$anvil->data->{cgi}{new_peer_password}{value} = "" if not defined $anvil->data->{cgi}{new_peer_password}{value}; |
|
$peer_table .= $anvil->Template->get({file => "striker.html", name => "striker-sync-entry", variables => { |
|
uuid => $uuid, |
|
access => $port eq 5432 ? $user."\@".$host : $user."\@".$host.":".$port, |
|
password => $anvil->data->{cgi}{new_peer_password}{value}, |
|
say_ping => $ping ? "#!string!unit_0001!#" : "#!string!unit_0002!#", |
|
}}); |
|
} |
|
|
|
# Build the menu. |
|
$anvil->data->{form}{refresh_link} = "?striker=true&task=sync"; |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "striker-sync", variables => { |
|
inbound_table => $inbound_table, |
|
peer_table => $peer_table, |
|
new_peer_access => defined $anvil->data->{cgi}{new_peer_access}{value} ? $anvil->data->{cgi}{new_peer_access}{value} : "", |
|
new_peer_password => defined $anvil->data->{cgi}{new_peer_password}{value} ? $anvil->data->{cgi}{new_peer_password}{value} : "", |
|
}}); |
|
|
|
return(0); |
|
} |
|
|
|
# This deletes a sync peer. |
|
sub delete_sync_peer |
|
{ |
|
my ($anvil) = @_; |
|
|
|
my $uuid = $anvil->data->{cgi}{'delete'}{value}; |
|
my $host_name = $anvil->Get->host_name({host_uuid => $uuid}); |
|
my $host = $anvil->data->{database}{$uuid}{host} ? $anvil->data->{database}{$uuid}{host} : ""; # This should fail |
|
my $name = $anvil->data->{database}{$uuid}{name} ? $anvil->data->{database}{$uuid}{name} : $anvil->data->{sys}{database}{name}; |
|
my $user = $anvil->data->{database}{$uuid}{user} ? $anvil->data->{database}{$uuid}{user} : $anvil->data->{sys}{database}{user}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
uuid => $uuid, |
|
host_name => $host_name, |
|
host => $host, |
|
name => $name, |
|
user => $user, |
|
}}); |
|
|
|
# Is the delete confirmed? |
|
if ($anvil->data->{cgi}{confirm}{value}) |
|
{ |
|
# OK, save the job! |
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ |
|
debug => 3, |
|
file => $THIS_FILE, |
|
line => __LINE__, |
|
job_command => $anvil->data->{path}{exe}{'striker-manage-peers'}." --remove --host-uuid ".$uuid, |
|
job_data => "", |
|
job_name => "striker-peer::remove", |
|
job_title => "job_0013", |
|
job_description => "job_0014", |
|
job_progress => 0, |
|
}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }}); |
|
|
|
# Show the use that the job has been saved. |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => { |
|
title_id => "", |
|
message_id => "", |
|
reload_url => "/cgi-bin/".$THIS_FILE."?striker=true&task=sync", |
|
title => "#!string!striker_0044!#", |
|
description => "#!string!striker_0104!#", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
} |
|
else |
|
{ |
|
# Show the screen the confirm the addition. |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "confirm-action", variables => { |
|
title => "#!string!job_0013!#", |
|
message => $anvil->Words->string({key => "striker_0105", variables => { peer => $user."\@".$host_name }}), |
|
hidden_fields => "<input type=\"hidden\" name=\"delete\" id=\"delete\" value=\"".$uuid."\" />", |
|
}}); |
|
} |
|
|
|
|
|
return(0); |
|
} |
|
|
|
# This adds a new peer to anvil.conf. |
|
sub add_sync_peer |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# Break up the user, host and port. If anything goes wrong, we'll set an error and send it back. |
|
my $pgsql_user = $anvil->data->{sys}{database}{user}; |
|
my $host = $anvil->data->{cgi}{new_peer_access}{value}; |
|
my $password = $anvil->data->{cgi}{new_peer_password}{value}; |
|
my $db_name = $anvil->data->{sys}{database}{name}; |
|
my $ping = $anvil->data->{cgi}{new_peer_ping}{value} eq "on" ? 1 : 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
pgsql_user => $pgsql_user, |
|
host => $host, |
|
password => $anvil->Log->is_secure($password), |
|
db_name => $db_name, |
|
ping => $ping, |
|
}}); |
|
|
|
my $pgsql_port = 5432; |
|
my $ssh_port = 22; |
|
my $peer_host_uuid = ""; |
|
my $peer_host_name = ""; |
|
my $use_ip = ""; # This will contain the local IP to use for the peer to setup comms with us |
|
if ($host =~ /,ssh=(\d+)$/) |
|
{ |
|
$ssh_port = $1; |
|
$host =~ s/,ssh=\d+$//; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
ssh_port => $ssh_port, |
|
host => $host, |
|
}}); |
|
} |
|
if ($host =~ /^(.*?)\@(.*?):(\d+)$/) |
|
{ |
|
$pgsql_user = $1; |
|
$host = $2; |
|
$pgsql_port = $3; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
host => $host, |
|
pgsql_port => $pgsql_port, |
|
pgsql_user => $pgsql_user, |
|
}}); |
|
} |
|
elsif ($host =~ /^(.*?)\@(.*?)$/) |
|
{ |
|
$pgsql_user = $1; |
|
$host = $2; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
host => $host, |
|
pgsql_user => $pgsql_user, |
|
}}); |
|
} |
|
elsif ($host =~ /^(.*?):(\d+)$/) |
|
{ |
|
$host = $1; |
|
$pgsql_port = $2; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
host => $host, |
|
pgsql_port => $pgsql_port, |
|
}}); |
|
} |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
ssh_port => $ssh_port, |
|
host => $host, |
|
pgsql_port => $pgsql_port, |
|
pgsql_user => $pgsql_user, |
|
}}); |
|
|
|
# Is the host a domain or IP? |
|
# If so, and 'bi-directional' is set, verify we can ssh into the peer. |
|
my $is_domain = $anvil->Validate->is_domain_name({name => $host}); |
|
my $is_ipv4 = $anvil->Validate->is_ipv4({ip => $host}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
is_domain => $is_domain, |
|
is_ipv4 => $is_ipv4, |
|
pgsql_port => $pgsql_port, |
|
}}); |
|
if (((not $is_domain) && (not $is_ipv4)) or ($pgsql_port < 1) or ($pgsql_port > 65536)) |
|
{ |
|
# Bad host. |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0002"}) }}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
}}); |
|
} |
|
else |
|
{ |
|
my ($connected, $data) = $anvil->Striker->get_peer_data({ |
|
debug => 2, |
|
target => $host, |
|
password => $password, |
|
port => $ssh_port, |
|
}); |
|
if ($data->{host_name}) |
|
{ |
|
# We collect this, but apparently not for any real reason... |
|
$peer_host_name = $data->{host_name}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_host_name => $peer_host_name }}); |
|
} |
|
if ($data->{host_uuid}) |
|
{ |
|
$peer_host_uuid = $data->{host_uuid}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_host_uuid => $peer_host_uuid }}); |
|
} |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
peer_host_name => $peer_host_name, |
|
peer_host_uuid => $peer_host_uuid, |
|
}}); |
|
|
|
if ((not $connected) or (not $peer_host_uuid)) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0005", variables => { uuid => $peer_host_uuid }}) }}); |
|
} |
|
|
|
# Lastly, if bi-directional is set, make sure we have a way to talk to it. |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::new_peer_bidirection::value" => $anvil->data->{cgi}{new_peer_bidirection}{value} }}); |
|
if ($anvil->data->{cgi}{new_peer_bidirection}{value} eq "on") |
|
{ |
|
# See which of our IPs match theirs. If the peer is a host name, first, find the IP. |
|
$use_ip = $anvil->System->find_matching_ip({host => $host}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { use_ip => $use_ip }}); |
|
|
|
if ((not $use_ip) or ($use_ip eq "!!error!!")) |
|
{ |
|
# Can't do bi-directional |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0008", variables => { host => $host }}) }}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"form::error_massage" => $anvil->data->{form}{error_massage}, |
|
}}); |
|
} |
|
} |
|
} |
|
|
|
# Now, verify we can access the peer database. This will involve writting out a .pgpass file, then making a local system call. |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }}); |
|
if (not $anvil->data->{form}{error_massage}) |
|
{ |
|
my $pgpass_file = "/tmp/.pgpass"; |
|
$password =~ s/:/\:/g; |
|
my $body = $host.":".$pgsql_port.":".$db_name.":".$pgsql_user.":".$password; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { |
|
body => $body, |
|
}}); |
|
$anvil->Storage->write_file({ |
|
file => $pgpass_file, |
|
body => $body, |
|
mode => "0600", |
|
secure => 1, |
|
overwrite => 1, |
|
}); |
|
|
|
# This will return '1' only, if it works. |
|
my ($db_access, $return_code) = $anvil->System->call({shell_call => "PGPASSFILE=\"".$pgpass_file."\" ".$anvil->data->{path}{exe}{psql}." --host ".$host." --port ".$pgsql_port." --dbname ".$db_name." --username ".$pgsql_user." --no-password --tuples-only --no-align --command \"SELECT 1\""}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { db_access => $db_access, return_code => $return_code }}); |
|
if ($db_access ne "1") |
|
{ |
|
# Failed to connect. |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0004"}) }}); |
|
} |
|
|
|
# Delete the pgpass file. |
|
unlink $pgpass_file; |
|
} |
|
|
|
# If an error was set, clear the 'save' and 'confirm' values. |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage} }}); |
|
if ($anvil->data->{form}{error_massage}) |
|
{ |
|
$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}, |
|
}}); |
|
} |
|
else |
|
{ |
|
# Things look good. Is the save confirmed? |
|
if ($anvil->data->{cgi}{confirm}{value}) |
|
{ |
|
# OK, save the job! |
|
my $job_command = $anvil->data->{path}{exe}{'striker-manage-peers'}." --add --host-uuid ".$peer_host_uuid." --host ".$host." --port ".$pgsql_port." --ping ".$ping; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
job_command => $job_command, |
|
password => $anvil->Log->is_secure($password), |
|
}}); |
|
|
|
# The job data will always contain the password for the peer, but also contain the |
|
# command for the peer to add us if 'bidirectional' was selected. This has to be |
|
# stored separately and not added directly as a job, because the peer is likely not |
|
# in 'hosts' yet, and thus we can't reference it in 'job_host_uuid' at this point. |
|
my $job_data = "password=".$password; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { job_data => $job_data }}); |
|
|
|
# Are we adding ourselves to the peer? |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { use_ip => $use_ip }}); |
|
if ($use_ip) |
|
{ |
|
# See which of our IPs match theirs. If the peer is a host name, first |
|
my $host_uuid = $anvil->Get->host_uuid; |
|
my $sql_port = $anvil->data->{database}{$host_uuid}{port}; |
|
my $job_command = $anvil->data->{path}{exe}{'striker-manage-peers'}." --add --host-uuid ".$host_uuid." --host ".$use_ip." --port ".$sql_port." --ping ".$ping; |
|
$job_data .= "\npeer_job_command=".$job_command; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
job_command => $job_command, |
|
job_data => $anvil->Log->is_secure($job_data), |
|
}}); |
|
} |
|
|
|
# Store the job |
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ |
|
debug => 3, |
|
file => $THIS_FILE, |
|
line => __LINE__, |
|
job_command => $job_command, |
|
job_data => $job_data, |
|
job_name => "striker-peer::add", |
|
job_title => "job_0011", |
|
job_description => "job_0012", |
|
job_progress => 0, |
|
}); |
|
$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."?striker=true&task=sync", |
|
title => "#!string!striker_0044!#", |
|
description => $ping ? "#!string!striker_0103!#" : "#!string!striker_0102!#", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
} |
|
else |
|
{ |
|
# Show the screen the confirm the addition. |
|
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "confirm-new-peer", variables => { |
|
access => $pgsql_user."@".$host.":".$pgsql_port, |
|
ping => $anvil->data->{cgi}{new_peer_ping}{value} ? "#!string!unit_0001!#" : "#!string!unit_0002!#", |
|
bidirectional => $anvil->data->{cgi}{new_peer_bidirection}{value} ? "#!string!unit_0001!#" : "#!string!unit_0002!#", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
} |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
# This shows the menus for configuring Striker. |
|
sub configure_striker |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# This will be true when the dashboard is unconfigured. |
|
if (not $anvil->data->{cgi}{step}{value}) |
|
{ |
|
$anvil->data->{form}{body} = config_step1($anvil); |
|
} |
|
elsif ($anvil->data->{cgi}{step}{value} eq "step1") |
|
{ |
|
# Sanity check step1. |
|
my $sane = sanity_check_step1($anvil); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { sane => $sane }}); |
|
if ($sane) |
|
{ |
|
# Step 1 was sane, show step 2. |
|
$anvil->data->{form}{body} = config_step2($anvil); |
|
} |
|
else |
|
{ |
|
# No good |
|
$anvil->data->{form}{body} = config_step1($anvil); |
|
} |
|
} |
|
elsif ($anvil->data->{cgi}{step}{value} eq "step2") |
|
{ |
|
# Sanity check step1. |
|
my $sane = sanity_check_step2($anvil); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { sane => $sane }}); |
|
if ($sane) |
|
{ |
|
# Step 2 was sane, show step 3. |
|
$anvil->data->{form}{body} = config_step3($anvil); |
|
} |
|
else |
|
{ |
|
# No good |
|
$anvil->data->{form}{body} = config_step2($anvil); |
|
} |
|
} |
|
elsif ($anvil->data->{cgi}{step}{value} eq "step3") |
|
{ |
|
# User has confirmed, update the system! |
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ |
|
debug => 3, |
|
file => $THIS_FILE, |
|
line => __LINE__, |
|
job_command => $anvil->data->{path}{exe}{'anvil-configure-host'}, |
|
job_data => "form::config_step2", |
|
job_name => "configure::network", |
|
job_title => "job_0001", |
|
job_description => "job_0002", |
|
job_progress => 0, |
|
}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { job_uuid => $job_uuid }}); |
|
|
|
# Set maintenance mode. |
|
$anvil->System->maintenance_mode({set => 1}); |
|
|
|
# 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 => "network_job_recorded", variables => { |
|
title_id => "", |
|
message_id => "", |
|
reload_url => "/cgi-bin/".$THIS_FILE, |
|
title => "#!string!striker_0044!#", |
|
description => "#!string!striker_0045!#", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); |
|
} |
|
else |
|
{ |
|
$anvil->data->{form}{body} = get_network_details_form($anvil); |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
# This checks to see if anything is running that requires Striker being unavailable. If not, this returns |
|
# '1'. If there is a job pending/running, it returns '0' |
|
sub check_availability |
|
{ |
|
my ($anvil) = @_; |
|
|
|
my $available = 1; |
|
|
|
# Check maintenance mode. |
|
my $maintenance_mode = $anvil->System->maintenance_mode({debug => 3}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { maintenance_mode => $maintenance_mode }}); |
|
|
|
if ($maintenance_mode) |
|
{ |
|
$available = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { available => $available }}); |
|
|
|
# If we have any running or recently finished jobs, we'll desplay them below. |
|
$anvil->data->{say}{maintenance} = $anvil->Template->get({file => "striker.html", name => "striker-offline", variables => { |
|
title_id => "", |
|
message_id => "", |
|
title => "#!string!striker_0046!#", |
|
description => $anvil->Words->string({key => "striker_0090", variables => {} }), |
|
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} }}); |
|
} |
|
|
|
# TODO: Phase this out |
|
if ($available) |
|
{ |
|
my $query = " |
|
SELECT |
|
job_progress, |
|
modified_date, |
|
extract(epoch from modified_date) |
|
FROM |
|
jobs |
|
WHERE |
|
job_name = 'configure::network' |
|
AND |
|
job_progress != 100 |
|
AND |
|
job_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." |
|
;"; |
|
$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, |
|
}}); |
|
if ($count) |
|
{ |
|
# We're waiting for the network configuration |
|
my $percent = $results->[0]->[0]; |
|
my $timestamp = $results->[0]->[1]; |
|
my $unixtime = $results->[0]->[2]; |
|
my $seconds_ago = $anvil->Convert->add_commas({number => (time - $unixtime)}); |
|
$available = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
available => $available, |
|
percent => $percent, |
|
seconds_ago => $seconds_ago, |
|
timestamp => $timestamp, |
|
unixtime => $unixtime, |
|
}}); |
|
|
|
$anvil->data->{say}{maintenance} = $anvil->Template->get({file => "striker.html", name => "striker-offline", variables => { |
|
title_id => "", |
|
message_id => "", |
|
title => "#!string!striker_0046!#", |
|
description => $anvil->Words->string({key => "striker_0047", variables => { percent => $percent, timestamp => $timestamp, seconds_ago => $seconds_ago }}), |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'say::maintenance' => $anvil->data->{say}{maintenance} }}); |
|
} |
|
} |
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { available => $available }}); |
|
return($available); |
|
} |
|
|
|
# This shows the user what is about to be done and asks the user to confirm. |
|
sub config_step3 |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# Read in all the variables from the database. We don't care what was passed, the data in the |
|
# database has been tested and is more valid than, say, a manipulated URL. |
|
my $cgi = ""; |
|
my $nets = {}; |
|
my $query = " |
|
SELECT |
|
variable_name, |
|
variable_value |
|
FROM |
|
variables |
|
WHERE |
|
(variable_section = 'config_step1' OR variable_section = 'config_step2') |
|
AND |
|
variable_source_table = 'hosts' |
|
AND |
|
variable_source_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." |
|
ORDER BY |
|
variable_name ASC;"; |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { 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}) |
|
{ |
|
my $variable_name = $row->[0]; |
|
my $variable_value = $row->[1]; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
variable_name => $variable_name, |
|
variable_value => $variable_value, |
|
}}); |
|
|
|
if ($variable_name =~ /form::config_step2::(.*?)::value/) |
|
{ |
|
my $variable = $1; |
|
$cgi .= $variable.","; |
|
$anvil->data->{cgi}{$variable}{value} = $variable_value; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${variable}::value" => $anvil->data->{cgi}{$variable}{value} }}); |
|
|
|
if (($variable =~ /^(bcn\d+)_/) or ($variable =~ /^(ifn\d+)_/)) |
|
{ |
|
my $this_net = $1; |
|
$nets->{$this_net} = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "nets->this_net" => $nets->{$this_net} }}); |
|
} |
|
} |
|
} |
|
|
|
#foreach my $key (sort {$a cmp $b} keys %ENV) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "ENV{$key}" => $ENV{$key} }}); } |
|
|
|
# Get the list of current IPs so that we can warn the user if committing the changes will require |
|
# reconnecting. |
|
$anvil->Network->get_ips({debug => 2}); |
|
my $matched_ip = 0; |
|
my $server_ip = $ENV{SERVER_ADDR}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_ip => $server_ip }}); |
|
|
|
# We'll need to show how networks will be configured. This depends on; |
|
# 1. Is it a bonded or single interface? |
|
# 2. Is it the interface with the gateway? |
|
# 3. If no gateway or DNS was specified, alert that there will be no outside access. |
|
get_network_details($anvil); |
|
my $networks = ""; |
|
foreach my $this_net (sort {$a cmp $b} keys %{$nets}) |
|
{ |
|
my $ip_key = $this_net."_ip"; |
|
my $subnet_mask_key = $this_net."_subnet_mask"; |
|
my $iface1_key = $this_net."_link1_mac_to_set"; |
|
my $iface2_key = $this_net."_link2_mac_to_set"; |
|
my $ip = $anvil->data->{cgi}{$ip_key}{value}; |
|
my $subnet_mask = $anvil->data->{cgi}{$subnet_mask_key}{value}; |
|
my $iface1_mac = $anvil->data->{cgi}{$iface1_key}{value}; |
|
my $iface2_mac = ((defined $anvil->data->{cgi}{$iface2_key}{value}) && ($anvil->data->{cgi}{$iface2_key}{value})) ? $anvil->data->{cgi}{$iface2_key}{value} : ""; |
|
my $template = $iface2_mac ? "step3_bonded_interface" : "step3_single_interface"; |
|
my $gateway = $anvil->data->{cgi}{gateway_interface}{value} eq $this_net ? 1 : 0; |
|
my $link_number = ($this_net =~ /n(\d+)$/)[0]; |
|
my $column = $this_net =~ /^bcn/ ? "striker_0018" : "striker_0022"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"s1:nets->this_net" => $nets->{$this_net}, |
|
"s2:ip" => $ip, |
|
"s3:subnet_mask" => $subnet_mask, |
|
"s4:iface1_mac" => $iface1_mac, |
|
"s5:iface2_mac" => $iface2_mac, |
|
"s6:template" => $template, |
|
"s7:gateway" => $gateway, |
|
"s8:link_number" => $link_number, |
|
}}); |
|
|
|
# Add to the networks template. |
|
my $say_ip = $ip."/".$subnet_mask; |
|
if (($gateway) && ($anvil->data->{cgi}{gateway}{value})) |
|
{ |
|
$template .= "_with_gateway"; |
|
$anvil->data->{cgi}{dns}{value} = "--" if not $anvil->data->{cgi}{dns}{value}; |
|
} |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { template => $template }}); |
|
$networks .= $anvil->Template->get({file => "config.html", name => $template, variables => { |
|
column => $anvil->Words->string({key => $column, variables => { number => $link_number }}), |
|
ip_address => $say_ip, |
|
ip => $ip, |
|
subnet_mask => $subnet_mask, |
|
primary => $iface1_mac, |
|
backup => $iface2_mac, |
|
gateway => $anvil->data->{cgi}{gateway}{value}, |
|
dns => $anvil->data->{cgi}{dns}{value}, |
|
}})."\n"; |
|
|
|
# Does this interface's IP match the active one? |
|
if ($server_ip eq $ip) |
|
{ |
|
# Yup! No need to warn the user |
|
$matched_ip = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { matched_ip => $matched_ip }}); |
|
} |
|
} |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }}); |
|
|
|
# If the IP is going to change, warn the user. |
|
if (not $matched_ip) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0001"}) }}); |
|
} |
|
|
|
# We don't need to store anything as hidden variables, we'll read it back from the database later. |
|
my $step3_body = $anvil->Template->get({file => "config.html", name => "config_step3", variables => { |
|
step1_welcome_title_id => "", |
|
step1_welcome_message_id => "", |
|
organization => $anvil->data->{cgi}{organization}{value}, |
|
prefix => $anvil->data->{cgi}{prefix}{value}, |
|
host_name => $anvil->data->{cgi}{host_name}{value}, |
|
striker_user => $anvil->data->{cgi}{striker_user}{value}, |
|
striker_password => $anvil->data->{cgi}{striker_password}{value}, |
|
networks => $networks, |
|
show_name => 1, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { step3_body => $step3_body }}); |
|
|
|
return($step3_body); |
|
} |
|
|
|
# This is step2 where the user maps their network. |
|
sub config_step2 |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# If I am coming from stage 1, load any values from the database, if they exist. |
|
if ($anvil->data->{cgi}{step}{value} eq "step1") |
|
{ |
|
# First load. See if we can read old data. We don't know for sure what variables will have |
|
# been set, so we'll load anything from the group 'config_step2'. |
|
my $query = " |
|
SELECT |
|
variable_name, |
|
variable_value |
|
FROM |
|
variables |
|
WHERE |
|
variable_section = 'config_step2' |
|
AND |
|
variable_source_table = 'hosts' |
|
AND |
|
variable_source_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." |
|
ORDER BY |
|
variable_name ASC;"; |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { 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}) |
|
{ |
|
my $variable_name = $row->[0]; |
|
my $variable_value = $row->[1]; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
variable_name => $variable_name, |
|
variable_value => $variable_value, |
|
}}); |
|
|
|
if ($variable_name =~ /form::config_step2::(.*?)::value/) |
|
{ |
|
my $variable = $1; |
|
$anvil->data->{cgi}{$variable}{value} = $variable_value; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${variable}::value" => $anvil->data->{cgi}{$variable}{value} }}); |
|
} |
|
} |
|
} |
|
|
|
# We need to decide how many IFNs there is, decide if we have enough NICs and then build the form |
|
# either complaining about insufficient NICs or a list of interfaces (single or bond, depending on |
|
# iface count), the IPs to assign and mapping MACs to ifaces. We'll also offer an option to |
|
# "blind-map" as we did in v2. |
|
get_network_details($anvil); |
|
my $required_interfaces_for_single = 1 + $anvil->data->{cgi}{ifn_count}{value}; |
|
my $required_interfaces_for_bonds = 2 * $required_interfaces_for_single; |
|
my $interface_count = keys %{$anvil->data->{interfaces}}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
required_interfaces_for_single => $required_interfaces_for_single, |
|
required_interfaces_for_bonds => $required_interfaces_for_bonds, |
|
interface_count => $interface_count, |
|
}}); |
|
|
|
my $interface_options = []; |
|
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{interfaces}}) |
|
{ |
|
my $this_mac = $anvil->data->{interfaces}{$interface}{mac}; |
|
push @{$interface_options}, $this_mac."#!#".$interface." (".$this_mac.")"; |
|
} |
|
|
|
my $problem = 0; |
|
my $interface_form = ""; |
|
my $cgi = ""; |
|
my $links = []; |
|
if ($interface_count >= $required_interfaces_for_bonds) |
|
{ |
|
### Show the bonded ifaces form. |
|
# BCN |
|
my $bcn_count = $anvil->data->{cgi}{bcn_count}{value} ? $anvil->data->{cgi}{bcn_count}{value} : 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bcn_count => $bcn_count }}); |
|
foreach my $bcn (1..$bcn_count) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bcn => $bcn }}); |
|
push @{$links}, "bcn_link".$bcn; |
|
my $this_ip_key = "bcn".$bcn."_ip"; |
|
my $this_subnet_mask_key = "bcn".$bcn."_subnet_mask"; |
|
my $this_iface1_key = "bcn".$bcn."_link1_mac_to_set"; |
|
my $this_iface2_key = "bcn".$bcn."_link2_mac_to_set"; |
|
$cgi .= $this_ip_key.",".$this_subnet_mask_key.",".$this_iface1_key.",".$this_iface2_key.","; |
|
my $this_ip = generate_ip($anvil, "bcn", $bcn, $anvil->data->{cgi}{sequence}{value}); |
|
my $this_ip_class = $anvil->data->{cgi}{$this_ip_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_subnet_mask_class = $anvil->data->{cgi}{$this_subnet_mask_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_iface1_class = $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_iface2_class = $anvil->data->{cgi}{$this_iface2_key}{alert} ? "input_alert" : "input_clear"; |
|
|
|
# Build the interface select boxes... |
|
my $this_iface1_form = $anvil->Template->select_form({ |
|
name => $this_iface1_key, |
|
options => $interface_options, |
|
blank => 1, |
|
'sort' => 0, |
|
selected => defined $anvil->data->{cgi}{$this_iface1_key}{value} ? $anvil->data->{cgi}{$this_iface1_key}{value} : "", |
|
class => $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
my $this_iface2_form = $anvil->Template->select_form({ |
|
name => $this_iface2_key, |
|
options => $interface_options, |
|
blank => 1, |
|
'sort' => 0, |
|
selected => defined $anvil->data->{cgi}{$this_iface2_key}{value} ? $anvil->data->{cgi}{$this_iface2_key}{value} : "", |
|
class => $anvil->data->{cgi}{$this_iface2_key}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
|
|
# Assemble the form |
|
$interface_form .= $anvil->Template->get({file => "config.html", name => "bonded_interface_form", variables => { |
|
field => $anvil->Words->string({key => "striker_0018", variables => { number => $bcn }}), |
|
description => "#!string!striker_0019!#", |
|
ip_key => $this_ip_key, |
|
ip_value => defined $anvil->data->{cgi}{$this_ip_key}{value} ? $anvil->data->{cgi}{$this_ip_key}{value} : "", |
|
ip_value_default => $this_ip, |
|
ip_class => $this_ip_class, |
|
subnet_mask_key => $this_subnet_mask_key, |
|
subnet_mask_value => defined $anvil->data->{cgi}{$this_subnet_mask_key}{value} ? $anvil->data->{cgi}{$this_subnet_mask_key}{value} : "", |
|
subnet_mask_value_default => $anvil->data->{defaults}{network}{bcn}{subnet_mask}, |
|
subnet_mask_class => $this_subnet_mask_class, |
|
iface1_select => $this_iface1_form, |
|
iface2_select => $this_iface2_form, |
|
}}); |
|
} |
|
|
|
# IFN |
|
my $ifn_count = $anvil->data->{cgi}{ifn_count}{value} ? $anvil->data->{cgi}{ifn_count}{value} : 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ifn_count => $ifn_count }}); |
|
foreach my $ifn (1..$ifn_count) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ifn => $ifn }}); |
|
push @{$links}, "ifn_link".$ifn; |
|
my $this_ip_key = "ifn".$ifn."_ip"; |
|
my $this_subnet_mask_key = "ifn".$ifn."_subnet_mask"; |
|
my $this_iface1_key = "ifn".$ifn."_link1_mac_to_set"; |
|
my $this_iface2_key = "ifn".$ifn."_link2_mac_to_set"; |
|
$cgi .= $this_ip_key.",".$this_subnet_mask_key.",".$this_iface1_key.",".$this_iface2_key.","; |
|
my $this_ip = generate_ip($anvil, "ifn", $ifn, $anvil->data->{cgi}{sequence}{value}); |
|
my $this_ip_class = $anvil->data->{cgi}{$this_ip_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_subnet_mask_class = $anvil->data->{cgi}{$this_subnet_mask_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_iface1_class = $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_iface2_class = $anvil->data->{cgi}{$this_iface2_key}{alert} ? "input_alert" : "input_clear"; |
|
|
|
# Build the interface select boxes... |
|
my $this_iface1_form = $anvil->Template->select_form({ |
|
name => $this_iface1_key, |
|
options => $interface_options, |
|
blank => 1, |
|
selected => defined $anvil->data->{cgi}{$this_iface1_key}{value} ? $anvil->data->{cgi}{$this_iface1_key}{value} : "", |
|
class => $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
my $this_iface2_form = $anvil->Template->select_form({ |
|
name => $this_iface2_key, |
|
options => $interface_options, |
|
blank => 1, |
|
selected => defined $anvil->data->{cgi}{$this_iface2_key}{value} ? $anvil->data->{cgi}{$this_iface2_key}{value} : "", |
|
class => $anvil->data->{cgi}{$this_iface2_key}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
|
|
# Assemble the form |
|
$interface_form .= $anvil->Template->get({file => "config.html", name => "bonded_interface_form", variables => { |
|
field => $anvil->Words->string({key => "striker_0022", variables => { number => $ifn }}), |
|
description => "#!string!striker_0023!#", |
|
ip_key => $this_ip_key, |
|
ip_value => defined $anvil->data->{cgi}{$this_ip_key}{value} ? $anvil->data->{cgi}{$this_ip_key}{value} : "", |
|
ip_value_default => $this_ip, |
|
ip_class => $this_ip_class, |
|
subnet_mask_key => $this_subnet_mask_key, |
|
subnet_mask_value => defined $anvil->data->{cgi}{$this_subnet_mask_key}{value} ? $anvil->data->{cgi}{$this_subnet_mask_key}{value} : "", |
|
subnet_mask_value_default => $anvil->data->{defaults}{network}{ifn}{subnet_mask}, |
|
subnet_mask_class => $this_subnet_mask_class, |
|
iface1_select => $this_iface1_form, |
|
iface2_select => $this_iface2_form, |
|
}}); |
|
} |
|
} |
|
else |
|
{ |
|
### Show the single iface per network form. |
|
# BCN |
|
my $bcn_count = $anvil->data->{cgi}{bcn_count}{value} ? $anvil->data->{cgi}{bcn_count}{value} : 1; |
|
foreach my $bcn (1..$bcn_count) |
|
{ |
|
push @{$links}, "bcn_link".$bcn; |
|
my $this_ip_key = "bcn".$bcn."_ip"; |
|
my $this_subnet_mask_key = "bcn".$bcn."_subnet_mask"; |
|
my $this_iface1_key = "bcn".$bcn."_link1_mac_to_set"; |
|
$cgi .= $this_ip_key.",".$this_subnet_mask_key.",".$this_iface1_key.","; |
|
my $this_ip = generate_ip($anvil, "bcn", $bcn, $anvil->data->{cgi}{sequence}{value}); |
|
my $this_ip_class = $anvil->data->{cgi}{$this_ip_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_subnet_mask_class = $anvil->data->{cgi}{$this_subnet_mask_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_iface1_class = $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear"; |
|
|
|
# Build the interface select boxes... |
|
my $this_iface1_form = $anvil->Template->select_form({ |
|
name => $this_iface1_key, |
|
options => $interface_options, |
|
blank => 1, |
|
selected => defined $anvil->data->{cgi}{$this_iface1_key}{value} ? $anvil->data->{cgi}{$this_iface1_key}{value} : "", |
|
class => $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
|
|
# Assemble the form |
|
$interface_form .= $anvil->Template->get({file => "config.html", name => "single_interface_form", variables => { |
|
field => $anvil->Words->string({key => "striker_0018", variables => { number => $bcn }}), |
|
description => "#!string!striker_0019!#", |
|
ip_key => $this_ip_key, |
|
ip_value => defined $anvil->data->{cgi}{$this_ip_key}{value} ? $anvil->data->{cgi}{$this_ip_key}{value} : "", |
|
ip_value_default => $this_ip, |
|
ip_class => $this_ip_class, |
|
subnet_mask_key => $this_subnet_mask_key, |
|
subnet_mask_value => defined $anvil->data->{cgi}{$this_subnet_mask_key}{value} ? $anvil->data->{cgi}{$this_subnet_mask_key}{value} : $anvil->data->{defaults}{network}{bcn}{subnet_mask}, |
|
subnet_mask_value_default => $anvil->data->{defaults}{network}{bcn}{subnet_mask}, |
|
subnet_mask_class => $this_subnet_mask_class, |
|
iface1_select => $this_iface1_form, |
|
}}); |
|
} |
|
|
|
# IFN |
|
my $ifn_count = $anvil->data->{cgi}{ifn_count}{value} ? $anvil->data->{cgi}{ifn_count}{value} : 1; |
|
foreach my $ifn (1..$ifn_count) |
|
{ |
|
push @{$links}, "ifn_link".$ifn; |
|
my $this_ip_key = "ifn".$ifn."_ip"; |
|
my $this_subnet_mask_key = "ifn".$ifn."_subnet_mask"; |
|
my $this_iface1_key = "ifn".$ifn."_link1_mac_to_set"; |
|
$cgi .= $this_ip_key.",".$this_subnet_mask_key.",".$this_iface1_key.","; |
|
my $this_ip = generate_ip($anvil, "ifn", $ifn, $anvil->data->{cgi}{sequence}{value}); |
|
my $this_ip_class = $anvil->data->{cgi}{$this_ip_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_subnet_mask_class = $anvil->data->{cgi}{$this_subnet_mask_key}{alert} ? "input_alert" : "input_clear"; |
|
my $this_iface1_class = $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear"; |
|
|
|
# Build the interface select boxes... |
|
my $this_iface1_form = $anvil->Template->select_form({ |
|
name => $this_iface1_key, |
|
options => $interface_options, |
|
blank => 1, |
|
selected => defined $anvil->data->{cgi}{$this_iface1_key}{value} ? $anvil->data->{cgi}{$this_iface1_key}{value} : "", |
|
class => $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
|
|
# Assemble the form |
|
$interface_form .= $anvil->Template->get({file => "config.html", name => "single_interface_form", variables => { |
|
field => $anvil->Words->string({key => "striker_0022", variables => { number => $ifn }}), |
|
description => "#!string!striker_0023!#", |
|
ip_key => $this_ip_key, |
|
ip_value => defined $anvil->data->{cgi}{$this_ip_key}{value} ? $anvil->data->{cgi}{$this_ip_key}{value} : "", |
|
ip_value_default => $this_ip, |
|
ip_class => $this_ip_class, |
|
subnet_mask_key => $this_subnet_mask_key, |
|
subnet_mask_value => defined $anvil->data->{cgi}{$this_subnet_mask_key}{value} ? $anvil->data->{cgi}{$this_subnet_mask_key}{value} : $anvil->data->{defaults}{network}{ifn}{subnet_mask}, |
|
subnet_mask_value_default => $anvil->data->{defaults}{network}{ifn}{subnet_mask}, |
|
subnet_mask_class => $this_subnet_mask_class, |
|
iface1_select => $this_iface1_form, |
|
}}); |
|
} |
|
} |
|
|
|
### TODO: Add a form for Gateway, DNS and which interface to use |
|
# Gateway |
|
my $gateway_class = $anvil->data->{cgi}{gateway}{alert} ? "input_alert" : "input_clear"; |
|
my $say_gateway = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "gateway", |
|
id => "gateway", |
|
field => "#!string!striker_0035!#", |
|
description => "#!string!striker_0036!#", |
|
value => defined $anvil->data->{cgi}{gateway}{value} ? $anvil->data->{cgi}{gateway}{value} : "", |
|
default_value => "", |
|
class => $gateway_class, |
|
extra => "", |
|
}}); |
|
|
|
# DNS |
|
my $dns_class = $anvil->data->{cgi}{dns}{alert} ? "input_alert" : "input_clear"; |
|
my $say_dns = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "dns", |
|
id => "dns", |
|
field => "#!string!striker_0037!#", |
|
description => "#!string!striker_0038!#", |
|
value => defined $anvil->data->{cgi}{dns}{value} ? $anvil->data->{cgi}{dns}{value} : "", |
|
default_value => $anvil->data->{defaults}{network}{dns}, |
|
class => $dns_class, |
|
extra => "", |
|
}}); |
|
|
|
# Which interface gets the route? |
|
my $default_dg_iface = defined $anvil->data->{cgi}{dg_iface}{value} ? $anvil->data->{cgi}{dg_iface}{value} : "ifn_link1"; |
|
my $dg_iface_select = $anvil->Template->select_form({ |
|
name => "dg_iface", |
|
options => $links, |
|
blank => 0, |
|
selected => $default_dg_iface, |
|
class => $anvil->data->{cgi}{dg_iface}{alert} ? "input_alert" : "input_clear", |
|
}); |
|
|
|
### NOTE: I'll likely want this for choosing which interface to use as the default gateway when 2+ |
|
### IFNs are used. |
|
# my $dg_iface_class = $anvil->data->{cgi}{dg_iface}{alert} ? "input_alert" : "input_clear"; |
|
# my $say_dg_iface = $anvil->Template->get({file => "main.html", name => "input_select_form", variables => { |
|
# field => "#!string!striker_0039!#", |
|
# description => "#!string!striker_0040!#", |
|
# 'select' => "", |
|
# }}); |
|
# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { say_dg_iface => $say_dg_iface }}); |
|
|
|
# Hostname |
|
my $say_default_host_name = $anvil->data->{cgi}{prefix}{value}."-striker0".$anvil->data->{cgi}{sequence}{value}.".".$anvil->data->{cgi}{domain}{value}; |
|
my $host_name_class = $anvil->data->{cgi}{host_name}{alert} ? "input_alert" : "input_clear"; |
|
my $say_host_name = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "host_name", |
|
id => "host_name", |
|
field => "#!string!striker_0016!#", |
|
description => "#!string!striker_0017!#", |
|
value => defined $anvil->data->{cgi}{host_name}{value} ? $anvil->data->{cgi}{host_name}{value} : $say_default_host_name, |
|
default_value => "", |
|
class => $host_name_class, |
|
extra => "", |
|
}}); |
|
|
|
# Admin user |
|
my $striker_user_class = $anvil->data->{cgi}{striker_user}{alert} ? "input_alert" : "input_clear"; |
|
my $say_striker_user = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "striker_user", |
|
id => "striker_user", |
|
field => "#!string!striker_0031!#", |
|
description => "#!string!striker_0032!#", |
|
value => defined $anvil->data->{cgi}{striker_user}{value} ? $anvil->data->{cgi}{striker_user}{value} : $anvil->data->{sys}{user}{name}, |
|
default_value => "", |
|
class => $striker_user_class, |
|
extra => "", |
|
}}); |
|
|
|
# Password |
|
my $striker_password_class = $anvil->data->{cgi}{striker_password}{alert} ? "input_alert" : "input_clear"; |
|
my $say_striker_password = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "striker_password", |
|
id => "striker_password", |
|
field => "#!string!striker_0033!#", |
|
description => "#!string!striker_0034!#", |
|
value => defined $anvil->data->{cgi}{striker_password}{value} ? $anvil->data->{cgi}{striker_password}{value} : "", |
|
default_value => "", |
|
class => $striker_password_class, |
|
extra => "", |
|
}}); |
|
|
|
# Get the table that shows the current interface states. |
|
my $interface_states = get_network_details_form($anvil); |
|
|
|
# Store the previous CGI variables and display the new fields. |
|
my $step2_body = $anvil->Template->get({file => "config.html", name => "config_step2", variables => { |
|
step1_welcome_title_id => "", |
|
step1_welcome_message_id => "", |
|
organization => $anvil->data->{cgi}{organization}{value}, |
|
prefix => $anvil->data->{cgi}{prefix}{value}, |
|
domain => $anvil->data->{cgi}{domain}{value}, |
|
sequence => $anvil->data->{cgi}{sequence}{value}, |
|
bcn_count => $anvil->data->{cgi}{bcn_count}{value}, |
|
ifn_count => $anvil->data->{cgi}{ifn_count}{value}, |
|
interface_form => $interface_form, |
|
interface_states => $interface_states, |
|
striker_user_form => $say_striker_user, |
|
striker_password_form => $say_striker_password, |
|
gateway_form => $say_gateway, |
|
dns_form => $say_dns, |
|
host_name_form => $say_host_name, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { step2_body => $step2_body }}); |
|
|
|
return($step2_body); |
|
} |
|
|
|
# This sanity-checks step 2 and returns '1' if there was a problem. |
|
sub sanity_check_step2 |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# This will flip if we run into a problem. |
|
my $sane = 1; |
|
|
|
# Do we have a host name, striker user and password? |
|
if (not $anvil->Validate->form_field({name => "host_name", type => "domain_name"})) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0012"}) }}); |
|
$anvil->data->{cgi}{host_name}{alert} = 1; |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }}); |
|
} |
|
else |
|
{ |
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::host_name::value", |
|
variable_value => $anvil->data->{cgi}{host_name}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0017", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# The user name |
|
if ((not defined $anvil->data->{cgi}{striker_user}{value}) or (not $anvil->data->{cgi}{striker_user}{value})) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0013"}) }}); |
|
$anvil->data->{cgi}{striker_user}{alert} = 1; |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::striker_user::alert" => $anvil->data->{cgi}{striker_user}{alert} }}); |
|
} |
|
else |
|
{ |
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::striker_user::value", |
|
variable_value => $anvil->data->{cgi}{striker_user}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0032", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# The password |
|
if ((not defined $anvil->data->{cgi}{striker_password}{value}) or (not $anvil->data->{cgi}{striker_password}{value}) or (length($anvil->data->{cgi}{striker_password}{value}) < 6)) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0014"}) }}); |
|
$anvil->data->{cgi}{striker_password}{alert} = 1; |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::striker_password::alert" => $anvil->data->{cgi}{striker_password}{alert} }}); |
|
} |
|
else |
|
{ |
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::striker_password::value", |
|
variable_value => $anvil->data->{cgi}{striker_password}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0034", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# DNS can be multiple entries, comma-separated. It can also be blank, if the user doesn't need Internet access. |
|
my $dns_ok = 1; |
|
if ((defined $anvil->data->{cgi}{dns}{value}) and ($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 => 3, list => { ip => $ip }}); |
|
if (not $anvil->Validate->is_ipv4({ip => $ip})) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0015"}) }}); |
|
$anvil->data->{cgi}{dns}{alert} = 1; |
|
$sane = 0; |
|
$dns_ok = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, dns_ok => $dns_ok, "cgi::dns::alert" => $anvil->data->{cgi}{dns}{alert} }}); |
|
} |
|
} |
|
} |
|
if ($dns_ok) |
|
{ |
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::dns::value", |
|
variable_value => $anvil->data->{cgi}{dns}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0038", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# Look for interfaces and sanity check them. |
|
my $networks = {}; |
|
foreach my $network ("bcn", "ifn") |
|
{ |
|
my $count_key = $network."_count"; |
|
my $network_count = $anvil->data->{cgi}{$count_key}{value} ? $anvil->data->{cgi}{$count_key}{value} : 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
network => $network, |
|
count_key => $count_key, |
|
network_count => $network_count, |
|
}}); |
|
foreach my $count (1..$network_count) |
|
{ |
|
my $this_network = $network.$count; |
|
my $this_ip_key = $this_network."_ip"; |
|
my $this_subnet_mask_key = $this_network."_subnet_mask"; |
|
my $this_iface1_key = $this_network."_link1_mac_to_set"; |
|
my $this_iface2_key = $this_network."_link2_mac_to_set"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
count => $count, |
|
this_ip_key => $this_ip_key, |
|
this_subnet_mask_key => $this_subnet_mask_key, |
|
this_iface1_key => $this_iface1_key, |
|
this_iface2_key => $this_iface2_key, |
|
"cgi::${this_ip_key}::value" => $anvil->data->{cgi}{$this_ip_key}{value}, |
|
"cgi::${this_subnet_mask_key}::value" => $anvil->data->{cgi}{$this_subnet_mask_key}{value}, |
|
"cgi::${this_iface1_key}::value" => $anvil->data->{cgi}{$this_iface1_key}{value}, |
|
"cgi::${this_iface2_key}::value" => $anvil->data->{cgi}{$this_iface2_key}{value}, |
|
}}); |
|
|
|
# This will be used to tell the user which interface has a problem, if one exists. |
|
my $network_key = $network =~ /^bcn/ ? "striker_0018" : "striker_0022"; |
|
my $say_network = $anvil->Words->string({key => $network_key, variables => { number => $count }}); |
|
|
|
# Is the IP sane? |
|
my $ip_ok = 1; |
|
if (not $anvil->Validate->form_field({name => $this_ip_key, type => "ipv4"})) |
|
{ |
|
# Nope |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0016", variables => { network => $say_network}}) }}); |
|
$anvil->data->{cgi}{$this_ip_key}{alert} = 1; |
|
$sane = 0; |
|
$ip_ok = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, ip_ok => $ip_ok }}); |
|
} |
|
else |
|
{ |
|
# Save the IP |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::${this_ip_key}::value", |
|
variable_value => $anvil->data->{cgi}{$this_ip_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0024", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# What about the subnet mask? |
|
if (not $anvil->Validate->form_field({name => $this_subnet_mask_key, type => "subnet_mask"})) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0016", variables => { network => $say_network }}) }}); |
|
$anvil->data->{cgi}{$this_subnet_mask_key}{alert} = 1; |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }}); |
|
} |
|
elsif ($ip_ok) |
|
{ |
|
# We'll use the dotted-decimal subnet_mask. If it already is, great. If not, convert it. |
|
my $say_subnet_mask = $anvil->data->{cgi}{$this_subnet_mask_key}{value} =~ /^\d{1,2}$/ ? $anvil->Convert->cide({cidr => $anvil->data->{cgi}{$this_subnet_mask_key}{value}}) : $anvil->data->{cgi}{$this_subnet_mask_key}{value}; |
|
my $full_ip = $anvil->data->{cgi}{$this_ip_key}{value}."/".$anvil->data->{cgi}{$this_subnet_mask_key}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_subnet_mask => $say_subnet_mask, full_ip => $full_ip }}); |
|
|
|
$networks->{$this_network} = $full_ip; |
|
|
|
# Save the subnet mask |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::${this_subnet_mask_key}::value", |
|
variable_value => $anvil->data->{cgi}{$this_subnet_mask_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0025", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# Interface 1 must be set |
|
if (not $anvil->Validate->form_field({name => $this_iface1_key, type => "mac"})) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0017", variables => { network => $say_network, 'link' => "1" }}) }}); |
|
$anvil->data->{cgi}{$this_iface1_key}{alert} = 1; |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }}); |
|
} |
|
else |
|
{ |
|
# Valid MAC. Has it been assigned elsewhere? |
|
my $mac_address = $anvil->data->{cgi}{$this_iface1_key}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { mac_address => $mac_address }}); |
|
if ((not exists $anvil->data->{network}{$mac_address}{set_as}) or (not $anvil->data->{network}{$mac_address}{set_as})) |
|
{ |
|
$anvil->data->{network}{$mac_address}{set_as} = $this_iface1_key; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "network::${mac_address}::set_as" => $anvil->data->{network}{$mac_address}{set_as} }}); |
|
|
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::${this_iface1_key}::value", |
|
variable_value => $anvil->data->{cgi}{$this_iface1_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0029", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
else |
|
{ |
|
# Conflict! Set the alert for this interface and the conflicting one. |
|
my $conflict_key = $anvil->data->{network}{$mac_address}{set_as}; |
|
$anvil->data->{cgi}{$conflict_key}{alert} = 1; |
|
$anvil->data->{cgi}{$this_iface1_key}{alert} = 1; |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0018"}) }}); |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { |
|
sane => $sane, |
|
"cgi::${conflict_key}::alert" => $anvil->data->{cgi}{$conflict_key}{alert}, |
|
"cgi::${this_iface1_key}::alert" => $anvil->data->{cgi}{$this_iface1_key}{alert}, |
|
}}); |
|
} |
|
} |
|
|
|
# Interface 2 doesn't have to be set. |
|
if ((defined $anvil->data->{cgi}{$this_iface2_key}{value}) && ($anvil->data->{cgi}{$this_iface2_key}{value})) |
|
{ |
|
if (not $anvil->Validate->form_field({name => $this_iface2_key, type => "mac"})) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0017", variables => { network => $say_network, 'link' => "2" }}) }}); |
|
$anvil->data->{cgi}{$this_iface2_key}{alert} = 1; |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }}); |
|
} |
|
else |
|
{ |
|
# Valid MAC. Has it been assigned elsewhere? |
|
my $mac_address = $anvil->data->{cgi}{$this_iface2_key}{value}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { mac_address => $mac_address }}); |
|
if ((not exists $anvil->data->{network}{$mac_address}{set_as}) or (not $anvil->data->{network}{$mac_address}{set_as})) |
|
{ |
|
$anvil->data->{network}{$mac_address}{set_as} = $this_iface2_key; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "network::${mac_address}::set_as" => $anvil->data->{network}{$mac_address}{set_as} }}); |
|
|
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::${this_iface2_key}::value", |
|
variable_value => $anvil->data->{cgi}{$this_iface2_key}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0030", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
else |
|
{ |
|
# Conflict! Set the alert for this interface and the conflicting one. |
|
my $conflict_key = $anvil->data->{network}{$mac_address}{set_as}; |
|
$anvil->data->{cgi}{$conflict_key}{alert} = 1; |
|
$anvil->data->{cgi}{$this_iface2_key}{alert} = 1; |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0018"}) }}); |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { |
|
sane => $sane, |
|
"cgi::${conflict_key}::alert" => $anvil->data->{cgi}{$conflict_key}{alert}, |
|
"cgi::${this_iface2_key}::alert" => $anvil->data->{cgi}{$this_iface2_key}{alert}, |
|
}}); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
# The gateway, this has to be after the interfaces so that we can match it to an interface (and error |
|
# if not) |
|
if (not $anvil->Validate->form_field({name => "gateway", type => "ipv4", empty_ok => 1})) |
|
{ |
|
$anvil->data->{cgi}{gateway}{alert} = 1; |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0019"}) }}); |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }}); |
|
} |
|
else |
|
{ |
|
# Convert the gateway strings to binary. |
|
my $gateway = defined $anvil->data->{cgi}{gateway}{value} ? $anvil->data->{cgi}{gateway}{value} : ""; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { gateway => $gateway }}); |
|
|
|
# If there is no gateway, that's OK, there just won't be any Internet access. |
|
my $gateway_interface = ""; |
|
if ($gateway) |
|
{ |
|
# Match this gateway to one of the interfaces. |
|
foreach my $this_network (sort {$a cmp $b} keys %{$networks}) |
|
{ |
|
my ($this_ip, $this_subnet_mask) = ($networks->{$this_network} =~ /^(.*?)\/(.*)$/); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"s1:this_network" => $this_network, |
|
"s2:networks->$this_network" => $networks->{$this_network}, |
|
"s3:this_ip" => $this_ip, |
|
"s4:this_subnet_mask" => $this_subnet_mask, |
|
}}); |
|
|
|
my $first = NetAddr::IP->new("$this_ip/$this_subnet_mask"); |
|
my $second = NetAddr::IP->new("$gateway/$this_subnet_mask"); |
|
|
|
if ($second->within($first)) |
|
{ |
|
$gateway_interface = $this_network; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { gateway_interface => $gateway_interface }}); |
|
} |
|
} |
|
if (not $gateway_interface) |
|
{ |
|
# Explain the problem |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0004"}) }}); |
|
$anvil->data->{cgi}{gateway}{alert} = 1; |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::gateway::alert" => $anvil->data->{cgi}{gateway}{alert} }}); |
|
} |
|
} |
|
|
|
# If no alert was raised, record the values. |
|
if (not $anvil->data->{cgi}{gateway}{alert}) |
|
{ |
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::gateway::value", |
|
variable_value => $anvil->data->{cgi}{gateway}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0036", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
|
|
# Record the gateway interface |
|
$anvil->Database->insert_or_update_variables({ |
|
variable_name => "form::config_step2::gateway_interface::value", |
|
variable_value => $gateway_interface, |
|
variable_default => "", |
|
variable_description => "", |
|
variable_section => "config_step2", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
} |
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { sane => $sane }}); |
|
return($sane); |
|
} |
|
|
|
# This sanity-checks step 1 and returns '1' if there was a problem. |
|
sub sanity_check_step1 |
|
{ |
|
my ($anvil) = @_; |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0131", variables => { function => "sanity_check_step1()" }}); |
|
|
|
# This will flip if we run into a problem. |
|
my $sane = 1; |
|
|
|
$anvil->data->{cgi}{organization}{value} = "" if not defined $anvil->data->{cgi}{organization}{value}; |
|
|
|
# Organization just needs *something* |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"cgi::organization::alert" => $anvil->data->{cgi}{organization}{alert}, |
|
|
|
}}); |
|
if (not $anvil->data->{cgi}{organization}{value}) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0020", variables => { field => "striker_0003" }}) }}); |
|
$anvil->data->{cgi}{organization}{alert} = 1; |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::organization::alert" => $anvil->data->{cgi}{organization}{alert} }}); |
|
} |
|
else |
|
{ |
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step1::organization::value", |
|
variable_value => $anvil->data->{cgi}{organization}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0004", |
|
variable_section => "config_step1", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# The prefix needs to be alphanumeric and be between 1 ~ 5 chatacters. |
|
if ((not $anvil->Validate->is_alphanumeric({string => $anvil->data->{cgi}{prefix}{value}})) or (length($anvil->data->{cgi}{prefix}{value}) > 5)) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0021"}) }}); |
|
$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} }}); |
|
} |
|
else |
|
{ |
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step1::prefix::value", |
|
variable_value => $anvil->data->{cgi}{prefix}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0006", |
|
variable_section => "config_step1", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# We can use Validate to check the domain. |
|
if (not $anvil->Validate->form_field({name => "domain", type => "domain_name"})) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0020", variables => { field => "striker_0007" }}) }}); |
|
$anvil->data->{cgi}{domain}{alert} = 1; |
|
$sane = 0; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }}); |
|
} |
|
else |
|
{ |
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step1::domain::value", |
|
variable_value => $anvil->data->{cgi}{domain}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0008", |
|
variable_section => "config_step1", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
# The sequence and IFN count need to be integers. |
|
if (not $anvil->Validate->is_positive_integer({number => $anvil->data->{cgi}{sequence}{value}})) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0022", variables => { field => "striker_0009" }}) }}); |
|
$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} }}); |
|
} |
|
else |
|
{ |
|
# Record the answer. |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step1::sequence::value", |
|
variable_value => $anvil->data->{cgi}{sequence}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0010", |
|
variable_section => "config_step1", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
if (not $anvil->Validate->is_positive_integer({number => $anvil->data->{cgi}{ifn_count}{value}})) |
|
{ |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0022", variables => { field => "striker_0011" }}) }}); |
|
$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} }}); |
|
} |
|
|
|
# Make sure we have enough interfaces. |
|
get_network_details($anvil); |
|
my $required_interfaces_for_single = 1 + $anvil->data->{cgi}{ifn_count}{value}; |
|
my $interface_count = keys %{$anvil->data->{interfaces}}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
required_interfaces_for_single => $required_interfaces_for_single, |
|
interface_count => $interface_count, |
|
}}); |
|
|
|
if ($interface_count < $required_interfaces_for_single) |
|
{ |
|
# Build the error message. |
|
my $say_message = $anvil->Words->string({key => "error_0001", variables => { |
|
interface_count => $interface_count, |
|
required_interfaces_for_single => $required_interfaces_for_single, |
|
}}); |
|
|
|
# Not enough interfaces found. |
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $say_message }}); |
|
$anvil->data->{cgi}{ifn_count}{alert} = 1; |
|
$sane = 0; |
|
} |
|
else |
|
{ |
|
# Sane, Record the answers. |
|
$anvil->Database->insert_or_update_variables({ |
|
debug => 3, |
|
variable_name => "form::config_step1::ifn_count::value", |
|
variable_value => $anvil->data->{cgi}{ifn_count}{value}, |
|
variable_default => "", |
|
variable_description => "striker_0012", |
|
variable_section => "config_step1", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
} |
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }}); |
|
return($sane); |
|
} |
|
|
|
# This is step 1 in asking the user how to configure Striker. |
|
sub config_step1 |
|
{ |
|
my ($anvil) = @_; |
|
|
|
if (not $anvil->data->{cgi}{'next'}{value}) |
|
{ |
|
# First load. See if we can read old data. |
|
my ($organization) = $anvil->Database->read_variable({ |
|
variable_name => "form::config_step1::organization::value", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
my ($prefix) = $anvil->Database->read_variable({ |
|
variable_name => "form::config_step1::prefix::value", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
my ($domain) = $anvil->Database->read_variable({ |
|
variable_name => "form::config_step1::domain::value", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
my ($sequence) = $anvil->Database->read_variable({ |
|
variable_name => "form::config_step1::sequence::value", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
my ($ifn_count) = $anvil->Database->read_variable({ |
|
variable_name => "form::config_step1::ifn_count::value", |
|
variable_source_uuid => $anvil->Get->host_uuid, |
|
variable_source_table => "hosts", |
|
}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
organization => $organization, |
|
prefix => $prefix, |
|
domain => $domain, |
|
sequence => $sequence, |
|
ifn_count => $ifn_count, |
|
}}); |
|
|
|
$anvil->data->{cgi}{organization}{value} = $organization ne "" ? $organization : ""; |
|
$anvil->data->{cgi}{prefix}{value} = $prefix ne "" ? $prefix : ""; |
|
$anvil->data->{cgi}{domain}{value} = $domain ne "" ? $domain : ""; |
|
$anvil->data->{cgi}{sequence}{value} = $sequence ne "" ? $sequence : ""; |
|
$anvil->data->{cgi}{ifn_count}{value} = $ifn_count ne "" ? $ifn_count : 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
'cgi::organization::value' => $anvil->data->{cgi}{organization}{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::ifn_count::value' => $anvil->data->{cgi}{ifn_count}{value}, |
|
}}); |
|
|
|
# If we don't have an organization name, prefix, domain name or sequence number, try to parse it from |
|
# the current static and pretty host_names. |
|
my ($traditional_host_name, $descriptive_host_name) = $anvil->System->host_name(); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
traditional_host_name => $traditional_host_name, |
|
descriptive_host_name => $descriptive_host_name, |
|
}}); |
|
if ($descriptive_host_name =~ /^(.*?) - Striker (\d+)/) |
|
{ |
|
my $organization = $1; |
|
my $sequence = $2; |
|
$sequence =~ s/^0+//; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
organization => $organization, |
|
sequence => $sequence, |
|
}}); |
|
|
|
if (($organization) && ($anvil->data->{cgi}{organization}{value} eq "")) |
|
{ |
|
$anvil->data->{cgi}{organization}{value} = $organization; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
'cgi::organization::value' => $anvil->data->{cgi}{organization}{value}, |
|
}}); |
|
} |
|
|
|
if (($sequence =~ /^\d+$/) && ($anvil->data->{cgi}{sequence}{value} eq "")) |
|
{ |
|
$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 ($traditional_host_name =~ /^(.*?)-striker\d+\.(.*)$/) |
|
{ |
|
my $prefix = $1; |
|
my $domain = $2; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
prefix => $prefix, |
|
domain => $domain, |
|
}}); |
|
|
|
if (($prefix) && ($anvil->data->{cgi}{prefix}{value} eq "")) |
|
{ |
|
$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 (($domain) && ($anvil->data->{cgi}{domain}{value} eq "")) |
|
{ |
|
$anvil->data->{cgi}{domain}{value} = $domain; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
'cgi::domain::value' => $anvil->data->{cgi}{domain}{value}, |
|
}}); |
|
} |
|
} |
|
|
|
# If I still don't have a sequence number, set '1'. |
|
if ($anvil->data->{cgi}{sequence}{value} eq "") |
|
{ |
|
$anvil->data->{cgi}{sequence}{value} = 1; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
'cgi::sequence::value' => $anvil->data->{cgi}{sequence}{value}, |
|
}}); |
|
} |
|
} |
|
|
|
my $organization_class = $anvil->data->{cgi}{organization}{alert} ? "input_alert" : "input_clear"; |
|
my $say_organization = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "organization", |
|
id => "organization", |
|
field => "#!string!striker_0003!#", |
|
description => "#!string!striker_0004!#", |
|
value => defined $anvil->data->{cgi}{organization}{value} ? $anvil->data->{cgi}{organization}{value} : "", |
|
default_value => "", |
|
class => $organization_class, |
|
extra => "", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_organization => $say_organization }}); |
|
my $prefix_class = $anvil->data->{cgi}{prefix}{alert} ? "input_alert" : "input_clear"; |
|
my $say_prefix = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "prefix", |
|
id => "prefix", |
|
field => "#!string!striker_0005!#", |
|
description => "#!string!striker_0006!#", |
|
value => defined $anvil->data->{cgi}{prefix}{value} ? $anvil->data->{cgi}{prefix}{value} : "", |
|
default_value => "", |
|
class => $prefix_class, |
|
extra => "maxlength=\"5\"", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_prefix => $say_prefix }}); |
|
my $domain_class = $anvil->data->{cgi}{domain}{alert} ? "input_alert" : "input_clear"; |
|
my $say_domain = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { |
|
name => "domain", |
|
id => "domain", |
|
field => "#!string!striker_0007!#", |
|
description => "#!string!striker_0008!#", |
|
value => defined $anvil->data->{cgi}{domain}{value} ? $anvil->data->{cgi}{domain}{value} : "", |
|
default_value => "", |
|
class => $domain_class, |
|
extra => "maxlength=\"255\"", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_domain => $say_domain }}); |
|
my $sequence_class = $anvil->data->{cgi}{sequence}{alert} ? "input_alert" : "input_clear"; |
|
my $say_sequence = $anvil->Template->get({file => "main.html", name => "input_number_form", variables => { |
|
name => "sequence", |
|
id => "sequence", |
|
field => "#!string!striker_0009!#", |
|
description => "#!string!striker_0010!#", |
|
value => defined $anvil->data->{cgi}{sequence}{value} ? $anvil->data->{cgi}{sequence}{value} : "", |
|
class => $sequence_class, |
|
extra => "min=\"1\" max=\"24\"", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_domain => $say_domain }}); |
|
my $ifn_count_class = $anvil->data->{cgi}{ifn_count}{alert} ? "input_alert" : "input_clear"; |
|
my $say_ifn_count = $anvil->Template->get({file => "main.html", name => "input_number_form", variables => { |
|
name => "ifn_count", |
|
id => "ifn_count", |
|
field => "#!string!striker_0011!#", |
|
description => "#!string!striker_0012!#", |
|
value => defined $anvil->data->{cgi}{ifn_count}{value} ? $anvil->data->{cgi}{ifn_count}{value} : "", |
|
class => $ifn_count_class, |
|
extra => "min=\"1\" max=\"24\"", |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_ifn_count => $say_ifn_count }}); |
|
|
|
my $step1_body = $anvil->Template->get({file => "config.html", name => "config_step1", variables => { |
|
step1_welcome_title_id => "", |
|
step1_welcome_message_id => "", |
|
organization_form => $say_organization, |
|
prefix_form => $say_prefix, |
|
domain_form => $say_domain, |
|
sequence_form => $say_sequence, |
|
ifn_count_form => $say_ifn_count, |
|
}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { step1_body => $step1_body }}); |
|
|
|
return($step1_body); |
|
} |
|
|
|
# This reads the network status XML file and loads the data into $anvil->data->{network}{{...}. |
|
sub get_network_details |
|
{ |
|
my ($anvil) = @_; |
|
|
|
### TODO: Daemonize this or solve selinux issues |
|
### Refresh the network.xml |
|
#$anvil->System->call({shell_call => $anvil->data->{path}{exe}{'anvil-update-states'}}); |
|
|
|
# Now read the network.xml |
|
my $file = $anvil->data->{path}{directories}{html}."/status/network.xml"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { file => $file }}); |
|
|
|
# Parse... |
|
my $xml = XML::Simple->new(); |
|
my $data = ""; |
|
my $network = ""; |
|
eval { $data = $xml->XMLin($file, KeyAttr => { interface => 'name', key => 'name', ip => 'address' }, ForceArray => [ 'interface', 'key' ] ) }; |
|
if ($@) |
|
{ |
|
chomp $@; |
|
my $error = "[ Error ] - The was a problem reading: [$file]. The error was:\n"; |
|
$error .= "===========================================================\n"; |
|
$error .= $@."\n"; |
|
$error .= "===========================================================\n"; |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", raw => $error}); |
|
} |
|
else |
|
{ |
|
foreach my $interface (sort {$a cmp $b} keys %{$data->{interface}}) |
|
{ |
|
$anvil->data->{interfaces}{$interface} = { |
|
bond => $data->{interface}{$interface}{bond}, |
|
bridge => $data->{interface}{$interface}{bridge}, |
|
duplex => $data->{interface}{$interface}{duplex}, |
|
'link' => $data->{interface}{$interface}{'link'}, |
|
mac => $data->{interface}{$interface}{mac}, |
|
media => $data->{interface}{$interface}{media}, |
|
mtu => $data->{interface}{$interface}{mtu}, |
|
order => $data->{interface}{$interface}{order}, |
|
speed => $data->{interface}{$interface}{speed}, |
|
'state' => $data->{interface}{$interface}{'state'}, |
|
}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"interfaces::${interface}::bond" => $anvil->data->{interfaces}{$interface}{bond}, |
|
"interfaces::${interface}::bridge" => $anvil->data->{interfaces}{$interface}{bridge}, |
|
"interfaces::${interface}::duplex" => $anvil->data->{interfaces}{$interface}{duplex}, |
|
"interfaces::${interface}::link" => $anvil->data->{interfaces}{$interface}{'link'}, |
|
"interfaces::${interface}::mac" => $anvil->data->{interfaces}{$interface}{mac}, |
|
"interfaces::${interface}::media" => $anvil->data->{interfaces}{$interface}{media}, |
|
"interfaces::${interface}::mtu" => $anvil->data->{interfaces}{$interface}{mtu}, |
|
"interfaces::${interface}::order" => $anvil->data->{interfaces}{$interface}{order}, |
|
"interfaces::${interface}::speed" => $anvil->data->{interfaces}{$interface}{speed}, |
|
"interfaces::${interface}::state" => $anvil->data->{interfaces}{$interface}{'state'}, |
|
}}); |
|
} |
|
### TODO: Sort out how to read the XML using the proper KeyAttr to avoid this mess... |
|
# If there is only one IP, the details will be stored directly under the 'ip' key. If two or |
|
# more exist, each ip address will be the key after 'ip'. |
|
if (exists $data->{ip}{address}) |
|
{ |
|
# Only one entry. Fix the hash. |
|
my $address = $data->{ip}{address}; |
|
my $on = $data->{ip}{on}; |
|
my $subnet_mask = $data->{ip}{subnet_mask}; |
|
my $gateway = $data->{ip}{gateway}; |
|
my $default_gateway = $data->{ip}{default_gateway}; |
|
my $dns = $data->{ip}{dns}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
address => $address, |
|
on => $on, |
|
subnet_mask => $subnet_mask, |
|
gateway => $gateway, |
|
default_gateway => $default_gateway, |
|
dns => $dns, |
|
}}); |
|
|
|
$anvil->data->{ip}{$address} = { |
|
on => $on, |
|
subnet_mask => $subnet_mask, |
|
gateway => $gateway, |
|
default_gateway => $default_gateway, |
|
dns => $dns, |
|
}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"ip::${address}::on" => $anvil->data->{ip}{$address}{on}, |
|
"ip::${address}::subnet_mask" => $anvil->data->{ip}{$address}{subnet_mask}, |
|
"ip::${address}::gateway" => $anvil->data->{ip}{$address}{gateway}, |
|
"ip::${address}::default_gateway" => $anvil->data->{ip}{$address}{default_gateway}, |
|
"ip::${address}::dns" => $anvil->data->{ip}{$address}{dns}, |
|
}}); |
|
} |
|
else |
|
{ |
|
foreach my $address (sort {$a cmp $b} keys %{$data->{ip}}) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { address => $address }}); |
|
$anvil->data->{ip}{$address} = { |
|
on => $data->{ip}{$address}{on}, |
|
subnet_mask => $data->{ip}{$address}{subnet_mask}, |
|
gateway => $data->{ip}{$address}{gateway}, |
|
default_gateway => $data->{ip}{$address}{default_gateway}, |
|
dns => $data->{ip}{$address}{dns}, |
|
}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"ip::${address}::on" => $anvil->data->{ip}{$address}{on}, |
|
"ip::${address}::subnet_mask" => $anvil->data->{ip}{$address}{subnet_mask}, |
|
"ip::${address}::gateway" => $anvil->data->{ip}{$address}{gateway}, |
|
"ip::${address}::default_gateway" => $anvil->data->{ip}{$address}{default_gateway}, |
|
"ip::${address}::dns" => $anvil->data->{ip}{$address}{dns}, |
|
}}); |
|
} |
|
} |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
sub get_network_details_form |
|
{ |
|
my ($anvil) = @_; |
|
|
|
my $file = $anvil->data->{path}{directories}{html}."/status/network.xml"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { file => $file }}); |
|
my $xml = XML::Simple->new(); |
|
my $data = ""; |
|
my $network = ""; |
|
eval { $data = $xml->XMLin($file, KeyAttr => { interface => 'name', key => 'name' }, ForceArray => [ 'interface', 'key' ]) }; |
|
if ($@) |
|
{ |
|
chomp $@; |
|
my $error = "[ Error ] - The was a problem reading: [$file]. The error was:\n"; |
|
$error .= "===========================================================\n"; |
|
$error .= $@."\n"; |
|
$error .= "===========================================================\n"; |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", raw => $error}); |
|
} |
|
else |
|
{ |
|
my $interface_list = ""; |
|
$network = $anvil->Template->get({file => "config.html", name => "network_header"}); |
|
foreach my $interface (sort {$a cmp $b} keys %{$data->{interface}}) |
|
{ |
|
$interface_list .= "$interface,"; |
|
$network .= $anvil->Template->get({file => "config.html", name => "network_entry", variables => { |
|
mac => "", |
|
mac_id => $interface."_mac", |
|
name => $interface, |
|
name_id => $interface."_name", |
|
speed => "", |
|
speed_id => $interface."_speed", |
|
'link' => "", |
|
link_id => $interface."_link", |
|
order => "", |
|
order_id => $interface."_order", |
|
}}); |
|
} |
|
$interface_list =~ s/,$//; |
|
$network .= $anvil->Template->get({file => "config.html", name => "network_footer", variables => { interface_list => $interface_list }}); |
|
} |
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network => $network }}); |
|
return($network); |
|
} |
|
|
|
=cut |
|
Network planning; |
|
|
|
10.x.y.z / 255.255.0.0 |
|
10.x.y.z / 255.255.0.0 |
|
|
|
x = Network; |
|
- BCN = 200 + network |
|
ie: BCN1 = 10.201.y.z |
|
BCN2 = 10.202.y.z |
|
- SN = 100 + network |
|
ie: SN1 = 10.101.y.z |
|
SN2 = 10.102.y.z |
|
|
|
y = Device Type. |
|
Foudation Pack; |
|
1. Switches |
|
2. PDUs |
|
3. UPSes |
|
4. Switches |
|
5. Strikers |
|
6. Striker IPMI (BCN only) |
|
|
|
Anvil! systems; |
|
1st - 10 = Node IP |
|
11 = Node IPMI |
|
2nd - 12 = Node IP |
|
13 = Node IPMI |
|
3rd - 14 = Node IP |
|
15 = Node IPMI |
|
N... |
|
|
|
z = Device Sequence |
|
- Foundation pack devices are simple sequence |
|
- Anvils; .1 = node 1, .2 = node 2, .3 = DR host |
|
=cut |
|
|
|
# This is a rudimentary function for generating default Striker IPs. |
|
sub generate_ip |
|
{ |
|
my ($anvil, $network, $network_sequence, $device_sequence) = @_; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
network => $network, |
|
network_sequence => $network_sequence, |
|
device_sequence => $device_sequence, |
|
}}); |
|
|
|
# An empty string is returned if we can't make a sane guess at what should be set. |
|
my $ip = ""; |
|
|
|
# The subnet mask's second octet will be '+X' where 'X' is the sequence. |
|
my $default_ip = $anvil->data->{defaults}{network}{$network}{network}; |
|
my $default_subnet_mask = $anvil->data->{defaults}{network}{$network}{subnet_mask}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
default_ip => $default_ip, |
|
default_subnet_mask => $default_subnet_mask, |
|
}}); |
|
|
|
if (($anvil->Validate->is_ipv4({ip => $default_ip})) && ($anvil->Validate->is_ipv4({ip => $default_subnet_mask}))) |
|
{ |
|
# Valid values. |
|
my ($ip_octet1, $ip_octet2, $ip_octet3, $ip_octet4) = (split/\./, $default_ip); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
ip_octet1 => $ip_octet1, |
|
ip_octet2 => $ip_octet2, |
|
ip_octet3 => $ip_octet3, |
|
ip_octet4 => $ip_octet4, |
|
}}); |
|
|
|
if ($default_subnet_mask eq "255.255.0.0") |
|
{ |
|
# We can work with this. |
|
if ($network ne "ifn") |
|
{ |
|
$ip_octet2 += $network_sequence; |
|
} |
|
$ip_octet3 = $anvil->data->{defaults}{network}{$network}{striker_octet3}; |
|
$ip_octet4 = $device_sequence; |
|
$ip = $ip_octet1.".".$ip_octet2.".".$ip_octet3.".".$ip_octet4; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
|
"s1:ip_octet2" => $ip_octet2, |
|
"s2:ip_octet3" => $ip_octet3, |
|
"s3:ip_octet4" => $ip_octet4, |
|
"s4:ip" => $ip, |
|
}}); |
|
} |
|
} |
|
else |
|
{ |
|
# Something wrong with our defaults. |
|
$ip = "#!error!#"; |
|
} |
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { ip => $ip }}); |
|
return($ip); |
|
}
|
|
|