From 90f5bf49d52e8ae686a02937e335bf188a8918bb Mon Sep 17 00:00:00 2001 From: Digimer Date: Tue, 3 Dec 2019 00:30:26 -0500 Subject: [PATCH] * Updated Network->load_interfces() to only assign a 'changed_order' to real interfaces. * Fixed a bug in System->generate_state_json() where interfaces connected to a bridge were constantly having their 'network_interface_bond_uuid' cleared and reset. * Finished (for now) the jquery code to update the network interface list when preparing the network interface configuration of a new node or DR host. Signed-off-by: Digimer --- Anvil/Tools/Network.pm | 19 ++-- Anvil/Tools/System.pm | 2 +- html/skins/alteeve/anvil.html | 12 ++- html/skins/alteeve/anvil.js | 75 ++++++++++--- tools/anvil-daemon | 15 +-- tools/anvil-update-states | 197 ++++++++++++++-------------------- tools/test.pl | 19 +++- 7 files changed, 182 insertions(+), 157 deletions(-) diff --git a/Anvil/Tools/Network.pm b/Anvil/Tools/Network.pm index 66b3e34c..8ea82c6a 100755 --- a/Anvil/Tools/Network.pm +++ b/Anvil/Tools/Network.pm @@ -994,7 +994,7 @@ AND ORDER BY modified_date DESC ;"; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0124", variables => { query => $query }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }}); $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); $count = @{$results}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { @@ -1017,6 +1017,15 @@ ORDER BY my $network_interface_bridge_uuid = defined $row->[10] ? $row->[10] : ""; my $bond_name = ""; my $bridge_name = ""; + my $this_change_orger = 0; + if (($network_interface_name =~ /^virbr/) or ($network_interface_name =~ /^vnet/)) + { + # This isn't a physical NIC, so it doesn't get a changed order + } + else + { + $this_change_orger = $changed_order++; + } if (($network_interface_bond_uuid) && (defined $anvil->data->{network}{$host}{bond_uuid}{$network_interface_bond_uuid}{name})) { $bond_name = $anvil->data->{network}{$host}{bond_uuid}{$network_interface_bond_uuid}{name}; @@ -1048,10 +1057,9 @@ ORDER BY network_interface_bond_uuid => $network_interface_bond_uuid, network_interface_bridge_uuid => $network_interface_bridge_uuid, bond_name => $bond_name, - changed_order => $changed_order, + changed_order => $this_change_orger, }}); - # We'll initially load empty strings for what would be the IP information. Any interface with IPs will be populated when we call $anvil->data->{network}{$host}{interface}{$network_interface_name}{uuid} = $network_interface_uuid; $anvil->data->{network}{$host}{interface}{$network_interface_name}{mac_address} = $network_interface_mac_address; @@ -1066,8 +1074,8 @@ ORDER BY $anvil->data->{network}{$host}{interface}{$network_interface_name}{bridge_uuid} = $network_interface_bridge_uuid; $anvil->data->{network}{$host}{interface}{$network_interface_name}{bridge_name} = $bridge_name; $anvil->data->{network}{$host}{interface}{$network_interface_name}{type} = "interface"; - $anvil->data->{network}{$host}{interface}{$network_interface_name}{changed_order} = $changed_order; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + $anvil->data->{network}{$host}{interface}{$network_interface_name}{changed_order} = $this_change_orger; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "network::${host}::interface::${network_interface_name}::uuid" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{uuid}, "network::${host}::interface::${network_interface_name}::mac_address" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{mac_address}, "network::${host}::interface::${network_interface_name}::speed" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{speed}, @@ -1083,7 +1091,6 @@ ORDER BY "network::${host}::interface::${network_interface_name}::type" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{type}, "network::${host}::interface::${network_interface_name}::changed_order" => $anvil->data->{network}{$host}{interface}{$network_interface_name}{changed_order}, }}); - $changed_order++; } # Load the IPs diff --git a/Anvil/Tools/System.pm b/Anvil/Tools/System.pm index e5529006..c22145cc 100644 --- a/Anvil/Tools/System.pm +++ b/Anvil/Tools/System.pm @@ -882,7 +882,7 @@ sub generate_state_json my $mtu = $anvil->data->{network}{$host}{interface}{$interface}{mtu}; my $mac_address = $anvil->data->{network}{$host}{interface}{$interface}{mac_address}; my $iface_hash = {}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "s1:interface" => $interface, "s2:mac_address" => $mac_address, "s3:type" => $type, diff --git a/html/skins/alteeve/anvil.html b/html/skins/alteeve/anvil.html index 298b6fcd..a8308b1d 100644 --- a/html/skins/alteeve/anvil.html +++ b/html/skins/alteeve/anvil.html @@ -179,7 +179,17 @@ -
+
diff --git a/html/skins/alteeve/anvil.js b/html/skins/alteeve/anvil.js index 56f4919d..e7ca4b8e 100644 --- a/html/skins/alteeve/anvil.js +++ b/html/skins/alteeve/anvil.js @@ -39,15 +39,15 @@ $( window ).on( "load", function() // Open the table var body = ''; - body += ''; - body += ''; - body += ''; - body += ''; - body += ''; - body += ''; - body += ''; - body += ''; - body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; $.each(data.hosts, function(index, element) { if (element.type === 'dashboard') { // Skip @@ -138,19 +138,68 @@ $( window ).on( "load", function() body += '
'+say_unconfigured+'   '+say_type+'   '+say_accessible+'   '+say_at_ip+'
'+say_unconfigured+'   '+say_type+'   '+say_accessible+'   '+say_at_ip+'
'; // clear + append can't be the best way to do this... - $( "#unconfigured_hosts" ).empty(); - $( "#unconfigured_hosts" ).append(body); + $("#unconfigured_hosts").empty(); + $("#unconfigured_hosts").append(body); }); }, 1000); }; // Run in we're showing a specific hosts' network. if ($('#network_interface_table').length) { - var host_name = $('#network_interface_table').data('host-name'); + var host_name = $('#network_interface_table').data('host-name'); + var say_title = $('#network_interface_table').data('title'); + var say_mac_address = $('#network_interface_table').data('mac-address'); + var say_name = $('#network_interface_table').data('name'); + var say_state = $('#network_interface_table').data('state'); + var say_speed = $('#network_interface_table').data('speed'); + var say_up_order = $('#network_interface_table').data('up-order'); + var say_up = $('#network_interface_table').data('up'); + var say_down = $('#network_interface_table').data('down'); //console.log('showing network info for: ['+host_name+']'); setInterval(function() { $.getJSON('/status/all_status.json', function(data) { - //console.log('Reload: ['+host_name+']'); + //console.log('read all_status.json: ['+data+']'); + // Build the HTML + var body = ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + $.each(data.hosts, function(i, host) { + //console.log('This is: ['+host.name+']'); + if (host.name != host_name) { + // Skip + return true; + }; + //console.log('Found it!'); + $.each(host.network_interfaces, function(j, nic) { + // Only real interfaces have a 'changed_order' value. + if (nic.changed_order) { + var say_link_state = say_down; + if (nic.link_state) { + say_link_state = say_up; + } + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + body += ''; + } + }); + }); + body += '
'+say_title+'
'+say_mac_address+''+say_name+''+say_state+''+say_speed+''+say_up_order+'
'+nic.mac_address+''+nic.name+''+say_link_state+''+nic.say_speed+''+nic.changed_order+'
'; + + // clear + append can't be the best way to do this... + $("#network_interface_table").empty(); + $("#network_interface_table").append(body); }); }, 1000); }; diff --git a/tools/anvil-daemon b/tools/anvil-daemon index 6ad31b35..dc050e9b 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -1143,7 +1143,7 @@ sub keep_running # Write out state information for all known Anvil! systems and the information from # unconfigured nods and DR hosts, using just database data (hence, fast enough to run # constantly). - update_striker_json($anvil); + $anvil->System->generate_state_json({debug => 3}); } else { @@ -1157,19 +1157,6 @@ sub keep_running return(0); } -# This writes out the main JSON file used by Striker to display information about unconfigured nodes/dr -# hosts, and known Anvil! / node / server states. -sub update_striker_json -{ - my ($anvil) = @_; - - # Start by recording information about currently unconfigured nodes and DR hosts. - $anvil->System->generate_state_json({debug => 3}); - - - return(0); -} - # This will check for any jobs that aren't at 100%. For each found, if 'picked_up_by' is set, a check is made # to see if the PID is still alive. If it isn't, or if 'picked_up_by' is not set, the appropriate tool is # invoked to handle it. diff --git a/tools/anvil-update-states b/tools/anvil-update-states index 62ef4aaf..8a596db6 100755 --- a/tools/anvil-update-states +++ b/tools/anvil-update-states @@ -347,8 +347,27 @@ sub update_network } closedir(DIRECTORY); - # We need to record bonds first so that their UUIDs are available when recording interfaces. - foreach my $processing ("bond", "interface", "bridge") + # Find what interfaces are connected to which bridges + $anvil->Network->bridge_info({debug => 3}); + delete $anvil->data->{interface_to_bridge} if exists $anvil->data->{interface_to_bridge}; + foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{bridge}{'local'}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bridge_name => $bridge_name }}); + foreach my $interface_name (sort {$a cmp $b} @{$anvil->data->{bridge}{'local'}{$bridge_name}{interfaces}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { interface_name => $interface_name }}); + + $anvil->data->{interface_to_bridge}{$interface_name} = $bridge_name; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + "interface_to_bridge::${interface_name}" => $anvil->data->{interface_to_bridge}{$interface_name}, + }}); + } + } + + # We need to record bridges first so we know their UUIDs when looking at bonds and interfaces that + # might be connected to them. Then we need to look at bonds so that their UUIDs are available when + # recording interfaces. + foreach my $processing ("bridge", "bond", "interface") { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { processing => $processing }}); foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}}) @@ -409,10 +428,53 @@ sub update_network up_delay => $up_delay, }}); + if (($type eq $processing) && ($type eq "bridge")) + { + my $bridge_uuid = $anvil->Database->insert_or_update_bridges({ + debug => 3, + file => $THIS_FILE, + line => __LINE__, + bridge_name => $interface, + bridge_id => $bridge_id, + bridge_mac_address => $mac_address, + bridge_mtu => $mtu, + bridge_stp_enabled => $bridge_stp_enabled, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bridge_uuid => $bridge_uuid }}); + + $anvil->data->{bridge_by_name}{$interface} = $bridge_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "bridge_by_name::${interface}" => $anvil->data->{bridge_by_name}{$interface} }}); + if (($bridge_uuid) && ($ip_address)) + { + my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({ + file => $THIS_FILE, + line => __LINE__, + ip_address_on_type => $type, + ip_address_on_uuid => $bridge_uuid, + ip_address_address => $ip_address, + ip_address_subnet_mask => $subnet_mask, + ip_address_gateway => $gateway, + ip_address_default_gateway => $default_gateway, + ip_address_dns => $dns, + ip_address_note => "", + }); + } + } + if (($type eq $processing) && ($type eq "bond")) { + # Is this bond connected to a bridge? + my $bond_bridge_uuid = ""; + my $bond_on_bridge = exists $anvil->data->{interface_to_bridge}{$interface} ? $anvil->data->{interface_to_bridge}{$interface} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bond_on_bridge => $bond_on_bridge }}); + if ($bond_on_bridge) + { + $bond_bridge_uuid = $anvil->data->{bridge_by_name}{$bond_on_bridge}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bond_bridge_uuid => $bond_bridge_uuid }}); + } + my $bond_uuid = $anvil->Database->insert_or_update_bonds({ - debug => 3, + debug => 2, file => $THIS_FILE, line => __LINE__, bond_name => $interface, @@ -427,6 +489,7 @@ sub update_network bond_mii_polling_interval => $mii_polling_interval, bond_up_delay => $up_delay, bond_down_delay => $down_delay, + bond_bridge_uuid => $bond_bridge_uuid, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bond_uuid => $bond_uuid }}); @@ -452,6 +515,16 @@ sub update_network if (($type eq $processing) && ($type eq "interface")) { + # Is this interface connected to a bridge? + my $network_interface_bridge_uuid = ""; + my $network_interface_on_bridge = exists $anvil->data->{interface_to_bridge}{$interface} ? $anvil->data->{interface_to_bridge}{$interface} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_interface_on_bridge => $network_interface_on_bridge }}); + if ($network_interface_on_bridge) + { + $network_interface_bridge_uuid = $anvil->data->{bridge_by_name}{$network_interface_on_bridge}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_interface_bridge_uuid => $network_interface_bridge_uuid }}); + } + my $say_bond_uuid = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bond_master => $bond_master }}); if (($bond_master) && ($anvil->data->{bond_by_name}{$bond_master})) @@ -463,10 +536,11 @@ sub update_network }}); } my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({ - debug => 3, + debug => 2, file => $THIS_FILE, line => __LINE__, network_interface_bond_uuid => $say_bond_uuid, + network_interface_bridge_uuid => $network_interface_bridge_uuid, network_interface_name => $interface, network_interface_duplex => $duplex, network_interface_link_state => $link_state, @@ -496,39 +570,6 @@ sub update_network }); } } - - if (($type eq $processing) && ($type eq "bridge")) - { - my $bridge_uuid = $anvil->Database->insert_or_update_bridges({ - debug => 3, - file => $THIS_FILE, - line => __LINE__, - bridge_name => $interface, - bridge_id => $bridge_id, - bridge_mac_address => $mac_address, - bridge_mtu => $mtu, - bridge_stp_enabled => $bridge_stp_enabled, - }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { bridge_uuid => $bridge_uuid }}); - - $anvil->data->{bridge_by_name}{$interface} = $bridge_uuid; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "bridge_by_name::${interface}" => $anvil->data->{bridge_by_name}{$interface} }}); - if (($bridge_uuid) && ($ip_address)) - { - my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({ - file => $THIS_FILE, - line => __LINE__, - ip_address_on_type => $type, - ip_address_on_uuid => $bridge_uuid, - ip_address_address => $ip_address, - ip_address_subnet_mask => $subnet_mask, - ip_address_gateway => $gateway, - ip_address_default_gateway => $default_gateway, - ip_address_dns => $dns, - ip_address_note => "", - }); - } - } } } @@ -842,88 +883,6 @@ WHERE $network_xml .= " \n"; } - # Now verify that the interface is connected to this bridge - $anvil->Network->bridge_info({debug => 3}); - foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{bridge}{'local'}}) - { - my $bridge_uuid = $anvil->data->{bridge_by_name}{$bridge_name}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - bridge_name => $bridge_name, - bridge_uuid => $bridge_uuid, - }}); - - foreach my $interface_name (sort {$a cmp $b} @{$anvil->data->{bridge}{'local'}{$bridge_name}{interfaces}}) - { - my $interface_uuid = exists $anvil->data->{interface_by_name}{$interface_name} ? $anvil->data->{interface_by_name}{$interface_name} : ""; - my $bond_uuid = exists $anvil->data->{bond_by_name}{$interface_name} ? $anvil->data->{bond_by_name}{$interface_name} : ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 's1:interface_name' => $interface_name, - 's2:interface_uuid' => $interface_uuid, - 's3:bond_uuid' => $bond_uuid, - }}); - - # Is this interface a bond or an interface? - if ($interface_uuid) - { - # Read the interface_bridge_uuid and, if it doesn't match, update it. - my $query = "SELECT network_interface_bridge_uuid FROM network_interfaces WHERE network_interface_uuid = ".$anvil->Database->quote($interface_uuid).";"; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }}); - my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); - my $count = @{$results}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - results => $results, - count => $count, - }}); - my $interface_bridge_uuid = defined $results->[0]->[0] ? $results->[0]->[0] : ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { interface_bridge_uuid => $interface_bridge_uuid }}); - if (($bridge_uuid) && ($interface_bridge_uuid ne $bridge_uuid)) - { - # Update it. - my $query = " -UPDATE - network_interfaces -SET - network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).", - modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." -WHERE - network_interface_uuid = ".$anvil->Database->quote($interface_uuid)." -;" ; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); - $anvil->Database->write({debug => 3, query => $query, source => $THIS_FILE, line => __LINE__}); - } - } - elsif ($bond_uuid) - { - # Read the interface_bridge_uuid and, if it doesn't match, update it. - my $query = "SELECT bond_bridge_uuid FROM bonds WHERE bond_uuid = ".$anvil->Database->quote($bond_uuid).";"; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }}); - my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); - my $count = @{$results}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - results => $results, - count => $count, - }}); - my $bond_bridge_uuid = defined $results->[0]->[0] ? $results->[0]->[0] : ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_bridge_uuid => $bond_bridge_uuid }}); - if (($bridge_uuid) && ($bond_bridge_uuid ne $bridge_uuid)) - { - # Update it. - my $query = " -UPDATE - bonds -SET - bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).", - modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." -WHERE - bond_uuid = ".$anvil->Database->quote($bond_uuid)." -;" ; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); - $anvil->Database->write({debug => 3, query => $query, source => $THIS_FILE, line => __LINE__}); - } - } - } - } - $network_json =~ s/,$//s; $network_json .= "]}\n"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_json => $network_json }}); diff --git a/tools/test.pl b/tools/test.pl index a58efa7a..dc341fc5 100755 --- a/tools/test.pl +++ b/tools/test.pl @@ -27,11 +27,24 @@ $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"}); -$anvil->System->generate_state_json({debug => 3}); -$anvil->Striker->parse_all_status_json({debug => 3}); +my $interface_uuid = "ffd6d29b-100c-452f-be4f-51cbc94eb069"; +my $query = "SELECT network_interface_bridge_uuid FROM network_interfaces WHERE network_interface_uuid = ".$anvil->Database->quote($interface_uuid).";"; +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); +my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); +my $count = @{$results}; +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + results => $results, + count => $count, +}}); +my $network_interface_bridge_uuid = defined $results->[0]->[0] ? $results->[0]->[0] : ""; +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_bridge_uuid => $network_interface_bridge_uuid }}); + + +#$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'}; -#die; +die; foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{json}{all_status}{hosts}}) {