@ -37,7 +37,7 @@ if (not $connections)
$anvil->nice_exit({exit_code => 2});
}
report _network($anvil);
update _network($anvil);
$anvil->nice_exit({exit_code => 0});
@ -46,7 +46,7 @@ $anvil->nice_exit({exit_code => 0});
#############################################################################################################
# This reports the current network interface states, tracked by the MAC address.
sub report _network
sub update _network
{
my ($anvil) = @_;
@ -59,6 +59,14 @@ sub report_network
my $directory = "/sys/class/net";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { directory => $directory }});
# We'll need to know what interfaces to remove, if any. This will store the interfaces we've seen and
# any others will be removed.
$anvil->data->{seen} = {
interfaces => {},
bonds => {},
bridges => {},
};
local(*DIRECTORY);
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0018", variables => { directory => $directory }});
opendir(DIRECTORY, $directory);
@ -222,6 +230,10 @@ sub report_network
}
}
# Record this interface
$anvil->data->{seen}{$type}{$interface} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "seen::${type}::${interface}" => $anvil->data->{seen}{$type}{$interface} }});
# Log
$anvil->data->{network}{interfaces}{by_name}{$interface} = {
active_slave => $active_slave,
@ -427,7 +439,9 @@ SELECT
FROM
bonds
WHERE
bond_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)."
bond_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)."
AND
bond_mode != 'DELETED'
;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0124", variables => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
@ -439,8 +453,9 @@ WHERE
foreach my $row (@{$results})
{
my $bond_uuid = $row->[0];
my $bond_name = $row->[1];
$anvil->data->{bonds}{$bond_uuid} = {
bond_name => $row->[1] ,
bond_name => $bond_name ,
bond_mode => $row->[2],
bond_mtu => $row->[3],
bond_primary_slave => $row->[4],
@ -465,6 +480,17 @@ WHERE
"bonds::${bond_uuid}::bond_mac_address" => $anvil->data->{bonds}{$bond_uuid}{bond_mac_address},
"bonds::${bond_uuid}::bond_operational" => $anvil->data->{bonds}{$bond_uuid}{bond_operational},
}});
# Make sure I've seen this interface in this scan and, if not, update this entry to remove it.
if ((not exists $anvil->data->{seen}{bond}{$bond_name}) or (not $anvil->data->{seen}{bond}{$bond_name}))
{
# Mark it as deleted.
my $query = "UPDATE bonds SET bond_mode = 'DELETED' WHERE bond_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($bond_uuid).";";
$anvil->Database->write({debug => 2, query => $query, source => $THIS_FILE, line => __LINE__});
# Remove it from the hash so we don't add it to the .json and .xml files.
delete $anvil->data->{bonds}{$bond_uuid};
}
}
$query = "
@ -476,7 +502,9 @@ SELECT
FROM
bridges
WHERE
bridge_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)."
bridge_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)."
AND
bridge_id != 'DELETED'
;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0124", variables => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
@ -488,8 +516,9 @@ WHERE
foreach my $row (@{$results})
{
my $bridge_uuid = $row->[0];
my $bridge_name = $row->[1];
$anvil->data->{bridges}{$bridge_uuid} = {
bridge_name => $row->[1] ,
bridge_name => $bridge_name ,
bridge_id => $row->[2],
bridge_stp_enabled => $row->[3],
};
@ -498,6 +527,17 @@ WHERE
"bridges::${bridge_uuid}::bridge_id" => $anvil->data->{bridges}{$bridge_uuid}{bridge_id},
"bridges::${bridge_uuid}::bridge_stp_enabled" => $anvil->data->{bridges}{$bridge_uuid}{bridge_stp_enabled},
}});
# Make sure I've seen this interface in this scan and, if not, update this entry to remove it.
if ((not exists $anvil->data->{seen}{bridge}{$bridge_name}) or (not $anvil->data->{seen}{bridge}{$bridge_name}))
{
# Mark it as deleted.
my $query = "UPDATE bridges SET bridge_id = 'DELETED' WHERE bridge_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($bridge_uuid).";";
$anvil->Database->write({debug => 2, query => $query, source => $THIS_FILE, line => __LINE__});
# Remove it from the hash so we don't add it to the .json and .xml files.
delete $anvil->data->{bridges}{$bridge_uuid};
}
}
$query = "
@ -516,11 +556,13 @@ SELECT
FROM
network_interfaces
WHERE
network_interface_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)."
network_interface_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)."
AND
network_interface_operational != 'DELETED'
ORDER BY
modified_date DESC
;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3 , 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 => 3, list => {
@ -536,9 +578,10 @@ ORDER BY
foreach my $row (@{$results})
{
my $network_interface_uuid = $row->[0];
my $network_interface_name = $row->[2];
$anvil->data->{network_interfaces}{$network_interface_uuid} = {
network_interface_mac_address => $row->[1],
network_interface_name => $row->[2] ,
network_interface_name => $network_interface_name ,
network_interface_speed => $row->[3],
network_interface_mtu => $row->[4],
network_interface_link_state => $row->[5],
@ -548,7 +591,7 @@ ORDER BY
network_interface_bond_uuid => defined $row->[9] ? $row->[9] : 'NULL',
network_interface_bridge_uuid => defined $row->[10] ? $row->[10] : 'NULL',
};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3 , list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2 , list => {
"network_interfaces::${network_interface_uuid}::network_interface_mac_address" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_mac_address},
"network_interfaces::${network_interface_uuid}::network_interface_name" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_name},
"network_interfaces::${network_interface_uuid}::network_interface_speed" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_speed},
@ -561,6 +604,21 @@ ORDER BY
"network_interfaces::${network_interface_uuid}::network_interface_bridge_uuid" => $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_bridge_uuid},
order => $order,
}});
# Make sure I've seen this interface in this scan and, if not, update this entry to remove it.
if ((not exists $anvil->data->{seen}{interface}{$network_interface_name}) or (not $anvil->data->{seen}{interface}{$network_interface_name}))
{
# Mark it as deleted.
my $query = "UPDATE network_interfaces SET network_interface_operational = 'DELETED' WHERE network_interface_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($network_interface_uuid).";";
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
# Remove it from the hash so we don't add it to the .json and .xml files.
delete $anvil->data->{interfaces}{$network_interface_uuid};
# Loop so we don't try to process any further.
next;
}
my $say_bond = "";
my $network_interface_bond_uuid = $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_bond_uuid};
my $network_interface_bridge_uuid = $anvil->data->{network_interfaces}{$network_interface_uuid}{network_interface_bridge_uuid};
@ -597,7 +655,9 @@ SELECT
FROM
ip_addresses
WHERE
ip_address_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)."
ip_address_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)."
AND
ip_address_on_type != 'DELETED'
;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0124", variables => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
@ -626,25 +686,52 @@ WHERE
ip_address_dns => $ip_address_dns,
}});
my $say_on = "";
if ($ip_address_on_type eq "interface")
# Did we see this IP on this scan? If not, set on_type to DELETEd.
my $found = 0;
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}})
{
$say_on = $anvil->data->{network_interfaces}{$ip_address_on_uuid}{network_interface_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_on => $say_on }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface,
ip_address_address => $ip_address_address,
"sys::network::interface::${interface}::ip" => $anvil->data->{sys}{network}{interface}{$interface}{ip},
}});
if ((defined $anvil->data->{sys}{network}{interface}{$interface}{ip}) && ($anvil->data->{sys}{network}{interface}{$interface}{ip} eq $ip_address_address))
{
$found = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { found => $found }});
last;
}
}
elsif ($ip_address_on_type eq "bond")
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { found => $found }});
if ($found)
{
$say_on = $anvil->data->{bonds}{$ip_address_on_uuid}{bond_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_on => $say_on }});
my $say_on = "";
if ($ip_address_on_type eq "interface")
{
$say_on = $anvil->data->{network_interfaces}{$ip_address_on_uuid}{network_interface_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_on => $say_on }});
}
elsif ($ip_address_on_type eq "bond")
{
$say_on = $anvil->data->{bonds}{$ip_address_on_uuid}{bond_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_on => $say_on }});
}
elsif ($ip_address_on_type eq "bridge")
{
$say_on = $anvil->data->{bridges}{$ip_address_on_uuid}{bridge_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_on => $say_on }});
}
$network_json .= " { \"address\":\"$ip_address_address\", \"on\":\"$say_on\", \"subnet\":\"$ip_address_subnet_mask\", \"gateway\":\"$ip_address_gateway\", \"default_gateway\":\"$ip_address_default_gateway\", \"dns\":\"$ip_address_dns\" },\n";
$network_xml .= " <ip address=\"$ip_address_address\" on=\"$say_on\" subnet=\"$ip_address_subnet_mask\" gateway=\"$ip_address_gateway\" default_gateway=\"$ip_address_default_gateway\" dns=\"$ip_address_dns\" />\n";
}
elsif ($ip_address_on_type eq "bridge")
else
{
$say_on = $anvil->data->{bridges}{$ip_address_on_uuid}{bridge_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_on => $say_on }});
# Stale, mark it as deleted.
my $query = "UPDATE ip_addresses SET ip_address_on_type = 'DELETED' WHERE ip_address_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_uuid).";";
$anvil->Database->write({debug => 2, query => $query, source => $THIS_FILE, line => __LINE__});
}
$network_json .= " { \"address\":\"$ip_address_address\", \"on\":\"$say_on\", \"subnet\":\"$ip_address_subnet_mask\", \"gateway\":\"$ip_address_gateway\", \"default_gateway\":\"$ip_address_default_gateway\", \"dns\":\"$ip_address_dns\" },\n";
$network_xml .= " <ip address=\"$ip_address_address\" on=\"$say_on\" subnet=\"$ip_address_subnet_mask\" gateway=\"$ip_address_gateway\" default_gateway=\"$ip_address_default_gateway\" dns=\"$ip_address_dns\" />\n";
}
$network_json =~ s/,$//s;