* Created the new System->get_ips method which records IP addresses, subnet masks and MAC addresses of interfaces as reported by 'ip addr'.

* Finished the form for showing the user what changes will be made.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 7 years ago
parent 27fe291524
commit 886331c756
  1. 61
      AN/Tools/System.pm
  2. 74
      cgi-bin/home
  3. 12
      cgi-bin/words.xml
  4. 14
      html/skins/alteeve/main.css
  5. 164
      html/skins/alteeve/main.html
  6. 7
      tools/scancore-update-states

@ -18,6 +18,7 @@ my $THIS_FILE = "System.pm";
# check_memory
# determine_host_type
# enable_daemon
# get_ips
# is_local
# manage_firewall
# ping
@ -331,6 +332,66 @@ sub enable_daemon
return($return);
}
=head2 get_ips
This method checks the local system for interfaces with IP addresses and stores them in C<< sys::network::interface::<iface_name>::ip >> and C<< sys::network::interface::<iface_name>::subnet >>
=cut
sub get_ips
{
my $self = shift;
my $parameter = shift;
my $an = $self->parent;
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0125", variables => { method => "System->get_ips()" }});
my $debug = 3;
my $in_iface = "";
my $ip_addr = $an->System->call({shell_call => $an->data->{path}{exe}{ip}." addr list"});
foreach my $line (split/\n/, $ip_addr)
{
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /^\d+: (.*?): /)
{
$in_iface = $1;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_iface => $in_iface }});
$an->data->{sys}{networks}{$in_iface}{ip} = "" if not defined $an->data->{sys}{networks}{$in_iface}{ip};
$an->data->{sys}{networks}{$in_iface}{subnet} = "" if not defined $an->data->{sys}{networks}{$in_iface}{subnet};
$an->data->{sys}{networks}{$in_iface}{mac} = "" if not defined $an->data->{sys}{networks}{$in_iface}{mac};
}
next if not $in_iface;
next if $in_iface eq "lo";
if ($line =~ /inet (.*?)\/(.*?) /)
{
my $ip = $1;
my $cidr = $2;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip => $ip, cidr => $cidr }});
my $subnet = $cidr;
if (($cidr =~ /^\d{1,2}$/) && ($cidr >= 0) && ($cidr <= 32))
{
# Convert to subnet
$subnet = $an->Convert->cidr({cidr => $cidr});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { subnet => $subnet }});
}
$an->data->{sys}{networks}{$in_iface}{ip} = $ip;
$an->data->{sys}{networks}{$in_iface}{subnet} = $subnet;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:sys::networks::${in_iface}::ip" => $an->data->{sys}{networks}{$in_iface}{ip},
"s2:sys::networks::${in_iface}::subnet" => $an->data->{sys}{networks}{$in_iface}{subnet},
}});
}
if ($line =~ /ether ([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}) /i)
{
$an->data->{sys}{networks}{$in_iface}{mac} = $1;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::networks::${in_iface}::mac" => $an->data->{sys}{networks}{$in_iface}{mac} }});
}
}
return(0);
}
=head2 is_local
This method takes a host name or IP address and looks to see if it matches the local system. If it does, it returns C<< 1 >>. Otherwise it returns C<< 0 >>.

@ -154,6 +154,7 @@ sub config_step3
# 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,
@ -191,15 +192,85 @@ ORDER BY
$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} }});
if (($variable =~ /^(bcn\d+)_/) or ($variable =~ /^(ifn\d+)_/))
{
my $this_net = $1;
$nets->{$this_net} = 1;
$an->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) { $an->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.
$an->System->get_ips;
my $matched_ip = 0;
my $server_ip = $ENV{SERVER_ADDR};
$an->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.
foreach my $variable (sort {$a cmp $b} keys %{$an->data->{cgi}})
get_network_details($an);
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 = $an->data->{cgi}{$ip_key}{value};
my $subnet = $an->data->{cgi}{$subnet_key}{value};
my $iface1_mac = $an->data->{cgi}{$iface1_key}{value};
my $iface2_mac = ((defined $an->data->{cgi}{$iface2_key}{value}) && ($an->data->{cgi}{$iface2_key}{value})) ? $an->data->{cgi}{$iface2_key}{value} : "";
my $template = $iface2_mac ? "step3_bonded_interface" : "step3_single_interface";
my $gateway = $an->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";
$an->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) && ($an->data->{cgi}{gateway}{value}))
{
$template .= "_with_gateway";
$an->data->{cgi}{dns}{value} = "--" if not $an->data->{cgi}{dns}{value};
}
$networks .= $an->Template->get({file => "main.html", name => $template, variables => {
column => $an->Words->string({key => $column, variables => { number => $link_number }}),
ip_address => $say_ip,
primary => $iface1_mac,
backup => $iface2_mac,
gateway => $an->data->{cgi}{gateway}{value},
dns => $an->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;
$an->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)
{
$an->data->{form}{error_massage} = $an->Template->get({file => "main.html", name => "error_message", variables => { error_message => $an->Words->string({key => "striker_warning_0001"}) }});
}
#
@ -211,6 +282,7 @@ ORDER BY
domain => $an->data->{cgi}{domain}{value},
striker_user => $an->data->{cgi}{striker_user}{value},
striker_password => $an->data->{cgi}{striker_password}{value},
networks => $networks,
cgi_list => $cgi."step",
}});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { step3_body => $step3_body }});

@ -45,11 +45,11 @@ This is the AN::Tools master 'words' file.
<key name="striker_0015">IFN Count</key>
<key name="striker_0016">Host name</key>
<key name="striker_0017">This is the hostname for this Striker dashboard. Generally it is a good idea to stick with the default.</key>
<key name="striker_0018">Back-Channel Network link #!variable!number!#:</key>
<key name="striker_0018">Back-Channel Network link #!variable!number!#</key>
<key name="striker_0019">This is where you configure the network to enable access this Back-Channel Network.</key>
<key name="striker_0020">Storage Network link #!variable!number!#:</key>
<key name="striker_0020">Storage Network link #!variable!number!#</key>
<key name="striker_0021">This is where you configure the network to enable access this Storage Network.</key>
<key name="striker_0022">Internet-Facing Network link #!variable!number!#:</key>
<key name="striker_0022">Internet-Facing Network link #!variable!number!#</key>
<key name="striker_0023">This is where you configure the network to enable access this Internet-Facing Network.</key>
<key name="striker_0024">IP Address</key>
<key name="striker_0025">Subnet</key>
@ -69,7 +69,11 @@ This is the AN::Tools master 'words' file.
<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>
<key name="striker_0042">What we are planning to do...</key>
<key name="striker_0043">Apply New Configuration</key>
<!-- Warnings -->
<key name="striker_warning_0001">The IP address will change. You will need to reconnect after applying these changes.</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>

@ -82,9 +82,17 @@ td.column_header {
}
td.column_row_name {
text-align: left;
color: #f7f7f7;
padding: 0.2em;
text-align: left;
vertical-align: top;
color: #f7f7f7;
padding: 0.2em;
}
td.column_subrow_name {
text-align: right;
vertical-align: top;
color: #c7c7c7;
padding: 0.1em;
}
td.column_row_value {

@ -228,6 +228,12 @@
#!string!striker_0041!#
</td>
</tr>
<tr>
<td>
<hr>
&nbsp;
</td>
</tr>
<tr>
<td>
<table class="data_table">
@ -272,6 +278,8 @@
#!variable!striker_password!#
</td>
</tr>
<!-- Networks -->
#!variable!networks!#
</table>
</td>
</tr>
@ -279,7 +287,7 @@
<td>
<br />
<hr>
<input type="submit" name="next" id="next" value="#!string!striker_0013!#">
<input type="submit" name="next" id="next" value="#!string!striker_0043!#">
</td>
</tr>
<!-- NOTE: For now, we support only one BCN in the web UI, but the system will be ready for N-number later. -->
@ -290,6 +298,158 @@
</table>
<!-- end config_step3 -->
<!-- start step3_bonded_interface -->
<tr>
<td class="column_row_name">
#!variable!column!#:
</td>
<td>
&nbsp;
</td>
</tr>
<tr>
<td>
#!string!striker_0024!#:
</td>
<td class="column_row_value_fixed">
#!variable!ip_address!#
</td>
</tr>
<tr>
<td>
#!string!striker_0029!#:
</td>
<td class="column_row_value_fixed">
#!variable!primary!#
</td>
<td>
#!string!striker_0030!#:
</td>
<td class="column_row_value_fixed">
#!variable!backup!#
</td>
</tr>
<!-- end step3_bonded_interface -->
<!-- start step3_bonded_interface_with_gateway -->
<tr>
<td class="column_row_name">
#!variable!column!#:
</td>
<td>
&nbsp;
</td>
</tr>
<tr>
<td>
#!string!striker_0024!#:
</td>
<td class="column_row_value_fixed">
#!variable!ip_address!#
</td>
</tr>
<tr>
<td>
#!string!striker_0026!#:
</td>
<td class="column_row_value_fixed">
#!variable!gateway!#
</td>
</tr>
<tr>
<td>
#!string!striker_0027!#:
</td>
<td class="column_row_value_fixed">
#!variable!dns!#
</td>
</tr>
<tr>
<td>
#!string!striker_0029!#:
</td>
<td class="column_row_value_fixed">
#!variable!primary!#
</td>
<td>
#!string!striker_0030!#:
</td>
<td class="column_row_value_fixed">
#!variable!backup!#
</td>
</tr>
<!-- end step3_bonded_interface_with_gateway -->
<!-- start step3_single_interface -->
<tr>
<td class="column_row_name">
#!variable!column!#:
</td>
<td>
&nbsp;
</td>
</tr>
<tr>
<td class="column_subrow_name">
#!string!striker_0024!#:
</td>
<td class="column_row_value_fixed">
#!variable!ip_address!#
</td>
</tr>
<tr>
<td class="column_subrow_name">
#!string!striker_0028!#:
</td>
<td class="column_row_value_fixed">
#!variable!primary!#
</td>
</tr>
<!-- end step3_single_interface -->
<!-- start step3_single_interface_with_gateway -->
<tr>
<td class="column_row_name">
#!variable!column!#:
</td>
<td>
&nbsp;
</td>
</tr>
<tr>
<td class="column_subrow_name">
#!string!striker_0024!#:
</td>
<td class="column_row_value_fixed">
#!variable!ip_address!#
</td>
</tr>
<tr>
<td class="column_subrow_name">
#!string!striker_0026!#:
</td>
<td class="column_row_value_fixed">
#!variable!gateway!#
</td>
</tr>
<tr>
<td class="column_subrow_name">
#!string!striker_0027!#:
</td>
<td class="column_row_value_fixed">
#!variable!dns!#
</td>
</tr>
<tr>
<td class="column_subrow_name">
#!string!striker_0028!#:
</td>
<td class="column_row_value_fixed">
#!variable!primary!#
</td>
</tr>
<!-- end step3_single_interface_with_gateway -->
<!-- start error_message -->
<div class="error_message"><span style="color: #ff3f7f;">*</span> #!variable!error_message!# </div>
<!-- end error_message -->
@ -313,7 +473,7 @@
<table>
<tr>
<td colspan="5" class="form_group_header1">
#!variable!field!#
#!variable!field!#:
</td>
</tr>
<tr>

@ -40,7 +40,7 @@ sub report_network
my ($an) = @_;
# Write out the data in json format.
my $directory = $an->data->{path}{sysfs}{network_interfaces};
my $directory = $an->data->{path}{sysfs}{network_interfaces};
local(*DIRECTORY);
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0018", variables => { directory => $directory }});
opendir(DIRECTORY, $directory);
@ -107,6 +107,11 @@ sub report_network
}
closedir(DIRECTORY);
### TODO: Create an "ip" table and record IPs on this system, linking back to an interface, bond or
### bridge.
# Run 'ip addr' to see what IPs are in use.
$an->System->get_ips;
# Write out the XML file and JSON file.
my $order = 1;
my $network_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";

Loading…
Cancel
Save