diff --git a/Anvil/Tools.pm b/Anvil/Tools.pm
index b7edbc84..ddbcda14 100755
--- a/Anvil/Tools.pm
+++ b/Anvil/Tools.pm
@@ -748,6 +748,7 @@ sub _set_paths
firewalld_services => "/usr/lib/firewalld/services",
firewalld_zones => "/etc/firewalld/zones",
html => "/var/www/html",
+ ifcfg => "/etc/sysconfig/network-scripts",
skins => "/var/www/html/skins",
tools => "/usr/sbin",
units => "/usr/lib/systemd/system",
diff --git a/cgi-bin/home b/cgi-bin/home
index 31d738c6..e87937a6 100755
--- a/cgi-bin/home
+++ b/cgi-bin/home
@@ -4,6 +4,9 @@
# 0 == OK
# 1 == Host UUID not available yet.
#
+# TODO:
+# * Make the BCN count a thing, remove Striker user and make it statically 'admin'.
+#
use strict;
use warnings;
diff --git a/notes b/notes
index b7426ab6..a0219b18 100644
--- a/notes
+++ b/notes
@@ -60,6 +60,19 @@ Example Link config:
Example Bonding config:
====
+BRIDGE_UUID="e7a8f977-560d-4a94-95cd-a1218f0fe890"
+DEVICE="ifn1_bond1"
+NAME="IFN 1 - Bond 1"
+UUID="a59d138e-6c40-4366-b859-fcadafe577f4"
+BONDING_OPTS="mode=active-backup primary=ifn1_link1 updelay=120000 downdelay=0 miimon=100 primary_reselect=better"
+TYPE="Bond"
+BONDING_MASTER="yes"
+BOOTPROTO="none"
+IPV6INIT="no"
+ONBOOT="yes"
+DEFROUTE="no"
+BRIDGE="ifn1_bridge1"
+ZONE=public
====
Example Bridge config:
diff --git a/share/words.xml b/share/words.xml
index 54e6583b..30bf54ea 100644
--- a/share/words.xml
+++ b/share/words.xml
@@ -221,6 +221,8 @@ The database connection error was:
A job to configure the network was found, but it has already been picked up by: [#!variable!pid!#].
A job to configure the network was found, and it was picked up by: [#!variable!pid!#], but that process is not running and it appears to only be: [#!variable!percent!# %] complete. Taking the job.
+ The network: [#!variable!network!#] has something set for the IP [#!variable!ip!#], but it appears to be invalid. Ignoring this network.
+ The network: [#!variable!network!#] is not set to be configured. Skipping it.
Test
diff --git a/tools/anvil-configure-network b/tools/anvil-configure-network
index a86d55a4..9a90de8d 100755
--- a/tools/anvil-configure-network
+++ b/tools/anvil-configure-network
@@ -52,6 +52,10 @@ pickup_job_details($anvil);
reconfigure_network($anvil);
+# Set the passwords
+my $password = $anvil->data->{variables}{form}{config_step2}{striker_password}{value};
+$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { password => $password }});
+
$anvil->nice_exit({code => 0});
#############################################################################################################
@@ -68,8 +72,9 @@ sub reconfigure_network
my $domain = $anvil->data->{variables}{form}{config_step1}{domain}{value};
my $organization = $anvil->data->{variables}{form}{config_step1}{organization}{value};
my $bcn_count = 1; # TODO: This should be coming from the form, even though it's only '1' for now.
+ my $sn_count = 0; # TODO: This should be coming from the form, even though it's always '0' for Strikers.
my $ifn_count = $anvil->data->{variables}{form}{config_step1}{ifn_count}{value};
- my $new_hostname = $prefix."-striker".sprintf("%02d", $sequence).".".$domain;
+ my $new_hostname = defined $anvil->data->{variables}{form}{config_step2}{hostname}{value} ? $anvil->data->{variables}{form}{config_step2}{hostname}{value} : $prefix."-striker".sprintf("%02d", $sequence).".".$domain;
my $pretty_hostname = $organization." - Striker ".sprintf("%02d", $sequence);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
prefix => $prefix,
@@ -88,22 +93,25 @@ sub reconfigure_network
if ($hostname eq $new_hostname)
{
# Success
+ $anvil->{job}{status} .= "message_0016,!!hostname!$new_hostname!!\n";
$anvil->Database->insert_or_update_jobs({
job_uuid => $anvil->{job}{uuid},
update_progress_only => 1,
job_progress => 10,
- job_status => "message_0016,!!hostname!$new_hostname!!\n",
+ job_status => $anvil->{job}{status},
});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "message_0016", variables => { hostname => $new_hostname }});
}
else
{
# Failed
+ $anvil->{job}{status} .= "message_0017,!!hostname!$new_hostname!!,!!bad_hostname!$hostname!!\n";
+ $anvil->{job}{status} .= "failed\n";
$anvil->Database->insert_or_update_jobs({
job_uuid => $anvil->{job}{uuid},
update_progress_only => 1,
job_progress => 100,
- job_status => "message_0017,!!hostname!$new_hostname!!,!!bad_hostname!$hostname!!\nfailed\n",
+ job_status => $anvil->{job}{status},
});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, key => "message_0017", variables => {
hostname => $new_hostname,
@@ -113,82 +121,195 @@ sub reconfigure_network
}
# Now configure the network.
- foreach my $network (1..$bcn_count)
+ my $dns = defined $anvil->data->{variables}{form}{config_step2}{dns}{value} ? [split/,/, $anvil->data->{variables}{form}{config_step2}{dns}{value}] : [];
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { dns => $dns }});
+ for (my $i = 0; $i < @{$dns}; $i++)
{
- my $link1_key = "bcn".$network."_iface1_mac";
- my $link2_key = "bcn".$network."_iface2_mac";
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
- link1_key => $link1_key,
- link2_key => $link2_key,
- }});
- my $create_bond = 0;
- if ((exists $anvil->data->{variables}{form}{config_step2}{$link2_key}{value}) && ($anvil->Validate->is_mac({mac => $anvil->data->{variables}{form}{config_step2}{$link2_key}{value}})))
- {
- # Bonded
- }
- elsif ((exists $anvil->data->{variables}{form}{config_step2}{$link1_key}{value}) && ($anvil->Validate->is_mac({mac => $anvil->data->{variables}{form}{config_step2}{$link1_key}{value}})))
+ $dns->[$i] = $anvil->Words->clean_spaces({ string => $dns->[$i] });
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "dns->[$i]" => $dns->[$i] }});
+ }
+
+ my $gateway = defined $anvil->data->{variables}{form}{config_step2}{gateway}{value} ? $anvil->data->{variables}{form}{config_step2}{gateway}{value} : "";
+ my $gateway_interface = defined $anvil->data->{variables}{form}{config_step2}{gateway_interface}{value} ? $anvil->data->{variables}{form}{config_step2}{gateway_interface}{value} : "";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ gateway => $gateway,
+ gateway_interface => $gateway_interface,
+ }});
+ foreach my $network_type ("bcn", "sn", "ifn")
+ {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_type => $network_type }});
+
+ my $count = 0;
+ if ($network_type eq "bcn") { $count = $bcn_count; }
+ elsif ($network_type eq "sn") { $count = $sn_count; }
+ elsif ($network_type eq "ifn") { $count = $ifn_count; }
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
+
+ next if not $count;
+ foreach my $network_count (1..$count)
{
- # Single
+ my $this_network = $network_type.$network_count;
+ my $link1_key = $this_network."_iface1_mac";
+ my $link2_key = $this_network."_iface2_mac";
+ my $subnet_key = $this_network."_subnet";
+ my $ip_key = $this_network."_ip";
+ my $is_gateway = $this_network eq $gateway_interface ? 1 : 0;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ this_network => $this_network,
+ link1_key => $link1_key,
+ link2_key => $link2_key,
+ subnet_key => $subnet_key,
+ ip_key => $ip_key,
+ is_gateway => $is_gateway,
+ }});
+
+ # Skip if this doesn't exist or isn't a valid IPv$ address.
+ next if not exists $anvil->data->{variables}{form}{config_step2}{$ip_key}{value};
+ if (($anvil->data->{variables}{form}{config_step2}{$ip_key}{value}) and (not $anvil->Validate->is_ipv4({ip => $anvil->data->{variables}{form}{config_step2}{$ip_key}{value}})))
+ {
+ # Something was set, but it isn't valid.
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, key => "log_0148", variables => {
+ network => $this_network,
+ ip => $anvil->data->{variables}{form}{config_step2}{$ip_key}{value},
+ }});
+ next;
+ }
+
+ my $ip = $anvil->data->{variables}{form}{config_step2}{$ip_key}{value};
+ my $subnet = $anvil->data->{variables}{form}{config_step2}{$subnet_key}{value};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ ip => $ip,
+ subnet => $subnet,
+ }});
+
+ if ((exists $anvil->data->{variables}{form}{config_step2}{$link2_key}{value}) && ($anvil->Validate->is_mac({mac => $anvil->data->{variables}{form}{config_step2}{$link2_key}{value}})))
+ {
+ # Bonded
+ my $link1_mac = $anvil->data->{variables}{form}{config_step2}{$link1_key}{value};
+ my $link2_mac = $anvil->data->{variables}{form}{config_step2}{$link2_key}{value};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ link1_mac => $link1_mac,
+ link2_mac => $link2_mac,
+ }});
+
+ ### TODO: Handle when bridges exist. Detect when the host is a node and/or have a "use as bridge" option?
+ # Build the configs.
+ my $say_network = "";
+ my $say_interface = "";
+ my $interface_prefix = "";
+ if ($network_type eq "bcn")
+ {
+ $say_network = "Back-Channel Network ".$network_count;
+ $say_interface = "bcn".$network_count;
+ $interface_prefix = "BCN";
+ }
+ elsif ($network_type eq "sn")
+ {
+ $say_network = "Storage Network ".$network_count;
+ $say_interface = "sn".$network_count;
+ $interface_prefix = "SN";
+ }
+ elsif ($network_type eq "ifn")
+ {
+ $say_network = "Internet-Facing Network ".$network_count;
+ $say_interface = "ifn".$network_count;
+ $interface_prefix = "IFN";
+ }
+ my $bond_file = $anvil->data->{path}{directories}{ifcfg}."/ifcfg-".$interface_prefix."_".$network_count."_-_Bond_1";
+ my $link2_file = $anvil->data->{path}{directories}{ifcfg}."/ifcfg-".$interface_prefix."_".$network_count."_-_Link_2";
+ my $link1_file = $anvil->data->{path}{directories}{ifcfg}."/ifcfg-".$interface_prefix."_".$network_count."_-_Link_1";
+ my $bond_uuid = get_uuid_from_interface_file($anvil, $bond_file);
+ my $link2_uuid = get_uuid_from_interface_file($anvil, $link2_file);
+ my $link1_uuid = get_uuid_from_interface_file($anvil, $link1_file);
+ my $say_defroute = $is_gateway ? "yes" : "no";
+ my $cidr = $anvil->Convert->cidr({subnet => $subnet});
+
+ ### TODO: Set the firewall Zone appropriately.
+ # Build the Bond config.
+ my $bond_config = "# $say_network - Bond 1\n";
+ $bond_config .= "DEVICE=\"".$say_interface."_bond1\"\n";
+ $bond_config .= "NAME=\"".$interface_prefix." ".$network_count." - Bond 1\"\n";
+ $bond_config .= "UUID=\"".$bond_uuid."\"\n";
+ $bond_config .= "BONDING_OPTS=\"mode=active-backup primary=".$say_interface."_link1 updelay=120000 downdelay=0 miimon=100 primary_reselect=better\"\n";
+ $bond_config .= "TYPE=\"Bond\"\n";
+ $bond_config .= "BONDING_MASTER=\"yes\"\n";
+ $bond_config .= "BOOTPROTO=\"none\"\n";
+ $bond_config .= "IPV6INIT=\"no\"\n";
+ $bond_config .= "ONBOOT=\"yes\"\n";
+ $bond_config .= "IPADDR=\"".$ip."\"\n";
+ $bond_config .= $cidr ? "PREFIX=\"".$cidr."\"\n" : "NETMASK=\"".$subnet."\"\n";
+ if ($is_gateway)
+ {
+ $bond_config .= "GATEWAY=\"".$gateway."\"\n";
+ for (my $i = 0; $i < @{$dns}; $i++)
+ {
+ $bond_config .= "DNS".($i+1)."=\"".$dns->[$i]."\"\n";
+ }
+ }
+ $bond_config .= "DEFROUTE=\"".$say_defroute."\"\n";
+ $bond_config .= "ZONE=\"".$say_interface."\"";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ bond_config => $bond_config,
+ }});
+
+ my $link1_config = "";
+ my $link2_config = "";
+ }
+ elsif ((exists $anvil->data->{variables}{form}{config_step2}{$link1_key}{value}) && ($anvil->Validate->is_mac({mac => $anvil->data->{variables}{form}{config_step2}{$link1_key}{value}})))
+ {
+ # Single
+ my $link1_mac = $anvil->data->{variables}{form}{config_step2}{$link1_key}{value};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { link1_mac => $link1_mac }});
+ }
+ else
+ {
+ # Doesn't exist, skip.
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, key => "log_0149", variables => { network => $this_network }});
+ next;
+ }
}
- else
+ }
+
+ return(0);
+}
+
+# This will read a network interface file and return the UUID="x" value. If the file doesn't exist or the
+# UUID was not found, a new UUID is generated and returned.
+sub get_uuid_from_interface_file
+{
+ my ($anvil, $file) = @_;
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0131", variables => { function => "get_uuid_from_interface_file" }});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file => $file }});
+
+ my $uuid = "";
+ if (-e $file)
+ {
+ my $body = $anvil->Storage->read_file({file => $file});
+ foreach my $line (split/\n/, $body)
{
- # Doesn't exist, skip.
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
+ $line =~ s/#.*//;
+ if ($line =~ /UUID=\"(.*?)\"/)
+ {
+ my $test_uuid = $1;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_uuid => $test_uuid }});
+ if ($anvil->Validate->is_uuid({uuid => $test_uuid}))
+ {
+ $uuid = $test_uuid;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid => $uuid }});
+ }
+ last;
+ }
}
}
+ if (not $uuid)
+ {
+ $uuid = $anvil->Get->uuid();
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid => $uuid }});
+ }
-=cut
- print Dumper $anvil->data->{variables};
-
-$VAR1 = {
- 'form' => {
- 'config_step2' => {
- 'bcn1_subnet' => {
- 'value' => '255.255.0.0'
- },
- 'ifn1_iface1_mac' => {
- 'value' => '52:54:00:dd:ad:8a'
- },
- 'dns' => {
- 'value' => '8.8.8.8, 8.8.4.4'
- },
- 'gateway' => {
- 'value' => '192.168.122.1'
- },
- 'bcn1_iface1_mac' => {
- 'value' => '52:54:00:6b:35:bc'
- },
- 'striker_password' => {
- 'value' => 'super secret password'
- },
- 'hostname' => {
- 'value' => 'an-striker01.alteeve.com'
- },
- 'gateway_interface' => {
- 'value' => 'ifn1'
- },
- 'ifn1_subnet' => {
- 'value' => '255.255.0.0'
- },
- 'ifn1_ip' => {
- 'value' => '192.168.122.201'
- },
- 'bcn1_ip' => {
- 'value' => '10.1.4.1'
- },
- 'bcn1_iface2_mac' => {
- 'value' => '52:54:00:5d:5d:3d'
- },
- 'ifn1_iface2_mac' => {
- 'value' => '52:54:00:1e:36:03'
- },
- 'striker_user' => {
- 'value' => 'striker'
- }
- },
- };
-=cut
-
- return(0);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { uuid => $uuid }});
+ return($uuid);
}
# This will pick up the job, or exit.
@@ -242,9 +363,6 @@ LIMIT 1;";
job_progress => $job_progress,
}});
- # This will be used when updating the job
- $anvil->{job}{uuid} = $job_uuid;
-
# See if the job was picked up by another running instance.
if ($job_picked_up_by)
{
@@ -309,12 +427,16 @@ AND
$anvil->_make_hash_reference($anvil->data->{variables}, $this_variable, $this_value);
}
+ # This will be used when updating the job
+ $anvil->{job}{uuid} = $job_uuid;
+ $anvil->{job}{status} = "message_0015\n";
+
# Record that we've picked up this job.
$anvil->Database->insert_or_update_jobs({
job_uuid => $anvil->{job}{uuid},
update_progress_only => 1,
job_progress => 1,
- job_status => "message_0015\n",
+ job_status => $anvil->{job}{status},
});
return(0);