* Started work on config_step3.

* Reworked step 2 to allow for empty DNS and empty gateway fields.
* Step2 now loads previous answers from the database properly.
* Fixed (the lack of) recording each network's IP and subnet to the database.
* Added (and disabled for now) a jquery feature for clearing the variables from the URL to keep it from getting exceptionally long.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 7 years ago
parent 8a2c97c6c5
commit 27fe291524
  1. 2
      AN/Tools/Validate.pm
  2. 249
      cgi-bin/home
  3. 3
      cgi-bin/words.xml
  4. 85
      html/skins/alteeve/main.html
  5. 7
      html/skins/alteeve/main.js

@ -126,7 +126,7 @@ sub form_field
my $an = $self->parent;
my $valid = 1;
my $debug = 2;
my $debug = 3;
my $name = defined $parameter->{name} ? $parameter->{name} : "";
my $type = defined $parameter->{type} ? $parameter->{type} : "";
my $empty_ok = defined $parameter->{empty_ok} ? $parameter->{empty_ok} : 0;

@ -146,11 +146,128 @@ $an->nice_exit({exit_code => 0});
# Functions #
#############################################################################################################
# This shows the user what is about to be done and asks the user to confirm.
sub config_step3
{
my ($an) = @_;
# 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 $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 = ".$an->data->{sys}{use_db_fh}->quote($an->Get->host_uuid)."
ORDER BY
variable_name ASC;";
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
my $results = $an->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$an->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] : "";
$an->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.",";
$an->data->{cgi}{$variable}{value} = $variable_value;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${variable}::value" => $an->data->{cgi}{$variable}{value} }});
}
}
# 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.
foreach my $variable (sort {$a cmp $b} keys %{$an->data->{cgi}})
{
}
#
my $step3_body = $an->Template->get({file => "main.html", name => "config_step3", variables => {
step1_welcome_title_id => "",
step1_welcome_message_id => "",
organization => $an->data->{cgi}{organization}{value},
prefix => $an->data->{cgi}{prefix}{value},
domain => $an->data->{cgi}{domain}{value},
striker_user => $an->data->{cgi}{striker_user}{value},
striker_password => $an->data->{cgi}{striker_password}{value},
cgi_list => $cgi."step",
}});
$an->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 ($an) = @_;
# If I am coming from stage 1, load any values from the database, if they exist.
if ($an->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 = ".$an->data->{sys}{use_db_fh}->quote($an->Get->host_uuid)."
ORDER BY
variable_name ASC;";
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0124", variables => { query => $query }});
my $results = $an->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$an->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] : "";
$an->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;
$an->data->{cgi}{$variable}{value} = $variable_value;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "cgi::${variable}::value" => $an->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
@ -159,7 +276,7 @@ sub config_step2
my $required_interfaces_for_single = 1 + $an->data->{cgi}{ifn_count}{value};
my $required_interfaces_for_bonds = 2 * $required_interfaces_for_single;
my $interface_count = keys %{$an->data->{interfaces}};
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$an->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,
@ -534,16 +651,10 @@ sub sanity_check_step2
});
}
# DNS can be multiple entries, comma-separated.
if ((not defined $an->data->{cgi}{dns}{value}) or (not $an->data->{cgi}{dns}{value}))
# 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 $an->data->{cgi}{dns}{value}) and ($an->data->{cgi}{dns}{value}))
{
$an->data->{cgi}{dns}{alert} = 1;
$sane = 0;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::dns::alert" => $an->data->{cgi}{dns}{alert} }});
}
else
{
my $dns_ok = 1;
foreach my $ip (split/,/, $an->data->{cgi}{dns}{value})
{
$ip =~ s/^\s+//;
@ -557,20 +668,20 @@ sub sanity_check_step2
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, dns_ok => $dns_ok, "cgi::dns::alert" => $an->data->{cgi}{dns}{alert} }});
}
}
if ($dns_ok)
{
# Record the answer.
$an->Database->insert_or_update_variables({
variable_name => "form::config_step2::dns::value",
variable_value => $an->data->{cgi}{dns}{value},
variable_default => "",
variable_description => "striker_0038",
variable_section => "config_step2",
variable_source_uuid => $an->Get->host_uuid,
variable_source_table => "hosts",
update_value_only => 1,
});
}
}
if ($dns_ok)
{
# Record the answer.
$an->Database->insert_or_update_variables({
variable_name => "form::config_step2::dns::value",
variable_value => $an->data->{cgi}{dns}{value},
variable_default => "",
variable_description => "striker_0038",
variable_section => "config_step2",
variable_source_uuid => $an->Get->host_uuid,
variable_source_table => "hosts",
update_value_only => 1,
});
}
# Look for interfaces and sanity check them.
@ -612,6 +723,20 @@ sub sanity_check_step2
$ip_ok = 0;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, ip_ok => $ip_ok }});
}
else
{
# Save the IP
$an->Database->insert_or_update_variables({
variable_name => "form::config_step2::${this_ip_key}::value",
variable_value => $an->data->{cgi}{$this_ip_key}{value},
variable_default => "",
variable_description => "striker_0024",
variable_section => "config_step2",
variable_source_uuid => $an->Get->host_uuid,
variable_source_table => "hosts",
update_value_only => 1,
});
}
# What about the subnet?
if (not $an->Validate->form_field({name => $this_subnet_key, type => "subnet"}))
@ -624,9 +749,21 @@ sub sanity_check_step2
# We'll use the dotted-decimal subnet. If it already is, great. If not, convert it.
my $say_subnet = $an->data->{cgi}{$this_subnet_key}{value} =~ /^\d{1,2}$/ ? $an->Convert->cide({cidr => $an->data->{cgi}{$this_subnet_key}{value}}) : $an->data->{cgi}{$this_subnet_key}{value};
my $full_ip = $an->data->{cgi}{$this_ip_key}{value}."/".$an->data->{cgi}{$this_subnet_key}{value};
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_subnet => $say_subnet, full_ip => $full_ip }});
$an->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
$an->Database->insert_or_update_variables({
variable_name => "form::config_step2::${this_subnet_key}::value",
variable_value => $an->data->{cgi}{$this_subnet_key}{value},
variable_default => "",
variable_description => "striker_0025",
variable_section => "config_step2",
variable_source_uuid => $an->Get->host_uuid,
variable_source_table => "hosts",
update_value_only => 1,
});
}
# Interface 1 must be set
@ -722,7 +859,7 @@ sub sanity_check_step2
# The gateway, this has to be after the interfaces so that we can match it to an interface (and error
# if not)
if (not $an->Validate->form_field({name => "gateway", type => "ipv4"}))
if (not $an->Validate->form_field({name => "gateway", type => "ipv4", empty_ok => 1}))
{
$sane = 0;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }});
@ -730,38 +867,46 @@ sub sanity_check_step2
else
{
# Convert the gateway strings to binary.
my $gateway = $an->data->{cgi}{gateway}{value};
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { gateway => $gateway }});
# Match this gateway to one of the interfaces.
my $gateway = defined $an->data->{cgi}{gateway}{value} ? $an->data->{cgi}{gateway}{value} : "";
$an->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 = "";
foreach my $this_network (sort {$a cmp $b} keys %{$networks})
if ($gateway)
{
my ($this_ip, $this_subnet) = ($networks->{$this_network} =~ /^(.*?)\/(.*)$/);
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, 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");
# 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} =~ /^(.*?)\/(.*)$/);
$an->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))
if ($second->within($first))
{
$gateway_interface = $this_network;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { gateway_interface => $gateway_interface }});
}
}
if (not $gateway_interface)
{
$gateway_interface = $this_network;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { gateway_interface => $gateway_interface }});
}
$an->data->{cgi}{gateway}{alert} = 1;
$sane = 0;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::gateway::alert" => $an->data->{cgi}{gateway}{alert} }});
# Explain the problem
$an->data->{form}{error_massage} = $an->Template->get({file => "main.html", name => "error_message", variables => { error_message => $an->Words->string({key => "striker_error_0004"}) }});
}
}
if (not $gateway_interface)
{
$an->data->{cgi}{gateway}{alert} = 1;
$sane = 0;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::gateway::alert" => $an->data->{cgi}{gateway}{alert} }});
}
else
# If no alert was raised, record the values.
if (not $an->data->{cgi}{gateway}{alert})
{
# Record the answer.
$an->Database->insert_or_update_variables({

@ -68,11 +68,14 @@ This is the AN::Tools master 'words' file.
<key name="striker_0038">This is the domain name server(s) to use when resolving domain names. You can specify 2 or more, separated by commas.</key>
<key name="striker_0039">Gateway Interface</key>
<key name="striker_0040">This is the interface with the internet access. Usually this is "ifn_link1".</key> <!-- Translation note; leave 'ifn_link1' as it is, it is the device name. -->
<key name="striker_0041">We're almost ready! Does this look right? If so, we'll setup this Striker dashboard.</key>
<key name="striker_0042">Summary of answers.</key>
<!-- Errors -->
<key name="striker_error_0001">There are not enough network interfaces on this machine. You have: [#!variable!interface_count!#] interface(s), and you need at least: [#!variable!required_interfaces_for_single!#] interfaces to connect to the requested networks (one for Back-Channel and one for each Internet-Facing network).</key>
<key name="striker_error_0002">The local system UUID can't be read yet. This might be because the system is brand new and/or ScanCore hasn't run yet. Please try again in a minute.</key>
<key name="striker_error_0003">None of the databases are accessible, unable to proceed.</key>
<key name="striker_error_0004">The gateway address doesn't match any of your networks.</key>
<!-- These are works and strings used by javascript/jqery -->
<key name="js_0001">Up</key>

@ -207,6 +207,89 @@
</table>
<!-- end config_step2 -->
<!-- start config_step3 -->
<table>
<div id="config_step3_div">
<form name="config_step3" action="">
<tr>
<td>
<span name="#!variable!step1_welcome_title_id!#" id="#!variable!step1_welcome_title_id!#" class="config_header1">#!string!striker_0001!#</span><br />
<span name="#!variable!step1_welcome_message_id!#" id="#!variable!step1_welcome_message_id!#" class="config_header2">#!string!striker_0002!#</span>
</td>
</tr>
<tr>
<td>
<hr>
&nbsp;
</td>
</tr>
<tr>
<td>
#!string!striker_0041!#
</td>
</tr>
<tr>
<td>
<table class="data_table">
<tr>
<td class="column_header" colspan="2">
#!string!striker_0042!#
</td>
</tr>
<!-- Organization -->
<tr class="data_row">
<td class="column_row_name">
#!string!striker_0003!#:
</td>
<td class="column_row_value">
#!variable!organization!#
</td>
</tr>
<!-- Domain name -->
<tr>
<td class="column_row_name">
#!string!striker_0007!#:
</td>
<td class="column_row_value_fixed">
#!variable!domain!#
</td>
</tr>
<!-- User -->
<tr>
<td class="column_row_name">
#!string!striker_0031!#:
</td>
<td class="column_row_value_fixed">
#!variable!striker_user!#
</td>
</tr>
<!-- Password -->
<tr>
<td class="column_row_name">
#!string!striker_0033!#:
</td>
<td class="column_row_value_fixed">
#!variable!striker_password!#
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<br />
<hr>
<input type="submit" name="next" id="next" value="#!string!striker_0013!#">
</td>
</tr>
<!-- NOTE: For now, we support only one BCN in the web UI, but the system will be ready for N-number later. -->
<input type="hidden" name="step" id="step" value="step3">
<input type="hidden" name="cgi_list" id="cgi_list" value="next,step,#!variable!cgi_list!#">
</form>
</div>
</table>
<!-- end config_step3 -->
<!-- start error_message -->
<div class="error_message"><span style="color: #ff3f7f;">*</span> #!variable!error_message!# </div>
<!-- end error_message -->
@ -376,7 +459,7 @@
<!-- end network_footer -->
<!-- start footer -->
<div onload="show_status()" class="footer">
<div class="footer">
#!string!brand_0005!#
</div>
<!-- end footer -->

@ -35,3 +35,10 @@ $(function() {
//$("#bar").text('B');
}
});
$( window ).on( "load", function()
{
// NOTE: Disabled for now. Clears the URL to remove everything off after '?'.
//var newURL = location.href.split("?")[0];
//window.history.pushState('object', document.title, newURL);
})

Loading…
Cancel
Save