From 6d81e03fb27d24858eb099906c2b754d6214b680 Mon Sep 17 00:00:00 2001 From: Digimer Date: Sun, 8 Dec 2019 00:19:13 -0500 Subject: [PATCH] * Created Network->match_gateway() to check if a gateway applies to a given network. * Got more work done on confirming the user's request to setup the network of a node or DR host. * Reworked network select boxes to sort by the network name instead of the MAC address. Signed-off-by: Digimer --- Anvil/Tools/Network.pm | 86 +++++++++- cgi-bin/striker | 292 ++++++++++++++++++++++++++++++---- html/skins/alteeve/anvil.html | 146 ++++++++++++++++- html/skins/alteeve/main.css | 6 + share/words.xml | 49 ++++-- tools/anvil-configure-host | 6 +- tools/anvil-daemon | 2 +- tools/anvil-update-states | 6 +- tools/test.pl | 206 ++---------------------- 9 files changed, 536 insertions(+), 263 deletions(-) diff --git a/Anvil/Tools/Network.pm b/Anvil/Tools/Network.pm index f9c703b5..540e4c23 100755 --- a/Anvil/Tools/Network.pm +++ b/Anvil/Tools/Network.pm @@ -7,6 +7,7 @@ use strict; use warnings; use Data::Dumper; use Scalar::Util qw(weaken isweak); +use Net::Netmask; our $VERSION = "3.0.0"; my $THIS_FILE = "Network.pm"; @@ -22,6 +23,7 @@ my $THIS_FILE = "Network.pm"; # is_local # load_interfces # load_ips +# match_gateway # ping =pod @@ -1945,11 +1947,85 @@ sub is_local return($anvil->data->{cache}{is_local}{$host}); } -# =head3 -# -# Private Functions; -# -# =cut +=head2 match_gateway + +This takes a gateway and the IP address / subnet mask and sees if the gateway matches that network. If it does, it returns C<< 1 >>. If the gateway doesn't match the network, C<< 0 >> is returned. + +B<< Note >>: This can be used to test if any given IP is within subnet, of course. The name comes from the primary use of this method. + +Parameters + +=head3 gateway (required) + +This is the gateway IP address being analyzed. + +=head3 ip_address (required) + +This is the IP address that will be paired with the subnet mask to see if the gateway matches. + +=head3 subnet_mask (required) + +This is the subnet mask paired against the IP address used to check the gateway against. + +=cut +sub match_gateway +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + + my $gateway = defined $parameter->{gateway} ? $parameter->{gateway} : ""; + my $ip_address = defined $parameter->{ip_address} ? $parameter->{ip_address} : ""; + my $subnet_mask = defined $parameter->{subnet_mask} ? $parameter->{subnet_mask} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + gateway => $gateway, + ip_address => $ip_address, + subnet_mask => $subnet_mask, + }}); + + if (not $ip_address) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->match_gateway()", parameter => "ip_address" }}); + return(0); + } + elsif (not $anvil->Validate->is_ipv4({ip => $ip_address})) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "warning_0019", variables => { parameter => "ip_address", ip_address => $ip_address }}); + return(0); + } + if (not $gateway) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->match_gateway()", parameter => "gateway" }}); + return(0); + } + elsif (not $anvil->Validate->is_ipv4({ip => $gateway})) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "warning_0019", variables => { parameter => "gateway", ip_address => $gateway }}); + return(0); + } + if (not $subnet_mask) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->match_gateway()", parameter => "subnet_mask" }}); + return(0); + } + elsif (not $anvil->Validate->is_subnet_mask({subnet_mask => $subnet_mask})) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "warning_0020", variables => { parameter => "subnet_mask", subnet_mask => $subnet_mask }}); + return(0); + } + + my $match = 0; + my $block = Net::Netmask->new($ip_address."/".$subnet_mask); + if ($block->match($gateway)) + { + # This is a match! + $match = 1; + } + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { match => $match }}); + return($match); +} =head2 ping diff --git a/cgi-bin/striker b/cgi-bin/striker index 1f4039ec..dd906946 100755 --- a/cgi-bin/striker +++ b/cgi-bin/striker @@ -725,6 +725,7 @@ sub process_prep_network $anvil->data->{cgi}{task}{value} = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::task::value" => $anvil->data->{cgi}{task}{value} }}); process_anvil_menu($anvil); + return(0); } # Pull the host's data out of the JSON file. @@ -733,7 +734,7 @@ sub process_prep_network my $host_name = ""; foreach my $host (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}}) { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "cgi::host_uuid::value" => $anvil->data->{cgi}{host_uuid}{value}, "json::all_status::hosts::${host}::host_uuid" => $anvil->data->{json}{all_status}{hosts}{$host}{host_uuid}, }}); @@ -741,21 +742,242 @@ sub process_prep_network { # Found it. $host_name = $host; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { host_name => $host_name }}); last; } } - if (not $host_name) { # Didn't find it. - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0014", variables => { host_uuid => $anvil->data->{cgi}{host_uuid}{value} } }) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0014", variables => { host_uuid => $anvil->data->{cgi}{host_uuid}{value} } }) }}); $anvil->data->{cgi}{task}{value} = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::task::value" => $anvil->data->{cgi}{task}{value}, "form::error_massage" => $anvil->data->{form}{error_massage}, }}); process_anvil_menu($anvil); + return(0); + } + + # Are we saving? + if ($anvil->data->{cgi}{save}{value} eq "true") + { + # Is the form sane? + my $sane = 1; + + # Not yet, ask the user to confirm. + my $interfaces = ""; + my $error = 0; + my $gateway_interface = ""; + if ($anvil->data->{cgi}{gateway}{value}) + { + # Is if valid? + if (not $anvil->Validate->is_ipv4({ip => $anvil->data->{cgi}{gateway}{value}})) + { + # Bad IP + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0010", variables => { ip_address => $anvil->data->{cgi}{gateway}{value} }}) }}); + $anvil->data->{cgi}{gateway}{alert} = 1; + } + } + if ($anvil->data->{cgi}{dns}{value}) + { + foreach my $dns (split/,/, $anvil->data->{cgi}{dns}{value}) + { + $dns =~ s/^\s+//; + $dns =~ s/\s+$//; + if (not $anvil->Validate->is_ipv4({ip => $dns})) + { + # Bad IP + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0010", variables => { ip_address => $anvil->data->{cgi}{dns}{value} }}) }}); + $anvil->data->{cgi}{dns}{alert} = 1; + } + last if $anvil->data->{cgi}{dns}{alert}; + } + } + foreach my $network ("bcn", "sn", "ifn") + { + my $count_key = $network."_count"; + my $loops = $anvil->data->{cgi}{$count_key}{value}; + foreach my $i (1..$loops) + { + my $bridge_key = $network.$i."_create_bridge"; + my $ip_key = $network.$i."_ip"; + my $subnet_key = $network.$i."_subnet_mask"; + my $link1_key = $network.$i."_link1_mac_to_set"; + my $link2_key = $network.$i."_link2_mac_to_set"; + my $say_network = $anvil->Words->string({key => "striker_0018", variables => { number => $i }}); + if ($network eq "sn") + { + $say_network = $anvil->Words->string({key => "striker_0020", variables => { number => $i }}); + } + elsif ($network eq "ifn") + { + $say_network = $anvil->Words->string({key => "striker_0022", variables => { number => $i }}); + } + my $link1_interface = ""; + my $link2_interface = ""; + foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}}) + { + my $mac_address = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface}{mac_address}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + interface => $interface, + mac_address => $mac_address, + }}); + if ($mac_address eq $anvil->data->{cgi}{$link1_key}{value}) + { + $link1_interface = $interface; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { link1_interface => $link1_interface }}); + } + elsif ($mac_address eq $anvil->data->{cgi}{$link2_key}{value}) + { + $link2_interface = $interface; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { link2_interface => $link2_interface }}); + } + last if (($link1_interface) && ($link2_interface)); + } + my $say_bridge = "#!string!unit_0002!#"; + if ($anvil->data->{cgi}{$bridge_key}{value}) + { + # We're making a bridge. + $say_bridge = "#!string!unit_0001!#"; + } + my $say_ip_address = "#!string!striker_0152!#"; + if (($anvil->data->{cgi}{$ip_key}{value}) && (not $anvil->Validate->is_ipv4({ip => $anvil->data->{cgi}{$ip_key}{value}}))) + { + # Bad IP + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0010", variables => { ip_address => $anvil->data->{cgi}{$ip_key}{value} }}) }}); + $anvil->data->{cgi}{$ip_key}{alert} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "form::error_massage" => $anvil->data->{form}{error_massage}, + "cgi::${ip_key}::alert" => $anvil->data->{cgi}{$ip_key}{alert}, + }}); + } + elsif (($anvil->data->{cgi}{$subnet_key}{value}) && (not $anvil->Validate->is_subnet_mask({subnet_mask => $anvil->data->{cgi}{$subnet_key}{value}}))) + { + # Bad subnet + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0017"}) }}); + $anvil->data->{cgi}{$subnet_key}{alert} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "form::error_massage" => $anvil->data->{form}{error_massage}, + "cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert}, + }}); + } + elsif (($anvil->data->{cgi}{$ip_key}{value}) && (not $anvil->data->{cgi}{$subnet_key}{value})) + { + # IP without a subnet + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0018"}) }}); + $anvil->data->{cgi}{$subnet_key}{alert} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "form::error_massage" => $anvil->data->{form}{error_massage}, + "cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert}, + }}); + } + else + { + $say_ip_address = $anvil->data->{cgi}{$ip_key}{value}."/".$anvil->data->{cgi}{$subnet_key}{value}; + + # Is this the network with the subnet mask? + if ((not $gateway_interface) && + ($anvil->data->{cgi}{gateway}{value}) && + (not $anvil->data->{cgi}{gateway}{alert}) && + ($anvil->data->{cgi}{$ip_key}{value})) + { + my $match = $anvil->Network->match_gateway({ + ip_address => $anvil->data->{cgi}{$ip_key}{value}, + subnet_mask => $anvil->data->{cgi}{$subnet_key}{value}, + gateway => $anvil->data->{cgi}{gateway}{value}, + }); + + # Found the match! + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match => $match }}); + if ($match) + { + $say_ip_address .= ", #!string!striker_0026!#: ".$anvil->data->{cgi}{$bridge_key}{value}; + + # DNS? + if (($anvil->data->{cgi}{dns}{value}) && (not $anvil->data->{cgi}{dns}{alert})) + { + $say_ip_address .= ", #!string!striker_0037!#: ".$anvil->data->{cgi}{dns}{value}; + } + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::${bridge_key}::value" => $anvil->data->{cgi}{$bridge_key}{value} }}); + if ($anvil->data->{cgi}{$bridge_key}{value}) + { + $gateway_interface = $network.$i."_bridge1"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { gateway_interface => $gateway_interface }}); + } + else + { + $gateway_interface = $network.$i."_bond1"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { gateway_interface => $gateway_interface }}); + } + } + } + } + + $interfaces .= $anvil->Template->get({file => "anvil.html", name => "interface-entry", variables => { + network => $say_network, + primary => $link1_interface." (".$anvil->data->{cgi}{$link1_key}{value}.")", + link1_key => $link1_key, + link1_value => $anvil->data->{cgi}{$link1_key}{value}, + secondary => $link2_interface." (".$anvil->data->{cgi}{$link2_key}{value}.")", + link2_key => $link2_key, + link2_value => $anvil->data->{cgi}{$link2_key}{value}, + bridge => $say_bridge, + }}); + + } + } + + # Did we see an error? + if ($anvil->data->{form}{error_massage}) + { + $sane = 0; + } + + # Confirmed? + $anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{value}; + if (($anvil->data->{cgi}{confirm}{value}) && ($sane)) + { + # Yes, save the job. + +=cut +2019/12/05 20:43:15:Get.pm:394; cgi::next::value ............... : [Next] +2019/12/05 20:43:15:Get.pm:394; cgi::step::value ............... : [step2] + + variable_name | variable_value +--------------------------------------------------+------------------------- + form::config_step2::hostname::value | m3-striker01.digimer.ca + form::config_step2::dns::value | 8.8.8.8, 8.8.4.4 + form::config_step2::ifn1_link1_mac_to_set::value | 52:54:00:9d:91:8a + form::config_step2::gateway_interface::value | ifn1 + form::config_step2::striker_user::value | admin + form::config_step2::ifn1_subnet::value | 255.255.0.0 + form::config_step2::bcn1_link1_mac_to_set::value | 52:54:00:8b:a0:a3 + form::config_step2::gateway::value | 10.255.255.254 + form::config_step2::ifn1_ip::value | 10.255.14.1 + form::config_step2::bcn1_ip::value | 10.20.14.1 + form::config_step2::bcn1_subnet::value | 255.255.0.0 + form::config_step2::striker_password::value | super secret password + form::config_step1::organization::value | Madison Kelly + form::config_step1::sequence::value | 1 + form::config_step1::domain::value | digimer.ca + form::config_step1::prefix::value | m3 + form::config_step1::ifn_count::value | 1 +=cut + } + else + { + # Show the confirmation box. + $anvil->data->{form}{back_link} = $anvil->data->{sys}{cgi_string}; + $anvil->data->{form}{back_link} =~ s/step=step2//; + $anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "config-network-confirm", variables => { + host_name => $host_name, + host_uuid => $anvil->data->{cgi}{host_uuid}{value}, + interfaces => $interfaces, + }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }}); + return(0); + } } # How many actual interfaces do we have? We need at least six. For each two above that, we'll add an @@ -765,7 +987,7 @@ sub process_prep_network foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}}) { # if any interfaces are called 'virbrX-nic', ignore it as it will be removed. Likewise, ignore any 'vnetX' devices. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { interface => $interface }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface => $interface }}); if (($interface =~ /^virbr\d+-nic/) or ($interface =~ /^vnet\d+/)) { # Ignore it. @@ -774,27 +996,23 @@ sub process_prep_network # Store the mac used in the select box my $mac_address = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface}{mac_address}; - push @{$interface_options}, $mac_address."#!#".$mac_address." (".$interface.")"; + push @{$interface_options}, $mac_address."#!#".$interface." (".$mac_address.")"; # Store the mac address . $interfaces->{$interface} = $mac_address; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "interfaces->{".$interface."}" => $interfaces->{$interface} }}); - } - - foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{interfaces}}) - { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "interfaces->{".$interface."}" => $interfaces->{$interface} }}); } # Get the interface count my $interface_count = keys %{$interfaces}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { interface_count => $interface_count }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface_count => $interface_count }}); if ($interface_count < 6) { # Not enough interfaces. - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0015", variables => { interface_count => $interface_count } }) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0015", variables => { interface_count => $interface_count } }) }}); $anvil->data->{cgi}{task}{value} = ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "cgi::task::value" => $anvil->data->{cgi}{task}{value}, "form::error_massage" => $anvil->data->{form}{error_massage}, }}); @@ -807,7 +1025,7 @@ sub process_prep_network my $sn_pair_count = 1; my $ifn_pair_count = int(($interface_count - 4) / 2); $ifn_pair_count = 1 if $ifn_pair_count < 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bcn_pair_count => $bcn_pair_count, sn_pair_count => $sn_pair_count, ifn_pair_count => $ifn_pair_count, @@ -818,7 +1036,7 @@ sub process_prep_network # until set during the Anvil! build later. foreach my $network ("bcn", "sn", "ifn") { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network => $network }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network => $network }}); my $name_key = ""; my $description_key = ""; my $count = 1; @@ -840,7 +1058,7 @@ sub process_prep_network $description_key = "striker_0023"; $count = $ifn_pair_count; } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { name_key => $name_key, description_key => $description_key, count => $count, @@ -856,7 +1074,7 @@ sub process_prep_network my $this_subnet_mask_class = $anvil->data->{cgi}{$this_subnet_mask_key}{alert} ? "input_alert" : "input_clear"; my $this_iface1_class = $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear"; my $this_iface2_class = $anvil->data->{cgi}{$this_iface2_key}{alert} ? "input_alert" : "input_clear"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { this_ip_key => $this_ip_key, this_subnet_mask_key => $this_subnet_mask_key, this_iface1_key => $this_iface1_key, @@ -873,6 +1091,7 @@ sub process_prep_network name => $this_iface1_key, options => $interface_options, blank => 1, + 'sort' => 0, selected => defined $anvil->data->{cgi}{$this_iface1_key}{value} ? $anvil->data->{cgi}{$this_iface1_key}{value} : "", class => $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear", }); @@ -880,6 +1099,7 @@ sub process_prep_network name => $this_iface2_key, options => $interface_options, blank => 1, + 'sort' => 0, selected => defined $anvil->data->{cgi}{$this_iface2_key}{value} ? $anvil->data->{cgi}{$this_iface2_key}{value} : "", class => $anvil->data->{cgi}{$this_iface2_key}{alert} ? "input_alert" : "input_clear", }); @@ -898,6 +1118,8 @@ sub process_prep_network subnet_mask_class => $this_subnet_mask_class, iface1_select => $this_iface1_form, iface2_select => $this_iface2_form, + network_name => $network.$i, + create_bridge => $network eq "sn" ? 0 : 1, }}); } } @@ -952,7 +1174,11 @@ sub process_prep_network gateway_form => $say_gateway, dns_form => $say_dns, host_name_form => $say_host_name, - host_name => $host_name, # This is the current host name, used to find the data in the all_status.json + bcn_count => $bcn_pair_count, + sn_count => $sn_pair_count, + ifn_count => $ifn_pair_count, + host_uuid => $anvil->data->{cgi}{host_uuid}{value}, + host_name => $host_name, # This is the current host name, used to find the data in the all_status.json }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }}); @@ -1054,12 +1280,12 @@ sub process_prep_host_page if (not $anvil->Validate->is_ipv4({ip => $host_ip_address})) { # Bad IP - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0010"}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0010", variables => { ip_address => $host_ip_address }}) }}); } elsif (($ssh_port < 1) or ($ssh_port > 65535)) { # Bad port - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0011"}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0011"}) }}); } else { @@ -1171,7 +1397,7 @@ sub process_prep_host_page $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bad_line => $bad_line }}); } } - my $error_message = $anvil->Words->string({key => "striker_warning_0013", variables => { + my $error_message = $anvil->Words->string({key => "warning_0013", variables => { file => $bad_file, line => $bad_line, }}); @@ -1181,12 +1407,12 @@ sub process_prep_host_page else { # Nope, some other issue - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0012"}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0012"}) }}); } } elsif (not $target_host_uuid) { - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0005", variables => { uuid => $target_host_uuid }}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0005", variables => { uuid => $target_host_uuid }}) }}); } else { @@ -1300,7 +1526,7 @@ sub process_install_target else { # Just ignore it, someone's mucking with the subask value. - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0009"}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0009"}) }}); } return(0); @@ -1757,7 +1983,7 @@ sub add_sync_peer if (((not $is_domain) && (not $is_ipv4)) or ($pgsql_port < 1) or ($pgsql_port > 65536)) { # Bad host. - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0002"}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0002"}) }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage}, }}); @@ -1788,7 +2014,7 @@ sub add_sync_peer if ((not $connected) or (not $peer_host_uuid)) { - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0005", variables => { uuid => $peer_host_uuid }}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0005", variables => { uuid => $peer_host_uuid }}) }}); } # Lastly, if bi-directional is set, make sure we have a way to talk to it. @@ -1802,7 +2028,7 @@ sub add_sync_peer if ((not $use_ip) or ($use_ip eq "!!error!!")) { # Can't do bi-directional - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0008", variables => { host => $host }}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0008", variables => { host => $host }}) }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::error_massage" => $anvil->data->{form}{error_massage}, }}); @@ -1834,7 +2060,7 @@ sub add_sync_peer if ($db_access ne "1") { # Failed to connect. - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0004"}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0004"}) }}); } # Delete the pgpass file. @@ -2216,7 +2442,7 @@ ORDER BY # If the IP is going to change, warn the user. if (not $matched_ip) { - $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "striker_warning_0001"}) }}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "warning_0001"}) }}); } # We don't need to store anything as hidden variables, we'll read it back from the database later. @@ -2225,7 +2451,7 @@ ORDER BY step1_welcome_message_id => "", organization => $anvil->data->{cgi}{organization}{value}, prefix => $anvil->data->{cgi}{prefix}{value}, - host_name => $anvil->data->{cgi}{host_name}{value}, + host_name => $anvil->data->{cgi}{host_name}{value}, striker_user => $anvil->data->{cgi}{striker_user}{value}, striker_password => $anvil->data->{cgi}{striker_password}{value}, networks => $networks, @@ -2304,7 +2530,7 @@ ORDER BY foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{interfaces}}) { my $this_mac = $anvil->data->{interfaces}{$interface}{mac}; - push @{$interface_options}, $this_mac."#!#".$this_mac." (".$interface.")"; + push @{$interface_options}, $this_mac."#!#".$interface." (".$this_mac.")"; } my $problem = 0; @@ -2337,6 +2563,7 @@ ORDER BY name => $this_iface1_key, options => $interface_options, blank => 1, + 'sort' => 0, selected => defined $anvil->data->{cgi}{$this_iface1_key}{value} ? $anvil->data->{cgi}{$this_iface1_key}{value} : "", class => $anvil->data->{cgi}{$this_iface1_key}{alert} ? "input_alert" : "input_clear", }); @@ -2344,6 +2571,7 @@ ORDER BY name => $this_iface2_key, options => $interface_options, blank => 1, + 'sort' => 0, selected => defined $anvil->data->{cgi}{$this_iface2_key}{value} ? $anvil->data->{cgi}{$this_iface2_key}{value} : "", class => $anvil->data->{cgi}{$this_iface2_key}{alert} ? "input_alert" : "input_clear", }); diff --git a/html/skins/alteeve/anvil.html b/html/skins/alteeve/anvil.html index a8308b1d..e42ec82e 100644 --- a/html/skins/alteeve/anvil.html +++ b/html/skins/alteeve/anvil.html @@ -63,11 +63,13 @@ #!variable!field!#: + - #!variable!description!# + #!variable!description!#
+ #!string!prefix_0006!#: #!string!striker_0145!# @@ -76,7 +78,6 @@ -   @@ -94,7 +95,6 @@ -   @@ -199,21 +199,155 @@ + - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+   +
+ #!string!striker_0146!# +
+   +
+ #!string!striker_0147!# +
+
+
+ #!string!striker_0016!# + + #!variable!host_name!# +
+ +
+
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + #!variable!interfaces!# +
+ + #!string!striker_0148!# +
+ + #!string!striker_0149!# + + + #!string!striker_0029!# + + + #!string!striker_0030!# + + + #!string!striker_0150!# + + + #!string!striker_0151!# +
+
+
+
+ +
+
+
+ +
+
+ + + + + + + #!variable!network!# + + + + + #!variable!primary!# + + + + + #!variable!secondary!# + + + + + #!variable!ip_address!# + + + + + #!variable!bridge!# + + + + diff --git a/html/skins/alteeve/main.css b/html/skins/alteeve/main.css index c39e72fd..c144a515 100644 --- a/html/skins/alteeve/main.css +++ b/html/skins/alteeve/main.css @@ -381,6 +381,12 @@ tr.data_row { font-size: 0.9em; } +.notice { + font-size: 1.0em; + font-weight: bold; + font-style: italic; +} + .warning { color: #dc9012; font-size: 1.1em; diff --git a/share/words.xml b/share/words.xml index fcadf7c6..10f9caea 100644 --- a/share/words.xml +++ b/share/words.xml @@ -987,9 +987,17 @@ If you are comfortable that the target has changed for a known reason, you can s ]]>Indicates when the last time the networks connected to this host were scanned. The scan is done to help find the IP addresses assigned to hosted servers and virtual machine equipment. The scan is a simple, sequential nmap ping scan in an attempt to be as non-invasive as possible. The frequency of these scans can be controlled by setting 'network-scan::scan-period' to a number of seconds (the current value is: [#!data!network-scan::scan-period!# seconds]).Configure the network interfaces for this host. - This step renames the real network interfaces, pairs them into redundant bonds and creates brodges for connecting to hosted servers. IPs and host names are optional, and can be set when assembling this host into an Anvil! system. +
IPs and host names are optional, and can be set when assembling this host into an Anvil! system later.]]>
If you would like to change the host name now, you can do so here. When adding this machine to an Anvil!, the host name will be set there as well making this optional.This is the network gateway used to access the outside world. We'll match it to the appropriate network interface. + If left blank, the interface will be configured for DHCP. + Confirm network configuration. + If you confirm, the host will enter maintenance mode, reconfigure its network and reboot. + Network Plan + Network + Address + Bridged? + ]]>#!variable!number!#/sec @@ -1052,6 +1060,9 @@ If you are comfortable that the target has changed for a known reason, you can s [ Error ] - [ Warning ] - [ Note ] - + Error + Warning + NoteConfigure Network @@ -1129,23 +1140,27 @@ Failure! The return code: [#!variable!return_code!#] was received ('0' was expec Unable to find a matching network, skipping this database.Something went wrong adding this database. Please see: [#!data!path::log::main!#] for details. - - The IP address will change. You will need to reconnect after applying these changes. - The access information appears to not be valid. - Test access to the peer (using SSH) failed. There may be details in the log file. - Accessing the peer over SSH worked, but a test connection to the database failed. - There was a problem reading the peer's UUID. Read: [#!variable!uuid!#], which appears to be invalid. - An SSH connection was established to: [#!variable!target!#], but we failed to establish a channel. The last error was: [#!variable!error!#]. - The job: [#!variable!command!#] was picked up by: [#!variable!pid!#], but that process is not running and it appears to only be: [#!variable!percent!# %] complete. Restarting the job. - Unable to find a local IP on the same subnet as the IP/host: [#!variable!host!#] given for the target. Bi-directional setup not currently possible. - The subtask request for manipulating the 'Install Target' feature is not valid. It should be 'enabled' or 'disabled' - The IP address is not a valid IPv4 address - The SSH port is not a valid (usually it is 22, but it has to be between 1 ~ 65536) - Failed to log into the host. Is the IP or root user's password right? - Click here to resolve.]]> - The host UUID: [#!variable!host_uuid!#] was not found in the #!data!path::json::all_status!# file on the local dashboard. - To configure a host as either an Anvil! node or a disaster recovery host, there must be at least 6 network interfaces. This machine only has: [#!variable!interface_count!#] interfaces. + + The IP address will change. You will need to reconnect after applying these changes. + The access information appears to not be valid. + Test access to the peer (using SSH) failed. There may be details in the log file. + Accessing the peer over SSH worked, but a test connection to the database failed. + There was a problem reading the peer's UUID. Read: [#!variable!uuid!#], which appears to be invalid. + An SSH connection was established to: [#!variable!target!#], but we failed to establish a channel. The last error was: [#!variable!error!#]. + The job: [#!variable!command!#] was picked up by: [#!variable!pid!#], but that process is not running and it appears to only be: [#!variable!percent!# %] complete. Restarting the job. + Unable to find a local IP on the same subnet as the IP/host: [#!variable!host!#] given for the target. Bi-directional setup not currently possible. + The subtask request for manipulating the 'Install Target' feature is not valid. It should be 'enabled' or 'disabled' + The IP address: [#!variable!ip_address!#] is not a valid IPv4 address + The SSH port is not a valid (usually it is 22, but it has to be between 1 ~ 65536) + Failed to log into the host. Is the IP or root user's password right? + Click here to resolve.]]> + The host UUID: [#!variable!host_uuid!#] was not found in the #!data!path::json::all_status!# file on the local dashboard. + To configure a host as either an Anvil! node or a disaster recovery host, there must be at least 6 network interfaces. This machine only has: [#!variable!interface_count!#] interfaces.No databases are available. Changes to the network interfaces will be cached. + The subnet mask is not valid + The IP address was specified, but the subnet mask was not + The passed in parameter '#!variable!parameter!#': [#!variable!ip_address!#] is not a valid IPv4 address. + The passed in parameter '#!variable!parameter!#': [#!variable!subnet_mask!#] is not a valid IPv4 subnet mask.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). diff --git a/tools/anvil-configure-host b/tools/anvil-configure-host index 5a835550..779f438b 100755 --- a/tools/anvil-configure-host +++ b/tools/anvil-configure-host @@ -47,7 +47,7 @@ if (($< != 0) && ($> != 0)) } # Connect -$anvil->Database->connect; +$anvil->Database->connect(); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "message_0031"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); if (not $anvil->data->{sys}{database}{connections}) @@ -72,7 +72,7 @@ $anvil->Database->insert_or_update_variables({ variable_default => "", variable_description => "striker_0048", variable_section => "system", - variable_source_uuid => $anvil->Get->host_uuid, + variable_source_uuid => $anvil->data->{sys}{host_uuid}, variable_source_table => "hosts", }); @@ -813,7 +813,7 @@ LIKE AND variable_source_table = 'hosts' AND - variable_source_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." + variable_source_uuid = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid})." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }}); diff --git a/tools/anvil-daemon b/tools/anvil-daemon index 06dbbedf..314de377 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -1293,7 +1293,7 @@ sub run_jobs if ($anvil->data->{lost_job_count}{$job_uuid} > 5) { # The previous job is gone, but the job isn't finished. Start it again. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "striker_warning_0007", variables => { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "warning_0007", variables => { command => $job_command, pid => $job_picked_up_by, percent => $job_progress, diff --git a/tools/anvil-update-states b/tools/anvil-update-states index af07bc6e..431d08db 100755 --- a/tools/anvil-update-states +++ b/tools/anvil-update-states @@ -71,7 +71,7 @@ sub process_interface_cache { next if $line =~ /^#/; my ($interface, $timestamp, $mac_address, $speed, $link_state, $operational) = (split/,/, $line); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface => $interface, timestamp => $timestamp, speed => $speed, @@ -99,14 +99,14 @@ sub process_interface_cache # seen. If so, the coming scan will add it and this cache should flush out # next time. $anvil->data->{cache}{new_file} .= $line."\n"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cache::new_file" => $anvil->data->{cache}{new_file} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "cache::new_file" => $anvil->data->{cache}{new_file} }}); } } else { # No database, re-cache $anvil->data->{cache}{new_file} .= $line."\n"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cache::new_file" => $anvil->data->{cache}{new_file} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "cache::new_file" => $anvil->data->{cache}{new_file} }}); } } } diff --git a/tools/test.pl b/tools/test.pl index 0507138e..7346edd4 100755 --- a/tools/test.pl +++ b/tools/test.pl @@ -8,6 +8,7 @@ use XML::Simple; use JSON; use Math::BigInt; use Data::Dumper; +use Net::Netmask; my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; @@ -27,207 +28,20 @@ $anvil->Log->level({set => 2}); $anvil->Database->connect({debug => 3, check_if_configured => 1}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); -my $utc_tz = $anvil->Get->date_and_time({use_utc => 1}); - $utc_tz =~ s/\//-/g; -print "DB Timestamp; [".$anvil->data->{sys}{database}{timestamp}."]\n"; -print "GM Timestamp; [".$utc_tz."]\n"; -die; +my $ip = "10.255.4.1"; +my $subnet = "255.255.0.0"; +my $test1 = "10.255.255.254"; +my $test2 = "10.200.255.254"; -#$anvil->System->generate_state_json({debug => 3}); -#$anvil->Striker->parse_all_status_json({debug => 3}); - -#print Dumper $anvil->data->{json}{all_status}{hosts}{'el8-a01n01.digimer.ca'}; - -foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}}) +my $block = Net::Netmask->new($ip."/".$subnet); +foreach my $this_gw ($test1, $test2) { - print "\n"; - print "Host: [".$host_name." (".$anvil->data->{json}{all_status}{hosts}{$host_name}{short_host_name}.")], Type: [".$anvil->data->{json}{all_status}{hosts}{$host_name}{type}."], Configured: [".$anvil->data->{json}{all_status}{hosts}{$host_name}{configured}."], \n"; - #print " - Host UUID: ..... [".$anvil->data->{json}{all_status}{hosts}{$host_name}{host_uuid}."]\n"; - #print " - SSH Fingerprint: [".$anvil->data->{json}{all_status}{hosts}{$host_name}{ssh_fingerprint}."]\n"; - - foreach my $interface_name (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}}) - { - my $uuid = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{uuid}; - my $mtu = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{mtu}." ".$anvil->Words->string({key => "suffix_0014"}); - my $bridge_id = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{bridge_id}; - my $stp_enabled = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{stp_enabled}; - my $ip = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{ip}; - my $subnet_mask = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{subnet_mask}; - my $default_gateway = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{default_gateway}; - my $gateway = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{gateway}; - my $dns = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{dns}; - print "- Bridge: [".$interface_name."], MTU: [".$mtu."], ID: [".$bridge_id."], STP: [".$stp_enabled."]\n"; - if ($ip) - { - if ($gateway) - { - print " - IP: [".$ip."/".$subnet_mask."], Gateway (default?): [".$gateway." (".$default_gateway.")], DNS: [".$dns."]\n"; - } - else - { - print " - IP: [".$ip."/".$subnet_mask."]\n"; - } - } - else - { - print " - No IP on this bridge\n"; - } - - my $connected_interfaces = keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{connected_interfaces}}; - if ($connected_interfaces) - { - print "==[ Interfaces connected to this bridge ]==\n"; - foreach my $connected_interface (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{connected_interfaces}}) - { - my $type = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bridge}{$interface_name}{connected_interfaces}{$connected_interface}{type}; - if ($type eq "bond") - { - show_bond($anvil, $host_name, $connected_interface); - } - else - { - show_interface($anvil, $host_name, $connected_interface); - } - } - print "===========================================\n"; - } - else - { - print "==[ Nothing connected to this bridge ]===\n"; - } - $anvil->data->{json}{all_status}{hosts}{$host_name}{shown}{$interface_name} = 1; - } - - # Print the rest of the interfaces now. - foreach my $interface_name (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}}) - { - next if $anvil->data->{json}{all_status}{hosts}{$host_name}{shown}{$interface_name}; - show_bond($anvil, $host_name, $interface_name, ""); - } - - foreach my $interface_name (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}}) - { - next if $anvil->data->{json}{all_status}{hosts}{$host_name}{shown}{$interface_name}; - show_interface($anvil, $host_name, $interface_name, ""); - } -} - -$anvil->nice_exit({exit_code => 0}); - -sub show_bond -{ - my ($anvil, $host_name, $interface_name) = @_; - - print "Bond: [".$interface_name."]\n"; - my $uuid = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{uuid}; - my $mtu = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{mtu}." ".$anvil->Words->string({key => "suffix_0014"}); - my $ip = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{ip}; - my $subnet_mask = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{subnet_mask}; - my $default_gateway = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{default_gateway}; - my $gateway = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{gateway}; - my $dns = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{dns}; - my $mode = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{mode}; - my $active_interface = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{active_interface}; - my $primary_interface = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{primary_interface}; - my $primary_reselect = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{primary_reselect}; - my $up_delay = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{up_delay}; - my $down_delay = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{down_delay}; - my $operational = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{operational}; - my $mii_polling_interval = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{mii_polling_interval}; - my $bridge_name = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{bridge_name}; - my $say_up_delay = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{say_up_delay}; - my $say_down_delay = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{say_down_delay}; - my $say_mode = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{say_mode}; - my $say_operational = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{say_operational}; - my $say_primary_reselect = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{say_primary_reselect}; - - print "- Bond: [".$interface_name."], Mode: [".$say_mode." (".$mode.")], MTU: [".$mtu."], Operational: [".$say_operational." (".$operational.")], Bridge: [".$bridge_name."]\n"; - print " Active interface: [".$active_interface."], Primary interface: [".$primary_interface."], Primary reselect policy: [".$say_primary_reselect." (".$primary_reselect.")]\n"; - print " Up delay: [".$say_up_delay." (".$up_delay.")], Down delay: [".$say_down_delay." (".$down_delay.")], MII polling interval: [".$mii_polling_interval."]\n"; - if ($ip) - { - if ($gateway) - { - print " - IP: [".$ip."/".$subnet_mask."], Gateway (default?): [".$gateway." (".$default_gateway.")], DNS: [".$dns."]\n"; - } - else - { - print " - IP: [".$ip."/".$subnet_mask."]\n"; - } - } - else - { - print " - No IP on this bond\n"; - } - - my $connected_interfaces = keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{connected_interfaces}}; - if ($connected_interfaces) - { - print "--[ Interfaces connected to this bond ]----\n"; - foreach my $connected_interface (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{bond}{$interface_name}{connected_interfaces}}) - { - show_interface($anvil, $host_name, $connected_interface); - } - print "-------------------------------------------"; - } - else - { - print "--[ Nothing connected to this bond ]-----\n"; - } - - print "\n"; - $anvil->data->{json}{all_status}{hosts}{$host_name}{shown}{$interface_name} = 1; - - return(0); -} - -sub show_interface -{ - my ($anvil, $host_name, $interface_name) = @_; - print "Interface: [".$interface_name."]\n"; - - my $uuid = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{uuid}; - my $mtu = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{mtu}." ".$anvil->Words->string({key => "suffix_0014"}); - my $ip = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{ip}; - my $subnet_mask = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{subnet_mask}; - my $default_gateway = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{default_gateway}; - my $gateway = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{gateway}; - my $dns = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{dns}; - my $speed = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{speed}; - my $link_state = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{link_state}; - my $operational = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{operational}; - my $duplex = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{duplex}; - my $medium = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{medium}; - my $bridge_name = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{bridge_name}; - my $bond_name = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{bond_name}; - my $changed_order = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{changed_order}; - my $say_speed = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{say_speed}; - my $say_duplex = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{say_duplex}; - my $say_link_state = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{say_link_state}; - my $say_operational = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{say_operationa}; - my $say_medium = $anvil->data->{json}{all_status}{hosts}{$host_name}{network_interface}{interface}{$interface_name}{say_medium}; - - print "- Interface: [".$interface_name."], MTU: [".$mtu."], Operational: [".$say_operational." (".$operational.")], Link state: [".$say_link_state." (".$link_state.")]\n"; - print " Change Order: [".$changed_order."], Speed: [".$say_speed." (".$speed.")], Duplex: [".$say_duplex." (".$duplex.")], Medium: [".$say_medium." (".$medium.")]\n"; - print " Connected to bond: [".$bond_name."], bridge: [".$bridge_name."]\n"; - if ($ip) + if ($block->match($this_gw)) { - if ($gateway) - { - print " - IP: [".$ip."/".$subnet_mask."], Gateway (default?): [".$gateway." (".$default_gateway.")], DNS: [".$dns."]\n"; - } - else - { - print " - IP: [".$ip."/".$subnet_mask."]\n"; - } + print "The gateway: [".$this_gw."] DOES apply to: [".$ip."/".$subnet."]\n"; } else { - print " - No IP on this interface\n"; + print "The gateway: [".$this_gw."] DOES NOT apply to: [".$ip."/".$subnet."]\n"; } - - print "\n"; - $anvil->data->{json}{all_status}{hosts}{$host_name}{shown}{$interface_name} = 1; - - return(0); }