From 27fe291524f646312a1c6a604a26e9bf0061bc89 Mon Sep 17 00:00:00 2001 From: Digimer Date: Wed, 11 Oct 2017 01:20:03 -0400 Subject: [PATCH] * 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 --- AN/Tools/Validate.pm | 2 +- cgi-bin/home | 249 +++++++++++++++++++++++++++-------- cgi-bin/words.xml | 3 + html/skins/alteeve/main.html | 85 +++++++++++- html/skins/alteeve/main.js | 7 + 5 files changed, 292 insertions(+), 54 deletions(-) diff --git a/AN/Tools/Validate.pm b/AN/Tools/Validate.pm index 3b7925f1..20bf1efd 100755 --- a/AN/Tools/Validate.pm +++ b/AN/Tools/Validate.pm @@ -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; diff --git a/cgi-bin/home b/cgi-bin/home index d5797907..8ad7a791 100755 --- a/cgi-bin/home +++ b/cgi-bin/home @@ -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({ diff --git a/cgi-bin/words.xml b/cgi-bin/words.xml index af16fb9d..3aa02bdb 100644 --- a/cgi-bin/words.xml +++ b/cgi-bin/words.xml @@ -68,11 +68,14 @@ This is the AN::Tools master 'words' file. This is the domain name server(s) to use when resolving domain names. You can specify 2 or more, separated by commas. Gateway Interface This is the interface with the internet access. Usually this is "ifn_link1". + We're almost ready! Does this look right? If so, we'll setup this Striker dashboard. + Summary of answers. 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). 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. None of the databases are accessible, unable to proceed. + The gateway address doesn't match any of your networks. Up diff --git a/html/skins/alteeve/main.html b/html/skins/alteeve/main.html index 405bb74c..029f4ce5 100644 --- a/html/skins/alteeve/main.html +++ b/html/skins/alteeve/main.html @@ -207,6 +207,89 @@ + + +
+
+
+ + + + + + + + + + + + + + + + + + + +
+ #!string!striker_0001!#
+ #!string!striker_0002!# +
+
+   +
+ #!string!striker_0041!# +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ #!string!striker_0042!# +
+ #!string!striker_0003!#: + + #!variable!organization!# +
+ #!string!striker_0007!#: + + #!variable!domain!# +
+ #!string!striker_0031!#: + + #!variable!striker_user!# +
+ #!string!striker_0033!#: + + #!variable!striker_password!# +
+
+
+
+ +
+ +
* #!variable!error_message!#
@@ -376,7 +459,7 @@ -