* Got tools/anvil-configure-network writing the first network config file body.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 7 years ago
parent d6846841a2
commit c88cbf4531
  1. 1
      Anvil/Tools.pm
  2. 3
      cgi-bin/home
  3. 13
      notes
  4. 2
      share/words.xml
  5. 274
      tools/anvil-configure-network

@ -748,6 +748,7 @@ sub _set_paths
firewalld_services => "/usr/lib/firewalld/services", firewalld_services => "/usr/lib/firewalld/services",
firewalld_zones => "/etc/firewalld/zones", firewalld_zones => "/etc/firewalld/zones",
html => "/var/www/html", html => "/var/www/html",
ifcfg => "/etc/sysconfig/network-scripts",
skins => "/var/www/html/skins", skins => "/var/www/html/skins",
tools => "/usr/sbin", tools => "/usr/sbin",
units => "/usr/lib/systemd/system", units => "/usr/lib/systemd/system",

@ -4,6 +4,9 @@
# 0 == OK # 0 == OK
# 1 == Host UUID not available yet. # 1 == Host UUID not available yet.
# #
# TODO:
# * Make the BCN count a thing, remove Striker user and make it statically 'admin'.
#
use strict; use strict;
use warnings; use warnings;

13
notes

@ -60,6 +60,19 @@ Example Link config:
Example Bonding 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: Example Bridge config:

@ -221,6 +221,8 @@ The database connection error was:
<key name="log_0145"><![CDATA[[ Warning ] - Unable to use the database on the host: [#!variable!host!#]. The local Anvil! version is: [#!variable!local_version!#], and the target host's is: [#!variable!target_version!#]. If you are upgrading, we will resync and use it once the host and our version is again the same.]]></key> <key name="log_0145"><![CDATA[[ Warning ] - Unable to use the database on the host: [#!variable!host!#]. The local Anvil! version is: [#!variable!local_version!#], and the target host's is: [#!variable!target_version!#]. If you are upgrading, we will resync and use it once the host and our version is again the same.]]></key>
<key name="log_0146">A job to configure the network was found, but it has already been picked up by: [#!variable!pid!#].</key> <key name="log_0146">A job to configure the network was found, but it has already been picked up by: [#!variable!pid!#].</key>
<key name="log_0147">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.</key> <key name="log_0147">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.</key>
<key name="log_0148">The network: [#!variable!network!#] has something set for the IP [#!variable!ip!#], but it appears to be invalid. Ignoring this network.</key>
<key name="log_0149">The network: [#!variable!network!#] is not set to be configured. Skipping it.</key>
<!-- Test words. Do NOT change unless you update 't/Words.t' or tests will needlessly fail. --> <!-- Test words. Do NOT change unless you update 't/Words.t' or tests will needlessly fail. -->
<key name="t_0000">Test</key> <key name="t_0000">Test</key>

@ -52,6 +52,10 @@ pickup_job_details($anvil);
reconfigure_network($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}); $anvil->nice_exit({code => 0});
############################################################################################################# #############################################################################################################
@ -68,8 +72,9 @@ sub reconfigure_network
my $domain = $anvil->data->{variables}{form}{config_step1}{domain}{value}; my $domain = $anvil->data->{variables}{form}{config_step1}{domain}{value};
my $organization = $anvil->data->{variables}{form}{config_step1}{organization}{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 $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 $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); my $pretty_hostname = $organization." - Striker ".sprintf("%02d", $sequence);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
prefix => $prefix, prefix => $prefix,
@ -88,22 +93,25 @@ sub reconfigure_network
if ($hostname eq $new_hostname) if ($hostname eq $new_hostname)
{ {
# Success # Success
$anvil->{job}{status} .= "message_0016,!!hostname!$new_hostname!!\n";
$anvil->Database->insert_or_update_jobs({ $anvil->Database->insert_or_update_jobs({
job_uuid => $anvil->{job}{uuid}, job_uuid => $anvil->{job}{uuid},
update_progress_only => 1, update_progress_only => 1,
job_progress => 10, 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 }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "message_0016", variables => { hostname => $new_hostname }});
} }
else else
{ {
# Failed # Failed
$anvil->{job}{status} .= "message_0017,!!hostname!$new_hostname!!,!!bad_hostname!$hostname!!\n";
$anvil->{job}{status} .= "failed\n";
$anvil->Database->insert_or_update_jobs({ $anvil->Database->insert_or_update_jobs({
job_uuid => $anvil->{job}{uuid}, job_uuid => $anvil->{job}{uuid},
update_progress_only => 1, update_progress_only => 1,
job_progress => 100, 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 => { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, key => "message_0017", variables => {
hostname => $new_hostname, hostname => $new_hostname,
@ -113,82 +121,195 @@ sub reconfigure_network
} }
# Now configure the 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"; $dns->[$i] = $anvil->Words->clean_spaces({ string => $dns->[$i] });
my $link2_key = "bcn".$network."_iface2_mac"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "dns->[$i]" => $dns->[$i] }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { }
link1_key => $link1_key,
link2_key => $link2_key, 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} : "";
my $create_bond = 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
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}}))) gateway => $gateway,
{ gateway_interface => $gateway_interface,
# Bonded }});
} foreach my $network_type ("bcn", "sn", "ifn")
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}}))) {
$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 $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { uuid => $uuid }});
print Dumper $anvil->data->{variables}; return($uuid);
$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);
} }
# This will pick up the job, or exit. # This will pick up the job, or exit.
@ -242,9 +363,6 @@ LIMIT 1;";
job_progress => $job_progress, 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. # See if the job was picked up by another running instance.
if ($job_picked_up_by) if ($job_picked_up_by)
{ {
@ -309,12 +427,16 @@ AND
$anvil->_make_hash_reference($anvil->data->{variables}, $this_variable, $this_value); $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. # Record that we've picked up this job.
$anvil->Database->insert_or_update_jobs({ $anvil->Database->insert_or_update_jobs({
job_uuid => $anvil->{job}{uuid}, job_uuid => $anvil->{job}{uuid},
update_progress_only => 1, update_progress_only => 1,
job_progress => 1, job_progress => 1,
job_status => "message_0015\n", job_status => $anvil->{job}{status},
}); });
return(0); return(0);

Loading…
Cancel
Save