7694847160
* Fixed some logging in Get->cgi() and generally cleaned up logging levels. * Got striker to the point where the job to reconfigure the network is saved in the database and the dashboard goes offline until it is done. * Created the start of the new anvil-configure-network tool. Signed-off-by: Digimer <digimer@alteeve.ca>
1533 lines
64 KiB
Perl
Executable File
1533 lines
64 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
#
|
|
# Exit codes;
|
|
# 0 == OK
|
|
# 1 == Host UUID not available yet.
|
|
#
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Anvil::Tools;
|
|
use Data::Dumper;
|
|
use NetAddr::IP;
|
|
|
|
# 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();
|
|
|
|
# Print the html headers, with a new line to break the header from the body.
|
|
print $anvil->Template->get({file => "shared.html", name => "http_headers"})."\n";
|
|
|
|
# Set the log level to 2. Setting 3 slows he program down a LOT.
|
|
$anvil->Log->level({set => 2});
|
|
|
|
# Read the config and then connect to the database.
|
|
$anvil->Storage->read_config({file => "/etc/anvil/anvil.conf"});
|
|
|
|
# Make sure I can read the host UUID.
|
|
if (not $anvil->Get->host_uuid)
|
|
{
|
|
# Too early, exit.
|
|
print $anvil->Words->string({key => "striker_error_0002"});
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
my $connections = $anvil->Database->connect({
|
|
sql_file => $anvil->data->{sys}{database}{schema},
|
|
test_table => "network_interfaces",
|
|
});
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0132", variables => { connections => $connections }});
|
|
if (not $connections)
|
|
{
|
|
# No databases, exit.
|
|
print $anvil->Words->string({key => "striker_error_0003"});
|
|
$anvil->nice_exit({exit_code => 2});
|
|
}
|
|
|
|
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete.
|
|
$| = 1;
|
|
|
|
### Setup some variables.
|
|
$anvil->data->{form}{error_massage} = " ";
|
|
## Network stuff... The second octet auto-increments to handle N-number of netowrks. As such, we need to use
|
|
## a wider spread between the BCNs, SNs and IFNs than we had in v2.
|
|
# BCN starts at 10.(0+n)/16
|
|
$anvil->data->{'default'}{bcn}{subnet} = "10.0.0.0";
|
|
$anvil->data->{'default'}{bcn}{netmask} = "255.255.0.0";
|
|
$anvil->data->{'default'}{bcn}{pdu_octet3} = "1";
|
|
$anvil->data->{'default'}{bcn}{ups_octet3} = "2";
|
|
$anvil->data->{'default'}{bcn}{switch_octet3} = "3";
|
|
$anvil->data->{'default'}{bcn}{striker_octet3} = "4";
|
|
# SN starts at 10.(40+n)/16
|
|
$anvil->data->{'default'}{sn}{subnet} = "10.40.0.0";
|
|
$anvil->data->{'default'}{sn}{netmask} = "255.255.0.0";
|
|
# IFN starts at 10.(80+)/16
|
|
$anvil->data->{'default'}{ifn}{subnet} = "10.80.0.0";
|
|
$anvil->data->{'default'}{ifn}{netmask} = "255.255.0.0";
|
|
|
|
# Read in any CGI variables, if needed.
|
|
$anvil->Get->cgi();
|
|
|
|
$anvil->data->{skin}{url} = $anvil->data->{path}{urls}{skins}."/".$anvil->Template->skin;
|
|
my $header = $anvil->Template->get({file => "main.html", name => "header", variables => { language => $anvil->Words->language }});
|
|
my $body = "";
|
|
|
|
# If any jobs are pending/running, show the "unavailable" option.
|
|
my $available = check_availability($anvil);
|
|
if (not $available)
|
|
{
|
|
# Set the body to 'say::maintenance'.
|
|
$body = $anvil->data->{say}{maintenance};
|
|
}
|
|
else
|
|
{
|
|
# This will be true when the dashboard is unconfigured.
|
|
if (not $anvil->data->{cgi}{step}{value})
|
|
{
|
|
$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.
|
|
$body = config_step2($anvil);
|
|
}
|
|
else
|
|
{
|
|
# No good
|
|
$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 => 2, list => { sane => $sane }});
|
|
if ($sane)
|
|
{
|
|
# Step 2 was sane, show step 3.
|
|
$body = config_step3($anvil);
|
|
}
|
|
else
|
|
{
|
|
# No good
|
|
$body = config_step2($anvil);
|
|
}
|
|
}
|
|
elsif ($anvil->data->{cgi}{step}{value} eq "step3")
|
|
{
|
|
# User has confirmed, update the system!
|
|
$body = save_job($anvil);
|
|
}
|
|
else
|
|
{
|
|
$body = get_network_details_form($anvil);
|
|
}
|
|
}
|
|
my $buttons = $anvil->Template->get({file => "main.html", name => "button_bar"});
|
|
my $footer = $anvil->Template->get({file => "main.html", name => "footer"});
|
|
|
|
# Display the page.
|
|
my $template = $anvil->Template->get({file => "main.html", name => "master", variables => {
|
|
header => $header,
|
|
skin_url => $anvil->data->{path}{urls}{skins}."/".$anvil->Template->skin,
|
|
left_top_bar => " ",
|
|
center_top_bar => $anvil->data->{form}{error_massage},
|
|
right_top_bar => $buttons,
|
|
center_body => $body,
|
|
left_bottom_bar => " ",
|
|
center_bottom_bar => " ",
|
|
right_bottom_bar => " ",
|
|
footer => $footer,
|
|
}});
|
|
|
|
print $template;
|
|
|
|
$anvil->nice_exit({exit_code => 0});
|
|
|
|
|
|
#############################################################################################################
|
|
# Functions #
|
|
#############################################################################################################
|
|
|
|
# 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;
|
|
my $query = "SELECT count(*) FROM jobs WHERE job_name = 'configure::network' AND job_progress != 100 AND job_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid).";";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
|
|
my $count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'say::maintenance' => $anvil->data->{say}{maintenance} }});
|
|
if ($count)
|
|
{
|
|
# We're waiting for the network configuration
|
|
$available = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { available => $available }});
|
|
|
|
$anvil->data->{say}{maintenance} = $anvil->Template->get({file => "main.html", name => "striker-offline", variables => {
|
|
title_id => "",
|
|
message_id => "",
|
|
title => "#!string!striker_0046!#",
|
|
description => "#!string!striker_0047!#",
|
|
}});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'say::maintenance' => $anvil->data->{say}{maintenance} }});
|
|
}
|
|
|
|
return($available);
|
|
}
|
|
|
|
# This requests the job to reconfigure the network be run
|
|
sub save_job
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Record the job!
|
|
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
|
|
debug => 2,
|
|
file => $THIS_FILE,
|
|
line => __LINE__,
|
|
job_command => "anvil-configure-network",
|
|
job_data => "form::config_step2",
|
|
job_name => "configure::network",
|
|
job_title => "job_0001",
|
|
job_description => "job_0002",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
|
|
|
|
# TODO: Check that a job_uuid was returned and warn of a problem if not.
|
|
my $say_title = "#!string!striker_0044!#";
|
|
my $say_desciption = "#!string!striker_0045!#";
|
|
|
|
# We don't need to store anything as hidden variables, we'll read it back from the database later.
|
|
my $job_recorded_body = $anvil->Template->get({file => "main.html", name => "network_job_recorded", variables => {
|
|
title_id => "",
|
|
message_id => "",
|
|
title => $say_title,
|
|
description => $say_desciption,
|
|
}});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { job_recorded_body => $job_recorded_body }});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
|
|
return($job_recorded_body);
|
|
}
|
|
|
|
# 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->data->{sys}{use_db_fh}->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 = defined $row->[1] ? $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->System->get_ips;
|
|
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 ot 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_key = $this_net."_subnet";
|
|
my $iface1_key = $this_net."_iface1_mac";
|
|
my $iface2_key = $this_net."_iface2_mac";
|
|
my $ip = $anvil->data->{cgi}{$ip_key}{value};
|
|
my $subnet = $anvil->data->{cgi}{$subnet_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" => $subnet,
|
|
"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;
|
|
if (($gateway) && ($anvil->data->{cgi}{gateway}{value}))
|
|
{
|
|
$template .= "_with_gateway";
|
|
$anvil->data->{cgi}{dns}{value} = "--" if not $anvil->data->{cgi}{dns}{value};
|
|
}
|
|
$networks .= $anvil->Template->get({file => "main.html", name => $template, variables => {
|
|
column => $anvil->Words->string({key => $column, variables => { number => $link_number }}),
|
|
ip_address => $say_ip,
|
|
ip => $ip,
|
|
subnet => $subnet,
|
|
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 }});
|
|
}
|
|
}
|
|
|
|
# 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 => "striker_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 => "main.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},
|
|
domain => $anvil->data->{cgi}{domain}{value},
|
|
striker_user => $anvil->data->{cgi}{striker_user}{value},
|
|
striker_password => $anvil->data->{cgi}{striker_password}{value},
|
|
networks => $networks,
|
|
cgi_list => $cgi."step",
|
|
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->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)."
|
|
ORDER BY
|
|
variable_name ASC;";
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, 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 => 3, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $variable_name = $row->[0];
|
|
my $variable_value = defined $row->[1] ? $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 => 3, 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."#!#".$this_mac." (".$interface.")";
|
|
}
|
|
|
|
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;
|
|
foreach my $bcn (1..$bcn_count)
|
|
{
|
|
push @{$links}, "bcn_link".$bcn;
|
|
my $this_ip_key = "bcn".$bcn."_ip";
|
|
my $this_subnet_key = "bcn".$bcn."_subnet";
|
|
my $this_iface1_key = "bcn".$bcn."_iface1_mac";
|
|
my $this_iface2_key = "bcn".$bcn."_iface2_mac";
|
|
$cgi .= $this_ip_key.",".$this_subnet_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_class = $anvil->data->{cgi}{$this_subnet_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 => "main.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} : $this_ip,
|
|
ip_class => $this_ip_class,
|
|
subnet_key => $this_subnet_key,
|
|
subnet_value => defined $anvil->data->{cgi}{$this_subnet_key}{value} ? $anvil->data->{cgi}{$this_subnet_key}{value} : $anvil->data->{'default'}{bcn}{netmask},
|
|
subnet_class => $this_subnet_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;
|
|
foreach my $ifn (1..$ifn_count)
|
|
{
|
|
push @{$links}, "ifn_link".$ifn;
|
|
my $this_ip_key = "ifn".$ifn."_ip";
|
|
my $this_subnet_key = "ifn".$ifn."_subnet";
|
|
my $this_iface1_key = "ifn".$ifn."_iface1_mac";
|
|
my $this_iface2_key = "ifn".$ifn."_iface2_mac";
|
|
$cgi .= $this_ip_key.",".$this_subnet_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_class = $anvil->data->{cgi}{$this_subnet_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 => "main.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} : $this_ip,
|
|
ip_class => $this_ip_class,
|
|
subnet_key => $this_subnet_key,
|
|
subnet_value => defined $anvil->data->{cgi}{$this_subnet_key}{value} ? $anvil->data->{cgi}{$this_subnet_key}{value} : $anvil->data->{'default'}{ifn}{netmask},
|
|
subnet_class => $this_subnet_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_key = "bcn".$bcn."_subnet";
|
|
my $this_iface1_key = "bcn".$bcn."_iface1_mac";
|
|
$cgi .= $this_ip_key.",".$this_subnet_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_class = $anvil->data->{cgi}{$this_subnet_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 => "main.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} : $this_ip,
|
|
ip_class => $this_ip_class,
|
|
subnet_key => $this_subnet_key,
|
|
subnet_value => defined $anvil->data->{cgi}{$this_subnet_key}{value} ? $anvil->data->{cgi}{$this_subnet_key}{value} : $anvil->data->{'default'}{bcn}{netmask},
|
|
subnet_class => $this_subnet_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_key = "ifn".$ifn."_subnet";
|
|
my $this_iface1_key = "ifn".$ifn."_iface1_mac";
|
|
$cgi .= $this_ip_key.",".$this_subnet_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_class = $anvil->data->{cgi}{$this_subnet_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 => "main.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} : $this_ip,
|
|
ip_class => $this_ip_class,
|
|
subnet_key => $this_subnet_key,
|
|
subnet_value => defined $anvil->data->{cgi}{$this_subnet_key}{value} ? $anvil->data->{cgi}{$this_subnet_key}{value} : $anvil->data->{'default'}{ifn}{netmask},
|
|
subnet_class => $this_subnet_class,
|
|
iface1_select => $this_iface1_form,
|
|
}});
|
|
}
|
|
}
|
|
|
|
### TODO: Add a form for Gateway, DNS and which interface to use
|
|
# Gateway
|
|
my $say_default_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} : $say_default_gateway,
|
|
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} : "8.8.8.8, 8.8.4.4",
|
|
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",
|
|
});
|
|
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' => "",
|
|
}});
|
|
|
|
# Hostname
|
|
my $say_default_hostname = $anvil->data->{cgi}{prefix}{value}."-striker0".$anvil->data->{cgi}{sequence}{value}.".".$anvil->data->{cgi}{domain}{value};
|
|
my $hostname_class = $anvil->data->{cgi}{hostname}{alert} ? "input_alert" : "input_clear";
|
|
my $say_hostname = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => {
|
|
name => "hostname",
|
|
id => "hostname",
|
|
field => "#!string!striker_0016!#",
|
|
description => "#!string!striker_0017!#",
|
|
value => defined $anvil->data->{cgi}{hostname}{value} ? $anvil->data->{cgi}{hostname}{value} : $say_default_hostname,
|
|
class => $hostname_class,
|
|
extra => "",
|
|
}});
|
|
|
|
# Admin user
|
|
my $say_default_striker_user = "striker";
|
|
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} : $say_default_striker_user,
|
|
class => $striker_user_class,
|
|
extra => "",
|
|
}});
|
|
|
|
# Password
|
|
my $say_default_striker_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} : $say_default_striker_password,
|
|
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 => "main.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,
|
|
hostname_form => $say_hostname,
|
|
cgi_list => $cgi."organization,prefix,domain,sequence,bcn_count,ifn_count,gateway,hostname,dns,striker_user,striker_password",
|
|
}});
|
|
$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 => "hostname", type => "domain_name"}))
|
|
{
|
|
$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::hostname::value",
|
|
variable_value => $anvil->data->{cgi}{hostname}{value},
|
|
variable_default => "",
|
|
variable_description => "striker_0017",
|
|
variable_section => "config_step2",
|
|
variable_source_uuid => $anvil->Get->host_uuid,
|
|
variable_source_table => "hosts",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
# The user name
|
|
if ((not defined $anvil->data->{cgi}{striker_user}{value}) or (not $anvil->data->{cgi}{striker_user}{value}))
|
|
{
|
|
$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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
# 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->{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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
# 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->{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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
# 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_key = $this_network."_subnet";
|
|
my $this_iface1_key = $this_network."_iface1_mac";
|
|
my $this_iface2_key = $this_network."_iface2_mac";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
|
count => $count,
|
|
this_ip_key => $this_ip_key,
|
|
this_subnet_key => $this_subnet_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_key}::value" => $anvil->data->{cgi}{$this_subnet_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},
|
|
}});
|
|
|
|
# Is the IP sane?
|
|
my $ip_ok = 1;
|
|
if (not $anvil->Validate->form_field({name => $this_ip_key, type => "ipv4"}))
|
|
{
|
|
# Nope
|
|
$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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
# What about the subnet?
|
|
if (not $anvil->Validate->form_field({name => $this_subnet_key, type => "subnet"}))
|
|
{
|
|
$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. If it already is, great. If not, convert it.
|
|
my $say_subnet = $anvil->data->{cgi}{$this_subnet_key}{value} =~ /^\d{1,2}$/ ? $anvil->Convert->cide({cidr => $anvil->data->{cgi}{$this_subnet_key}{value}}) : $anvil->data->{cgi}{$this_subnet_key}{value};
|
|
my $full_ip = $anvil->data->{cgi}{$this_ip_key}{value}."/".$anvil->data->{cgi}{$this_subnet_key}{value};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_subnet => $say_subnet, full_ip => $full_ip }});
|
|
|
|
$networks->{$this_network} = $full_ip;
|
|
|
|
# Save the subnet
|
|
$anvil->Database->insert_or_update_variables({
|
|
variable_name => "form::config_step2::${this_subnet_key}::value",
|
|
variable_value => $anvil->data->{cgi}{$this_subnet_key}{value},
|
|
variable_default => "",
|
|
variable_description => "striker_0025",
|
|
variable_section => "config_step2",
|
|
variable_source_uuid => $anvil->Get->host_uuid,
|
|
variable_source_table => "hosts",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
# Interface 1 must be set
|
|
if (not $anvil->Validate->form_field({name => $this_iface1_key, type => "mac"}))
|
|
{
|
|
$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 = $anvil->data->{cgi}{$this_iface1_key}{value};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { mac => $mac }});
|
|
if ((not exists $anvil->data->{network}{$mac}{set_as}) or (not $anvil->data->{network}{$mac}{set_as}))
|
|
{
|
|
$anvil->data->{network}{$mac}{set_as} = $this_iface1_key;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "network::${mac}::set_as" => $anvil->data->{network}{$mac}{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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
else
|
|
{
|
|
# Conflict! Set the alert for this interface and the conflicting one.
|
|
my $conflict_key = $anvil->data->{network}{$mac}{set_as};
|
|
$anvil->data->{cgi}{$conflict_key}{alert} = 1;
|
|
$anvil->data->{cgi}{$this_iface1_key}{alert} = 1;
|
|
$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"}))
|
|
{
|
|
$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 = $anvil->data->{cgi}{$this_iface2_key}{value};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { mac => $mac }});
|
|
if ((not exists $anvil->data->{network}{$mac}{set_as}) or (not $anvil->data->{network}{$mac}{set_as}))
|
|
{
|
|
$anvil->data->{network}{$mac}{set_as} = $this_iface2_key;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "network::${mac}::set_as" => $anvil->data->{network}{$mac}{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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
else
|
|
{
|
|
# Conflict! Set the alert for this interface and the conflicting one.
|
|
my $conflict_key = $anvil->data->{network}{$mac}{set_as};
|
|
$anvil->data->{cgi}{$conflict_key}{alert} = 1;
|
|
$anvil->data->{cgi}{$this_iface2_key}{alert} = 1;
|
|
$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}))
|
|
{
|
|
$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) = ($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" => $this_subnet,
|
|
}});
|
|
|
|
my $first = NetAddr::IP->new("$this_ip/$this_subnet");
|
|
my $second = NetAddr::IP->new("$gateway/$this_subnet");
|
|
|
|
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)
|
|
{
|
|
$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} }});
|
|
|
|
# Explain the problem
|
|
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_error_0004"}) }});
|
|
}
|
|
}
|
|
|
|
# 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",
|
|
update_value_only => 1,
|
|
});
|
|
|
|
# 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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
}
|
|
|
|
$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 => 3, key => "log_0131", variables => { function => "sanity_check_step1()" }});
|
|
|
|
# This will flip if we run into a problem.
|
|
my $sane = 1;
|
|
|
|
# Organization just needs *something*
|
|
if ((not defined $anvil->data->{cgi}{organization}{value}) or (not $anvil->data->{cgi}{organization}{value}))
|
|
{
|
|
$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({
|
|
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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
# 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->{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({
|
|
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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
# We can use Validate to check the domain.
|
|
if (not $anvil->Validate->form_field({name => "domain", type => "domain_name"}))
|
|
{
|
|
$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_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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
# The sequence and IFN count need to be integers.
|
|
if (not $anvil->Validate->is_positive_integer({number => $anvil->data->{cgi}{sequence}{value}}))
|
|
{
|
|
$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({
|
|
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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
if (not $anvil->Validate->is_positive_integer({number => $anvil->data->{cgi}{ifn_count}{value}}))
|
|
{
|
|
$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 => "striker_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 }});
|
|
|
|
# We're not sane
|
|
$anvil->data->{cgi}{ifn_count}{alert} = 1;
|
|
$sane = 0;
|
|
}
|
|
else
|
|
{
|
|
# Sane, Record the answers.
|
|
$anvil->Database->insert_or_update_variables({
|
|
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",
|
|
update_value_only => 1,
|
|
});
|
|
}
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, 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 => 3, 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 : 1;
|
|
$anvil->data->{cgi}{ifn_count}{value} = $ifn_count ne "" ? $ifn_count : 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, 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},
|
|
}});
|
|
}
|
|
|
|
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} : "",
|
|
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} : "",
|
|
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} : "",
|
|
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 => "main.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,
|
|
cgi_list => "organization,prefix,domain,sequence,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}{'scancore-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' }, 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'},
|
|
}});
|
|
}
|
|
}
|
|
|
|
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 => "main.html", name => "network_header"});
|
|
foreach my $interface (sort {$a cmp $b} keys %{$data->{interface}})
|
|
{
|
|
$interface_list .= "$interface,";
|
|
$network .= $anvil->Template->get({file => "main.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 => "main.html", name => "network_footer", variables => { interface_list => $interface_list }});
|
|
}
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network => $network }});
|
|
return($network);
|
|
}
|
|
|
|
# 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's second octet will be '+X' where 'X' is the sequence.
|
|
my $default_ip = $anvil->data->{'default'}{$network}{subnet};
|
|
my $default_netmark = $anvil->data->{'default'}{$network}{netmask};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
|
default_ip => $default_ip,
|
|
default_netmark => $default_netmark,
|
|
}});
|
|
|
|
if (($anvil->Validate->is_ipv4({ip => $default_ip})) && ($anvil->Validate->is_ipv4({ip => $default_netmark})))
|
|
{
|
|
# 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_netmark eq "255.255.0.0")
|
|
{
|
|
# We can work with this.
|
|
$ip_octet2 += $network_sequence;
|
|
$ip_octet3 = $anvil->data->{'default'}{bcn}{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);
|
|
}
|