* Updated anvil-configure-striker to handle network configurations in non-bonded configurations and to remove virsh bridges.

* Added error messages to Striker configuration forms.
* Fixed a bug in home->get_network_details() function to handle single IPs in network.xml.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 7 years ago
parent a3d97e4c92
commit 2febb09d72
  1. 1
      Anvil/Tools.pm
  2. 146
      cgi-bin/home
  3. 2
      rpm/SPECS/anvil.spec
  4. 12
      share/words.xml
  5. 174
      tools/anvil-configure-striker
  6. 1
      tools/anvil-update-states

@ -886,6 +886,7 @@ sub _set_paths
'tr' => "/usr/bin/tr",
usermod => "/usr/sbin/usermod",
uuidgen => "/usr/bin/uuidgen",
virsh => "/usr/bin/virsh",
},
'lock' => {
database => "/tmp/anvil-tools.database.lock",

@ -178,6 +178,7 @@ sub check_availability
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'say::maintenance' => $anvil->data->{say}{maintenance} }});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { available => $available }});
return($available);
}
@ -742,7 +743,9 @@ sub sanity_check_step2
# Do we have a host name, striker user and password?
if (not $anvil->Validate->form_field({name => "hostname", type => "domain_name"}))
{
$sane = 0;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0012"}) }});
$anvil->data->{cgi}{hostname}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }});
}
else
@ -763,8 +766,9 @@ sub sanity_check_step2
# The user name
if ((not defined $anvil->data->{cgi}{striker_user}{value}) or (not $anvil->data->{cgi}{striker_user}{value}))
{
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0013"}) }});
$anvil->data->{cgi}{striker_user}{alert} = 1;
$sane = 0;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::striker_user::alert" => $anvil->data->{cgi}{striker_user}{alert} }});
}
else
@ -785,8 +789,9 @@ sub sanity_check_step2
# The password
if ((not defined $anvil->data->{cgi}{striker_password}{value}) or (not $anvil->data->{cgi}{striker_password}{value}) or (length($anvil->data->{cgi}{striker_password}{value}) < 6))
{
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0014"}) }});
$anvil->data->{cgi}{striker_password}{alert} = 1;
$sane = 0;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::striker_password::alert" => $anvil->data->{cgi}{striker_password}{alert} }});
}
else
@ -815,9 +820,10 @@ sub sanity_check_step2
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { ip => $ip }});
if (not $anvil->Validate->is_ipv4({ip => $ip}))
{
$anvil->data->{cgi}{dns}{alert} = 1;
$sane = 0;
$dns_ok = 0;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0015"}) }});
$anvil->data->{cgi}{dns}{alert} = 1;
$sane = 0;
$dns_ok = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, dns_ok => $dns_ok, "cgi::dns::alert" => $anvil->data->{cgi}{dns}{alert} }});
}
}
@ -853,8 +859,8 @@ sub sanity_check_step2
my $this_network = $network.$count;
my $this_ip_key = $this_network."_ip";
my $this_subnet_key = $this_network."_subnet";
my $this_iface1_key = $this_network."_iface1_mac";
my $this_iface2_key = $this_network."_iface2_mac";
my $this_iface1_key = $this_network."_link1_mac_to_set";
my $this_iface2_key = $this_network."_link2_mac_to_set";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
count => $count,
this_ip_key => $this_ip_key,
@ -867,13 +873,19 @@ sub sanity_check_step2
"cgi::${this_iface2_key}::value" => $anvil->data->{cgi}{$this_iface2_key}{value},
}});
# This will be used to tell the user which interface has a problem, if one exists.
my $network_key = $network =~ /^bcn/ ? "striker_0018" : "striker_0022";
my $say_network = $anvil->Words->string({key => $network_key, variables => { number => $count }});
# Is the IP sane?
my $ip_ok = 1;
if (not $anvil->Validate->form_field({name => $this_ip_key, type => "ipv4"}))
{
# Nope
$sane = 0;
$ip_ok = 0;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0016", variables => { network => $say_network}}) }});
$anvil->data->{cgi}{$this_ip_key}{alert} = 1;
$sane = 0;
$ip_ok = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, ip_ok => $ip_ok }});
}
else
@ -894,7 +906,9 @@ sub sanity_check_step2
# What about the subnet?
if (not $anvil->Validate->form_field({name => $this_subnet_key, type => "subnet"}))
{
$sane = 0;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0016", variables => { network => $say_network }}) }});
$anvil->data->{cgi}{$this_subnet_key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }});
}
elsif ($ip_ok)
@ -922,7 +936,9 @@ sub sanity_check_step2
# Interface 1 must be set
if (not $anvil->Validate->form_field({name => $this_iface1_key, type => "mac"}))
{
$sane = 0;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0017", variables => { network => $say_network, 'link' => "1" }}) }});
$anvil->data->{cgi}{$this_iface1_key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }});
}
else
@ -950,10 +966,11 @@ sub sanity_check_step2
else
{
# Conflict! Set the alert for this interface and the conflicting one.
my $conflict_key = $anvil->data->{network}{$mac}{set_as};
my $conflict_key = $anvil->data->{network}{$mac}{set_as};
$anvil->data->{cgi}{$conflict_key}{alert} = 1;
$anvil->data->{cgi}{$this_iface1_key}{alert} = 1;
$sane = 0;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0018"}) }});
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${conflict_key}::alert" => $anvil->data->{cgi}{$conflict_key}{alert},
@ -967,7 +984,9 @@ sub sanity_check_step2
{
if (not $anvil->Validate->form_field({name => $this_iface2_key, type => "mac"}))
{
$sane = 0;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0017", variables => { network => $say_network, 'link' => "2" }}) }});
$anvil->data->{cgi}{$this_iface2_key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }});
}
else
@ -996,9 +1015,10 @@ sub sanity_check_step2
{
# Conflict! Set the alert for this interface and the conflicting one.
my $conflict_key = $anvil->data->{network}{$mac}{set_as};
$anvil->data->{cgi}{$conflict_key}{alert} = 1;
$anvil->data->{cgi}{$this_iface2_key}{alert} = 1;
$sane = 0;
$anvil->data->{cgi}{$conflict_key}{alert} = 1;
$anvil->data->{cgi}{$this_iface2_key}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0018"}) }});
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${conflict_key}::alert" => $anvil->data->{cgi}{$conflict_key}{alert},
@ -1014,7 +1034,9 @@ sub sanity_check_step2
# if not)
if (not $anvil->Validate->form_field({name => "gateway", type => "ipv4", empty_ok => 1}))
{
$sane = 0;
$anvil->data->{cgi}{gateway}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0019"}) }});
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }});
}
else
@ -1049,12 +1071,11 @@ sub sanity_check_step2
}
if (not $gateway_interface)
{
$anvil->data->{cgi}{gateway}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::gateway::alert" => $anvil->data->{cgi}{gateway}{alert} }});
# Explain the problem
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0004"}) }});
$anvil->data->{cgi}{gateway}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::gateway::alert" => $anvil->data->{cgi}{gateway}{alert} }});
}
}
@ -1103,8 +1124,9 @@ sub sanity_check_step1
# Organization just needs *something*
if ((not defined $anvil->data->{cgi}{organization}{value}) or (not $anvil->data->{cgi}{organization}{value}))
{
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0020", variables => { field => "striker_0003" }}) }});
$anvil->data->{cgi}{organization}{alert} = 1;
$sane = 0;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::organization::alert" => $anvil->data->{cgi}{organization}{alert} }});
}
else
@ -1125,8 +1147,9 @@ sub sanity_check_step1
# The prefix needs to be alphanumeric and be between 1 ~ 5 chatacters.
if ((not $anvil->Validate->is_alphanumeric({string => $anvil->data->{cgi}{prefix}{value}})) or (length($anvil->data->{cgi}{prefix}{value}) > 5))
{
$anvil->data->{cgi}{prefix}{alert} = 1;
$sane = 0;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0021"}) }});
$anvil->data->{cgi}{prefix}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::prefix::alert" => $anvil->data->{cgi}{prefix}{alert} }});
}
else
@ -1147,7 +1170,9 @@ sub sanity_check_step1
# We can use Validate to check the domain.
if (not $anvil->Validate->form_field({name => "domain", type => "domain_name"}))
{
$sane = 0;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0020", variables => { field => "striker_0007" }}) }});
$anvil->data->{cgi}{domain}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane }});
}
else
@ -1168,8 +1193,9 @@ sub sanity_check_step1
# The sequence and IFN count need to be integers.
if (not $anvil->Validate->is_positive_integer({number => $anvil->data->{cgi}{sequence}{value}}))
{
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0022", variables => { field => "striker_0009" }}) }});
$anvil->data->{cgi}{sequence}{alert} = 1;
$sane = 0;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::sequence::alert" => $anvil->data->{cgi}{sequence}{alert} }});
}
else
@ -1189,8 +1215,9 @@ sub sanity_check_step1
if (not $anvil->Validate->is_positive_integer({number => $anvil->data->{cgi}{ifn_count}{value}}))
{
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0022", variables => { field => "striker_0011" }}) }});
$anvil->data->{cgi}{ifn_count}{alert} = 1;
$sane = 0;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::ifn_count::alert" => $anvil->data->{cgi}{ifn_count}{alert} }});
}
@ -1212,11 +1239,9 @@ sub sanity_check_step1
}});
# Not enough interfaces found.
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $say_message }});
# We're not sane
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $say_message }});
$anvil->data->{cgi}{ifn_count}{alert} = 1;
$sane = 0;
$sane = 0;
}
else
{
@ -1383,7 +1408,7 @@ sub get_network_details
my $xml = XML::Simple->new();
my $data = "";
my $network = "";
eval { $data = $xml->XMLin($file, KeyAttr => { interface => 'name', key => 'name', ip => 'address' }, ForceArray => [ 'interface', 'key' ]) };
eval { $data = $xml->XMLin($file, KeyAttr => { interface => 'name', key => 'name', ip => 'address' }, ForceArray => [ 'interface', 'key' ] ) };
if ($@)
{
chomp $@;
@ -1422,15 +1447,33 @@ sub get_network_details
"interfaces::${interface}::state" => $anvil->data->{interfaces}{$interface}{'state'},
}});
}
foreach my $address (sort {$a cmp $b} keys %{$data->{ip}})
### TODO: Sort out how to read the XML using the proper KeyAttr to avoid this mess...
# If there is only one IP, the details will be stored directly under the 'ip' key. If two or
# more exist, each ip address will be the key after 'ip'.
if (exists $data->{ip}{address})
{
# <ip address="192.168.122.201" on="ifn1_bond1" subnet="255.255.0.0" gateway="192.168.122.1" default_gateway="1" dns="8.8.8.8,8.8.4.4"
# Only one entry. Fix the hash.
my $address = $data->{ip}{address};
my $on = $data->{ip}{on};
my $subnet = $data->{ip}{subnet};
my $gateway = $data->{ip}{gateway};
my $default_gateway = $data->{ip}{default_gateway};
my $dns = $data->{ip}{dns};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
address => $address,
on => $on,
subnet => $subnet,
gateway => $gateway,
default_gateway => $default_gateway,
dns => $dns,
}});
$anvil->data->{ip}{$address} = {
on => $data->{ip}{$address}{on},
subnet => $data->{ip}{$address}{subnet},
gateway => $data->{ip}{$address}{gateway},
default_gateway => $data->{ip}{$address}{default_gateway},
dns => $data->{ip}{$address}{dns},
on => $on,
subnet => $subnet,
gateway => $gateway,
default_gateway => $default_gateway,
dns => $dns,
};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"ip::${address}::on" => $anvil->data->{ip}{$address}{on},
@ -1440,6 +1483,27 @@ sub get_network_details
"ip::${address}::dns" => $anvil->data->{ip}{$address}{dns},
}});
}
else
{
foreach my $address (sort {$a cmp $b} keys %{$data->{ip}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { address => $address }});
$anvil->data->{ip}{$address} = {
on => $data->{ip}{$address}{on},
subnet => $data->{ip}{$address}{subnet},
gateway => $data->{ip}{$address}{gateway},
default_gateway => $data->{ip}{$address}{default_gateway},
dns => $data->{ip}{$address}{dns},
};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"ip::${address}::on" => $anvil->data->{ip}{$address}{on},
"ip::${address}::subnet" => $anvil->data->{ip}{$address}{subnet},
"ip::${address}::gateway" => $anvil->data->{ip}{$address}{gateway},
"ip::${address}::default_gateway" => $anvil->data->{ip}{$address}{default_gateway},
"ip::${address}::dns" => $anvil->data->{ip}{$address}{dns},
}});
}
}
}
return(0);

@ -169,6 +169,8 @@ systemctl start httpd.service
# Open access for Striker. The database will be opened after initial setup.
firewall-cmd --zone=public --add-service=http
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --zone=public --add-service=postgresql
firewall-cmd --zone=public --add-service=postgresql --permanent
%files core
%doc README.md notes

@ -267,6 +267,7 @@ The database connection error was:
<key name="log_0173"><![CDATA[[ Error ] - Asked to valudate a password encoded with the algorithm: [#!variable!user_algorithm!#], which is not recognized. Only 'sha256', 'sha384' and 'sha512' are currently supported.]]></key>
<key name="log_0174"><![CDATA[[ Error ] - Asked to update the variable: [#!variable!variable!#] in the configuration file: [#!variable!file!#], but that variable was not found.]]></key>
<key name="log_0175"><![CDATA[[ Error ] - Asked to update the variable: [#!variable!variable!#] in the configuration file: [#!variable!file!#] on the host: [#!variable!target!#], but that variable was not found.]]></key>
<key name="log_0176">The IP hash key: [#!variable!ip_key!#] does not exist, skipping it.</key>
<!-- Test words. Do NOT change unless you update 't/Words.t' or tests will needlessly fail. -->
<key name="t_0000">Test</key>
@ -368,6 +369,17 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st
<key name="error_0009">Failed to add the target: [#!variable!target!#]:[#!variable!port!#]'s RSA fingerprint to: [#!variable!user!#]'s list of known hosts.</key>
<key name="error_0010">There was a problem adding the local machine to the: [#!data!path::configs::anvil.conf!#] file. Please see the log for details.</key>
<key name="error_0011">Something went wrong while trying to update the password. The return code was: [#!variable!return_code!#], but '0' was expected.</key>
<key name="error_0012"><![CDATA[The <a href="https://en.wikipedia.org/wiki/Hostname" target="_new">hostname</a> has to be set to a valid value.]]></key>
<key name="error_0013">A user name must be set. This is usually 'admin'.</key>
<key name="error_0014">You must set a password. There are no complexity rules, but a long password is strongly recommended.</key>
<key name="error_0015">A DNS entry is bad. One or more IPv4 addresses can be specified, with a comma separating multiple IPs.</key>
<key name="error_0016">The IPv4 address assigned to: [#!variable!network!#] is invalid.</key>
<key name="error_0017">An interface to use in: [#!variable!network!# - Link #!variable!link!#] must be selected.</key>
<key name="error_0018">Network interfaces can only be selected once.</key>
<key name="error_0019">The gateway appears to have an invalid IPv4 address set.</key>
<key name="error_0020">The: [#!variable!field!#] field can't be empty.</key>
<key name="error_0021">The prefix needs to be set, and be between 1 and 5 characters long.</key>
<key name="error_0022">The: [#!variable!field!#] must be a positive integer.</key>
<!-- These are works and strings used by javascript/jqery -->
<key name="js_0001">Up</key>

@ -227,16 +227,16 @@ sub reconfigure_network
next if not $count;
foreach my $network_count (1..$count)
{
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;
my $link1_mac = $anvil->data->{variables}{form}{config_step2}{$link1_key}{value};
my $link2_mac = $anvil->data->{variables}{form}{config_step2}{$link2_key}{value};
my $old_link1_iface = $anvil->data->{sys}{mac}{$link1_mac}{iface} ? $anvil->data->{sys}{mac}{$link1_mac}{iface} : "";
my $old_link2_iface = $anvil->data->{sys}{mac}{$link2_mac}{iface} ? $anvil->data->{sys}{mac}{$link2_mac}{iface} : "";
my $this_network = $network_type.$network_count;
my $link1_key = $this_network."_link1_mac_to_set";
my $link2_key = $this_network."_link2_mac_to_set";
my $subnet_key = $this_network."_subnet";
my $ip_key = $this_network."_ip";
my $is_gateway = $this_network eq $gateway_interface ? 1 : 0;
my $link1_mac = $anvil->data->{variables}{form}{config_step2}{$link1_key}{value};
my $link2_mac = defined $anvil->data->{variables}{form}{config_step2}{$link2_key}{value} ? $anvil->data->{variables}{form}{config_step2}{$link2_key}{value} : "";
my $old_link1_iface = $anvil->data->{sys}{mac}{$link1_mac}{iface} ? $anvil->data->{sys}{mac}{$link1_mac}{iface} : "";
my $old_link2_iface = $link2_mac ? $anvil->data->{sys}{mac}{$link2_mac}{iface} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ip_key => $ip_key,
is_gateway => $is_gateway,
@ -251,7 +251,15 @@ sub reconfigure_network
}});
# Skip if this doesn't exist or isn't a valid IPv4 address.
next if not exists $anvil->data->{variables}{form}{config_step2}{$ip_key}{value};
if (not exists $anvil->data->{variables}{form}{config_step2}{$ip_key}{value})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0176", variables => { ip_key => $ip_key }});
next;
}
else
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "variables::form::config_step2::${ip_key}::value" => $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.
@ -269,10 +277,11 @@ sub reconfigure_network
subnet => $subnet,
}});
# Are we building bonded interfaces?
if ($anvil->Validate->is_mac({mac => $link2_mac}))
{
### TODO: Handle when bridges exist. Detect when the host is a node and/or have a "use as bridge" option?
# Bonded; Build the configs.
# Yup! Build the configs.
my $say_network = "";
my $say_interface = "";
my $interface_prefix = "";
@ -494,9 +503,111 @@ sub reconfigure_network
}
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 interface
# Single interface, set it up
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 }});
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 $say_defroute = $is_gateway ? "yes" : "no";
my $cidr = $anvil->Convert->cidr({subnet => $subnet});
my $new_link1_file = $anvil->data->{path}{directories}{ifcfg}."/ifcfg-".$interface_prefix."_".$network_count."_-_Link_1";
my $old_link1_file = $new_link1_file;
my $new_link1_iface = $say_interface."_link1";
if ((exists $anvil->data->{sys}{mac}{$link1_mac}{iface}) && ($anvil->data->{sys}{mac}{$link1_mac}{iface}))
{
$old_link1_file = $anvil->data->{path}{directories}{ifcfg}."/ifcfg-".$anvil->data->{sys}{mac}{$link1_mac}{iface};
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_defroute => $say_defroute,
cidr => $cidr,
new_link1_file => $new_link1_file,
old_link1_file => $old_link1_file,
new_link1_iface => $new_link1_iface,
}});
# Gather (or create) UUIDs
my $link1_uuid = get_uuid_from_interface_file($anvil, $old_link1_file);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { link1_uuid => $link1_uuid }});
my $link1_config = "# $say_network - Link 1\n";
$link1_config .= "HWADDR=\"".uc($link1_mac)."\"\n";
$link1_config .= "UUID=\"".$link1_uuid."\"\n";
$link1_config .= "NAME=\"".$interface_prefix." ".$network_count." - Link 1\"\n";
$link1_config .= "DEVICE=\"".$new_link1_iface."\"\n";
$link1_config .= "TYPE=\"Ethernet\"\n";
$link1_config .= "BOOTPROTO=\"none\"\n";
$link1_config .= "IPV6INIT=\"no\"\n";
$link1_config .= "ONBOOT=\"yes\"\n";
$link1_config .= "IPADDR=\"".$ip."\"\n";
$link1_config .= $cidr ? "PREFIX=\"".$cidr."\"\n" : "NETMASK=\"".$subnet."\"\n";
if ($is_gateway)
{
$link1_config .= "GATEWAY=\"".$gateway."\"\n";
for (my $i = 0; $i < @{$dns}; $i++)
{
$link1_config .= "DNS".($i+1)."=\"".$dns->[$i]."\"\n";
}
}
$link1_config .= "DEFROUTE=\"".$say_defroute."\"\n";
$link1_config .= "USERCTL=\"no\"\n";
$link1_config .= "MTU=\"1500\"\n"; # TODO: Make the MTU user-adjustable
$link1_config .= "NM_CONTROLLED=\"yes\"\n";
$link1_config .= "ZONE=\"".$say_interface."\"";
# Backup the existing link1 file, if it exists.
if (-e $old_link1_file)
{
$anvil->Storage->backup({debug => 2, file => $old_link1_file});
}
# Write out the link1 config file.
$anvil->Storage->write_file({file => $new_link1_file, body => $link1_config, user => "root", group => "root", mode => "0644", overwrite => 1});
if ($old_link1_iface)
{
# Take down and rename the old link 1 interface
#print "Downing: ..... [$old_link1_iface]\n";
#$anvil->System->call({shell_call => $anvil->data->{path}{exe}{ifdown}." ".$old_link1_iface});
#print "Disconnecting: [$old_link1_iface]\n";
#$anvil->System->call({shell_call => $anvil->data->{path}{exe}{ip}." link set ".$old_link1_iface." down"});
}
if ($old_link1_iface ne $new_link1_iface)
{
# Rename it
#print "Renaming: .... [$old_link1_iface] -> [$new_link1_iface]\n";
#$anvil->System->call({shell_call => $anvil->data->{path}{exe}{ip}." link set ".$old_link1_iface." name ".$new_link1_iface});
# Unllnk the old one, if it exists.
if (-e $old_link1_file)
{
#print "Deleting: .... [$old_link1_file]\n";
unlink $old_link1_file;
}
}
# Drop the new link, too, in case it still has the old config
#print "Downing: ..... [$new_link1_iface]\n";
#$anvil->System->call({shell_call => $anvil->data->{path}{exe}{ifdown}." ".$new_link1_iface});
}
else
{
@ -507,6 +618,43 @@ sub reconfigure_network
}
}
# If any virtio bridges exist, remove it/them.
my $start = 0;
my $bridges = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." net-list"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridges => $bridges }});
foreach my $line (split/\n/, $bridges)
{
$line = $anvil->Words->clean_spaces({ string => $line });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /^----------/)
{
$start = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { start => $start }});
next;
}
next if not $start;
my $bridge = ($line =~ /(.*?)\s/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge => $bridge }});
$anvil->data->{virsh}{bridge}{$bridge} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "virsh::bridge::$bridge" => $anvil->data->{virsh}{bridge}{$bridge} }});
}
foreach my $bridge (sort {$a cmp $b} keys %{$anvil->data->{virsh}{bridge}})
{
# Destroy (stop) it.
my $destroy = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." net-destroy ".$bridge});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { destroy => $destroy }});
# Disable it from auto-start.
my $disable = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." net-autostart ".$bridge." --disable"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { disable => $disable }});
# Undefine (delete)
my $undefine = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." net-undefine ".$bridge});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { undefine => $undefine }});
}
### TODO: This isn't working... The route table won't set the IFN as the default route properly and
### the IFN links seem to drop out and not return when trying to fix it. For now, we'll do a
### closing reboot which seems to always comes up OK.

@ -3,7 +3,6 @@
# This is the master daemon that manages all periodically run processes on Striker dashboards and Anvil!
# nodes.
#
# TODO: Make sure to delete interfaces/bonds/bridges that disappear
#
use strict;
use warnings;

Loading…
Cancel
Save