fea10e5bb1
* Updated anvil-manage-server-storage to the point where it can now insert and eject optical disks! * Updated System->call to log parameters if 'shell_call' isn't set. * Fixed a bug in anvil-manage-server process_interactive where an $anvil->data reference was being scoped. Signed-off-by: digimer <mkelly@alteeve.ca>
4224 lines
191 KiB
Perl
Executable File
4224 lines
191 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
#
|
|
# This scans the network, bridges, bonds and interfaces.
|
|
#
|
|
# Examples;
|
|
#
|
|
# Exit codes;
|
|
# 0 = Normal exit.
|
|
# 1 = Startup failure (not running as root, no DB, bad file read, etc)
|
|
#
|
|
# TODO:
|
|
# -
|
|
#
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Anvil::Tools;
|
|
use Data::Dumper;
|
|
|
|
# Disable buffering
|
|
$| = 1;
|
|
|
|
# Prevent a discrepency between UID/GID and EUID/EGID from throwing an error.
|
|
$< = $>;
|
|
$( = $);
|
|
|
|
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
|
|
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
|
|
if (($running_directory =~ /^\./) && ($ENV{PWD}))
|
|
{
|
|
$running_directory =~ s/^\./$ENV{PWD}/;
|
|
}
|
|
|
|
my $anvil = Anvil::Tools->new();
|
|
|
|
# Make sure we're running as 'root'
|
|
# $< == real UID, $> == effective UID
|
|
if (($< != 0) && ($> != 0))
|
|
{
|
|
# Not root
|
|
print $anvil->Words->string({key => "error_0005"})."\n";
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
# These are the threasholds for when to alert when swap is running out.
|
|
$anvil->data->{switches}{force} = 0;
|
|
|
|
#$anvil->Storage->read_config();
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "log_0115", variables => { program => $THIS_FILE }});
|
|
|
|
# Read switches
|
|
$anvil->Get->switches;
|
|
|
|
# Handle start-up tasks
|
|
my $problem = $anvil->ScanCore->agent_startup({agent => $THIS_FILE});
|
|
if ($problem)
|
|
{
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
if ($anvil->data->{switches}{purge})
|
|
{
|
|
# This can be called when doing bulk-database purges.
|
|
my $schema_file = $anvil->data->{path}{directories}{scan_agents}."/".$THIS_FILE."/".$THIS_FILE.".sql";
|
|
$anvil->Database->purge_data({
|
|
debug => 2,
|
|
tables => $anvil->Database->get_tables_from_schema({schema_file => $schema_file}),
|
|
});
|
|
$anvil->nice_exit({exit_code => 0});
|
|
}
|
|
|
|
|
|
# Read the data.
|
|
collect_data($anvil);
|
|
|
|
# Load stored data.
|
|
read_last_scan($anvil);
|
|
|
|
# Look for changes.
|
|
find_changes($anvil);
|
|
|
|
# Finally, process health weights.
|
|
process_health($anvil);
|
|
|
|
# This clears the TX and RX variable data for interfaces older than 'scancore::database::age_out'.
|
|
clear_old_variables($anvil);
|
|
|
|
# This removes network interfaces that have been marked as DELETED for a while now.
|
|
clear_old_interfaces($anvil);
|
|
|
|
# Shut down.
|
|
$anvil->ScanCore->agent_shutdown({agent => $THIS_FILE});
|
|
|
|
|
|
#############################################################################################################
|
|
# Functions #
|
|
#############################################################################################################
|
|
|
|
# This removes network interfaces that have been marked as DELETED for a while now.
|
|
sub clear_old_interfaces
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Read in all interfaces and for each, delete historical records over the age-out time.
|
|
my $age = $anvil->data->{scancore}{database}{age_out};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { age => $age }});
|
|
|
|
if ($age =~ /\D/)
|
|
{
|
|
# Age is not valid, set it to defaults.
|
|
$age = 24;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { age => $age }});
|
|
}
|
|
|
|
my $query = "SELECT now() - '".$age."h'::interval;";
|
|
my $old_timestamp = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
query => $query,
|
|
old_timestamp => $old_timestamp,
|
|
}});
|
|
|
|
# It is possible that a record exists on one DB, but not the other. Unsure how this happens, but this
|
|
# cleans it up.
|
|
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
uuid => $anvil->Database->get_host_from_uuid({short => 1, host_uuid => $uuid})." (".$uuid.")",
|
|
}});
|
|
my $query = "
|
|
SELECT
|
|
ip_address_uuid,
|
|
ip_address_address
|
|
FROM
|
|
ip_addresses
|
|
WHERE
|
|
ip_address_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
|
|
AND
|
|
ip_address_note = 'DELETED'
|
|
AND
|
|
modified_date < '".$old_timestamp."'
|
|
ORDER BY
|
|
ip_address_address ASC
|
|
;";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
my $results = $anvil->Database->query({uuid => $uuid, 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,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $ip_address_uuid = $row->[0];
|
|
my $ip_address_address = $row->[1];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:ip_address_uuid' => $ip_address_uuid,
|
|
's2:ip_address_address' => $ip_address_address,
|
|
}});
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_log_0005", variables => {
|
|
age => $age,
|
|
ip => $ip_address_address,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.ip_addresses WHERE ip_address_uuid = '".$ip_address_uuid."';";
|
|
push @{$queries}, "DELETE FROM ip_addresses WHERE ip_address_uuid = '".$ip_address_uuid."';";
|
|
foreach my $query (@{$queries})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
}
|
|
# Write to both DBs.
|
|
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
}
|
|
|
|
# Remove interfaces
|
|
$query = "
|
|
SELECT
|
|
network_interface_uuid,
|
|
network_interface_mac_address,
|
|
network_interface_name
|
|
FROM
|
|
network_interfaces
|
|
WHERE
|
|
network_interface_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
|
|
AND
|
|
network_interface_operational = 'DELETED'
|
|
AND
|
|
modified_date < '".$old_timestamp."'
|
|
ORDER BY
|
|
network_interface_name ASC
|
|
;";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
$results = $anvil->Database->query({uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__});
|
|
$count = @{$results};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $network_interface_uuid = $row->[0];
|
|
my $network_interface_mac_address = $row->[1];
|
|
my $network_interface_name = $row->[2];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:network_interface_uuid' => $network_interface_uuid,
|
|
's2:network_interface_mac_address' => $network_interface_mac_address,
|
|
's3:network_interface_name' => $network_interface_name,
|
|
}});
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_log_0002", variables => {
|
|
age => $age,
|
|
mac => $network_interface_mac_address,
|
|
name => $network_interface_name,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_uuid = '".$network_interface_uuid."';";
|
|
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_uuid = '".$network_interface_uuid."';";
|
|
foreach my $query (@{$queries})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
}
|
|
# Write to both DBs.
|
|
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
}
|
|
|
|
# Delete old bonds
|
|
$query = "
|
|
SELECT
|
|
bond_uuid,
|
|
bond_name
|
|
FROM
|
|
bonds
|
|
WHERE
|
|
bond_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
|
|
AND
|
|
bond_mode = 'DELETED'
|
|
AND
|
|
modified_date < '".$old_timestamp."'
|
|
ORDER BY
|
|
bond_name ASC
|
|
;";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
$results = $anvil->Database->query({uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__});
|
|
$count = @{$results};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $bond_uuid = $row->[0];
|
|
my $bond_name = $row->[1];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:bond_uuid' => $bond_uuid,
|
|
's2:bond_name' => $bond_name,
|
|
}});
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_log_0003", variables => {
|
|
age => $age,
|
|
name => $bond_name,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.bonds WHERE bond_uuid = '".$bond_uuid."';";
|
|
push @{$queries}, "DELETE FROM bonds WHERE bond_uuid = '".$bond_uuid."';";
|
|
foreach my $query (@{$queries})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
}
|
|
# Write to both DBs.
|
|
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
}
|
|
|
|
# Delete old bridges
|
|
$query = "
|
|
SELECT
|
|
bridge_uuid,
|
|
bridge_name
|
|
FROM
|
|
bridges
|
|
WHERE
|
|
bridge_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
|
|
AND
|
|
bridge_id = 'DELETED'
|
|
AND
|
|
modified_date < '".$old_timestamp."'
|
|
ORDER BY
|
|
bridge_name ASC
|
|
;";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
$results = $anvil->Database->query({uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__});
|
|
$count = @{$results};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $bridge_uuid = $row->[0];
|
|
my $bridge_name = $row->[1];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:bridge_uuid' => $bridge_uuid,
|
|
's2:bridge_name' => $bridge_name,
|
|
}});
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_log_0004", variables => {
|
|
age => $age,
|
|
name => $bridge_name,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.bridges WHERE bridge_uuid = '".$bridge_uuid."';";
|
|
push @{$queries}, "DELETE FROM bridges WHERE bridge_uuid = '".$bridge_uuid."';";
|
|
foreach my $query (@{$queries})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
}
|
|
# Write to both DBs.
|
|
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
# This clears the TX and RX variable data for interfaces older than 'scancore::database::age_out'.
|
|
sub clear_old_variables
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Only Strikers run this.
|
|
my $host_type = $anvil->Get->host_type();
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
|
|
if ($host_type ne "striker")
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
# Read in all interfaces and for each, delete historical records over the age-out time.
|
|
my $age = $anvil->data->{scancore}{database}{age_out};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { age => $age }});
|
|
|
|
if ($age =~ /\D/)
|
|
{
|
|
# Age is not valid, set it to defaults.
|
|
$age = 24;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { age => $age }});
|
|
}
|
|
|
|
# Get the timestamp to delete thermal and power records older than $age hours.
|
|
my $query = "SELECT now() - '".$age."h'::interval;";
|
|
my $old_timestamp = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
|
query => $query,
|
|
old_timestamp => $old_timestamp,
|
|
}});
|
|
|
|
# Read in all interface RX and TX variables.
|
|
foreach my $uuid (keys %{$anvil->data->{cache}{database_handle}})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
|
uuid => $uuid,
|
|
db_host => $anvil->Get->host_name_from_uuid({host_uuid => $uuid}),
|
|
}});
|
|
my $queries = [];
|
|
$query = "
|
|
SELECT
|
|
variable_uuid,
|
|
variable_name
|
|
FROM
|
|
variables
|
|
WHERE
|
|
variable_name LIKE '%::tx_bytes'
|
|
OR
|
|
variable_name LIKE '%::rx_bytes'
|
|
;";
|
|
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
|
|
my $count = @{$results};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $variable_uuid = $row->[0];
|
|
my $variable_name = $row->[1];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
|
's1:variable_name' => $variable_name,
|
|
's2:variable_uuid' => $variable_uuid,
|
|
}});
|
|
|
|
# Find out of there are any records to remove at all.
|
|
my $query = "SELECT history_id FROM history.variables WHERE variable_uuid = ".$anvil->Database->quote($variable_uuid)." AND modified_date <= '".$old_timestamp."';";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }});
|
|
|
|
my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__});
|
|
my $count = @{$results};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
|
|
if ($count)
|
|
{
|
|
# Find how many records will be left. If it's 0, we'll use an OFFSET 1.
|
|
my $query = "SELECT history_id FROM history.variables WHERE variable_uuid = ".$anvil->Database->quote($variable_uuid)." AND modified_date > '".$old_timestamp."';";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }});
|
|
|
|
my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__});
|
|
my $count = @{$results};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
if ($count)
|
|
{
|
|
# At least one record will be left, we can do a simple delete.
|
|
my $query = "DELETE FROM history.variables WHERE variable_uuid = ".$anvil->Database->quote($variable_uuid)." AND modified_date <= '".$old_timestamp."';";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }});
|
|
push @{$queries}, $query;
|
|
}
|
|
else
|
|
{
|
|
# This would delete everything, reserve at least one record.
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $history_id = $row->[0];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { history_id => $history_id }});
|
|
|
|
my $query = "DELETE FROM history.variables WHERE variable_uuid = ".$anvil->Database->quote($variable_uuid)." AND history_id = '".$history_id."';";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }});
|
|
push @{$queries}, $query;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
my $commits = @{$queries};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { commits => $commits }});
|
|
if ($commits)
|
|
{
|
|
# Commit the DELETEs.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_log_0001", variables => {
|
|
age => $age,
|
|
records => $commits,
|
|
host => $anvil->Get->host_name_from_uuid({host_uuid => $uuid}),
|
|
}});
|
|
$anvil->Database->write({debug => 3, uuid => $uuid, query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
undef $queries;
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
# This reads in all of the network data
|
|
sub collect_data
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
$anvil->Network->get_ips({debug => 2});
|
|
|
|
# Read the data from the ifcfg files, if available. We'll use this to check for bond interfaces that
|
|
# didn't start.
|
|
$anvil->Network->check_network();
|
|
my $uptime = $anvil->Get->uptime();
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uptime => $uptime }});
|
|
if ($uptime < 600)
|
|
{
|
|
$anvil->Network->read_nmcli({debug => 2})
|
|
}
|
|
|
|
# The 'local_host' is needed to pull data recorded by Network->get_ips();
|
|
my $local_host = $anvil->Get->short_host_name();
|
|
my $directory = "/sys/class/net";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
local_host => $local_host,
|
|
directory => $directory,
|
|
}});
|
|
|
|
# Make sure there are no virsh bridges, removing any found.
|
|
my $host_type = $anvil->Get->host_type();
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
|
|
if (($host_type eq "node") or ($host_type eq "dr"))
|
|
{
|
|
my $default_network = "/etc/libvirt/qemu/networks/default.xml";
|
|
if (-e $default_network)
|
|
{
|
|
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-destroy default";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
$shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-undefine default";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
# Register an alert
|
|
my $variables = {
|
|
bridge => "default",
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0001", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0001",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
=cut
|
|
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-list --all --name";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
# This often hangs.
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
if (not $return_code)
|
|
{
|
|
# Virsh is up.
|
|
foreach my $line (split/\n/, $output)
|
|
{
|
|
$line =~ s/^\s+//;
|
|
$line =~ s/\s+$//;
|
|
next if not $line;
|
|
next if $line =~ /^error/;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "striker_0287", variables => { bridge => $line }});
|
|
|
|
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-destroy ".$line;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
$shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." net-undefine ".$line;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
|
|
# Register an alert
|
|
my $variables = {
|
|
bridge => $line,
|
|
};
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0001", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0001",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
}
|
|
=cut
|
|
}
|
|
|
|
# Walk through the sysfs files.
|
|
local(*DIRECTORY);
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0018", variables => { directory => $directory }});
|
|
opendir(DIRECTORY, $directory);
|
|
while(my $file = readdir(DIRECTORY))
|
|
{
|
|
next if $file eq ".";
|
|
next if $file eq "..";
|
|
next if $file eq "lo";
|
|
my $full_path = $directory."/".$file;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { full_path => $full_path }});
|
|
if (-d $full_path)
|
|
{
|
|
# Pull out the data I want. Note that some of these don't exist with virtio-net interfaces.
|
|
my $interface = $file;
|
|
my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0;
|
|
my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0;
|
|
my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half?
|
|
my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down
|
|
my $modalias = -e $full_path."/device/modalias" ? $anvil->Storage->read_file({file => $full_path."/device/modalias"}) : "unknown";
|
|
my $speed = $link_state ? $anvil->Storage->read_file({file => $full_path."/speed"}) : 0; # Mbps (ie: 1000 = Gbps), gives a very high number for unplugged link
|
|
my $media = "unknown";
|
|
my $type = "interface";
|
|
my $driver = "";
|
|
my $tx_bytes = 0; # How many bytes transmitted
|
|
my $rx_bytes = 0; # How many bytes received
|
|
|
|
# Clean up some newlines.
|
|
$link_state =~ s/\n$//;
|
|
$mtu =~ s/\n$//;
|
|
$duplex =~ s/\n$//;
|
|
$operational =~ s/\n$//;
|
|
$speed =~ s/\n$//;
|
|
$modalias =~ s/\n$//;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
interface => $interface,
|
|
link_state => $link_state,
|
|
mtu => $mtu,
|
|
duplex => $duplex,
|
|
operational => $operational,
|
|
speed => $speed,
|
|
modalias => $modalias,
|
|
}});
|
|
|
|
### NOTE: This only parses virtio so far.
|
|
# Pick out our driver.
|
|
if ($modalias =~ /^virtio:/)
|
|
{
|
|
$driver = "virtio";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { driver => $driver }});
|
|
}
|
|
|
|
# The MAC address can faked by a number of ways, so we make an explicit call to 'ethtool' to get the permanent mac address.
|
|
my $mac_address = "";
|
|
my $shell_call = $anvil->data->{path}{exe}{ethtool}." -P ".$interface;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
if ($output =~ /(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)$/)
|
|
{
|
|
$mac_address = lc($1);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
|
|
}
|
|
else
|
|
{
|
|
# Get it by reading the address file.
|
|
if (-e $full_path."/bonding_slave/perm_hwaddr")
|
|
{
|
|
$mac_address = $anvil->Storage->read_file({file => $full_path."/bonding_slave/perm_hwaddr"});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
|
|
}
|
|
elsif (-e $full_path."/address")
|
|
{
|
|
$mac_address = $anvil->Storage->read_file({file => $full_path."/address"});
|
|
$mac_address =~ s/\n//;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
|
|
}
|
|
}
|
|
|
|
# These are variables that will be needed if this is a bond interface.
|
|
my $ip_address = "";
|
|
my $subnet_mask = "";
|
|
my $bond_mode = "";
|
|
my $primary_interface = "";
|
|
my $primary_reselect = "";
|
|
my $active_interface = "";
|
|
my $mii_polling_interval = "";
|
|
my $up_delay = "";
|
|
my $down_delay = "";
|
|
my $bond_master = "";
|
|
|
|
# These are variables that will be needed if this is a bridge interface
|
|
my $bridge_id = "";
|
|
my $bridge_stp_enabled = "";
|
|
|
|
# Explicitly check for the existing of the hash so that we don't auto-vivivate the interface.
|
|
if (exists $anvil->data->{network}{$local_host}{interface}{$interface})
|
|
{
|
|
$ip_address = defined $anvil->data->{network}{$local_host}{interface}{$interface}{ip} ? $anvil->data->{network}{$local_host}{interface}{$interface}{ip} : "";
|
|
$subnet_mask = defined $anvil->data->{network}{$local_host}{interface}{$interface}{subnet_mask} ? $anvil->data->{network}{$local_host}{interface}{$interface}{subnet_mask} : "";
|
|
$type = defined $anvil->data->{network}{$local_host}{interface}{$interface}{type} ? $anvil->data->{network}{$local_host}{interface}{$interface}{type} : "interface";
|
|
$tx_bytes = defined $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes} ? $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes} : 0;
|
|
$rx_bytes = defined $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes} ? $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes} : 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
ip_address => $ip_address,
|
|
subnet_mask => $subnet_mask,
|
|
type => $type,
|
|
rx_bytes => $rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $rx_bytes}).")",
|
|
tx_bytes => $tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $tx_bytes}).")",
|
|
}});
|
|
}
|
|
|
|
# If this interface is already a bond slave, the real mac address will be in a
|
|
# sub-directory.
|
|
my $mac_bond_file = $directory."/".$file."/bonding_slave/perm_hwaddr";
|
|
if (-e $mac_bond_file)
|
|
{
|
|
# It's a slave.
|
|
$mac_address = $anvil->Storage->read_file({file => $mac_bond_file});
|
|
$mac_address =~ s/\n$//;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
|
|
}
|
|
|
|
# If this is a virtual interface, set some fake values that don't actually exist on
|
|
# the system for the sake of a cleaner display.
|
|
if (($mac_address =~ /^52:54:00/) or ($driver eq "virtio"))
|
|
{
|
|
### Set some fake values.
|
|
# Speed is "as fast as possible", so we'll record 100 Gbps, but that is really kind of arbitrary.
|
|
if ((not $speed) or ($speed eq "-1"))
|
|
{
|
|
$speed = 10000;
|
|
}
|
|
if ((not $duplex) or ($duplex eq "unknown"))
|
|
{
|
|
$duplex = "full";
|
|
}
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
speed => $speed,
|
|
duplex => $duplex,
|
|
}});
|
|
}
|
|
# If the state is 'down', set the speed to '0'.
|
|
if (not $link_state)
|
|
{
|
|
$speed = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { speed => $speed }});
|
|
}
|
|
|
|
# Is this a bond interface?
|
|
if (-e "/proc/net/bonding/".$interface)
|
|
{
|
|
# Yup, we'll neet to dig into the bond proc files to get the proper slaved
|
|
# interface MAC addresses.
|
|
$type = "bond";
|
|
|
|
# Read the bond mode.
|
|
$bond_mode = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/mode"});
|
|
$primary_interface = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/primary"});
|
|
$primary_reselect = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/primary_reselect"});
|
|
$active_interface = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/active_slave"});
|
|
$mii_polling_interval = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/miimon"});
|
|
$up_delay = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/updelay"});
|
|
$down_delay = $anvil->Storage->read_file({file => "/sys/devices/virtual/net/".$interface."/bonding/downdelay"});
|
|
$bond_mode =~ s/\s.*//;
|
|
$bond_mode =~ s/\n$//;
|
|
$primary_interface =~ s/\n$//;
|
|
$primary_reselect =~ s/\s.*//;
|
|
$primary_reselect =~ s/\n$//;
|
|
$active_interface =~ s/\n$//;
|
|
$mii_polling_interval =~ s/\n$//;
|
|
$up_delay =~ s/\n$//;
|
|
$down_delay =~ s/\n$//;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
active_interface => $active_interface,
|
|
bond_mode => $bond_mode,
|
|
mii_polling_interval => $mii_polling_interval,
|
|
primary_reselect => $primary_reselect,
|
|
primary_interface => $primary_interface,
|
|
type => $type,
|
|
}});
|
|
}
|
|
elsif ((-e $full_path."/master") && ($interface !~ /^vnet/))
|
|
{
|
|
# We're in a bond.
|
|
my $target = readlink($full_path."/master");
|
|
$bond_master = ($target =~ /^.*\/(.*)$/)[0];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
target => $target,
|
|
bond_master => $bond_master,
|
|
}});
|
|
}
|
|
elsif (-d $full_path."/bridge")
|
|
{
|
|
# It's a bridge
|
|
$type = "bridge";
|
|
$bridge_id = $anvil->Storage->read_file({debug => 3, file => $full_path."/bridge/bridge_id"});
|
|
$bridge_stp_enabled = $anvil->Storage->read_file({debug => 3, file => $full_path."/bridge/stp_state"});
|
|
$bridge_id =~ s/\n$//;
|
|
$bridge_stp_enabled =~ s/\n$//;
|
|
$speed = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bridge_id => $bridge_id,
|
|
bridge_stp_enabled => $bridge_stp_enabled,
|
|
type => $type,
|
|
}});
|
|
if ($bridge_stp_enabled eq "0")
|
|
{
|
|
$bridge_stp_enabled = "disabled";
|
|
}
|
|
elsif ($bridge_stp_enabled eq "1")
|
|
{
|
|
$bridge_stp_enabled = "enabled_kernel";
|
|
}
|
|
elsif ($bridge_stp_enabled eq "2")
|
|
{
|
|
$bridge_stp_enabled = "enabled_userland";
|
|
}
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge_stp_enabled => $bridge_stp_enabled }});
|
|
}
|
|
|
|
# If this is a 'vnet' device, set 'operational' to up
|
|
if ($interface =~ /^vnet/)
|
|
{
|
|
$operational = "up";
|
|
$media = "virtual";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
operational => $operational,
|
|
media => $media,
|
|
}});
|
|
}
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
active_interface => $active_interface,
|
|
bond_master => $bond_master,
|
|
bond_mode => $bond_mode,
|
|
bridge_id => $bridge_id,
|
|
bridge_stp_enabled => $bridge_stp_enabled,
|
|
down_delay => $down_delay,
|
|
duplex => $duplex,
|
|
interface => $interface,
|
|
mac_address => $mac_address,
|
|
mii_polling_interval => $mii_polling_interval,
|
|
mtu => $mtu,
|
|
operational => $operational,
|
|
primary_reselect => $primary_reselect,
|
|
primary_interface => $primary_interface,
|
|
speed => $speed,
|
|
subnet_mask => $subnet_mask,
|
|
type => $type,
|
|
up_delay => $up_delay,
|
|
}});
|
|
|
|
# If the MAC address starts with '52:54:00', we've got a virtio NIC.
|
|
if ((not defined $speed) or ($speed eq ""))
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_error_0001", variables => { file => $full_path."/speed" }});
|
|
next;
|
|
}
|
|
if ($speed =~ /\D/)
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_error_0002", variables => {
|
|
file => $full_path."/speed",
|
|
speed => $speed,
|
|
}});
|
|
next;
|
|
}
|
|
if ($speed > 100000)
|
|
{
|
|
# NOTE: This is probably 0 now... Though someday >100 Gbps will be reasonable
|
|
# and we'll need to change this.
|
|
$speed = 0;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { speed => $speed }});
|
|
}
|
|
|
|
# Find the media, if possible.
|
|
(my $ethtool, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{ethtool}." $interface"});
|
|
foreach my $line (split/\n/, $ethtool)
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
|
|
if ($line =~ /Supported ports: \[ (.*?) \]/i)
|
|
{
|
|
$media = lc($1);
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { media => $media }});
|
|
|
|
# This can be 'tp mii', which breaks json.
|
|
if ($media =~ /\t/)
|
|
{
|
|
$media =~ s/\t/,/g;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { media => $media }});
|
|
}
|
|
last;
|
|
}
|
|
}
|
|
|
|
# Store new information we found.
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{active_interface} = $active_interface;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{bond_mode} = $bond_mode;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{bond_master} = $bond_master;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{bridge_id} = $bridge_id;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{bridge_stp_enabled} = $bridge_stp_enabled;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{down_delay} = $down_delay;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{duplex} = $duplex;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{ip} = $ip_address;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{link_state} = $link_state;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{mac_address} = $mac_address;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{media} = $media;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{mii_polling_interval} = $mii_polling_interval;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{mtu} = $mtu;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{operational} = $operational;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{primary_reselect} = $primary_reselect;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{primary_interface} = $primary_interface;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{speed} = $speed;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{subnet_mask} = $subnet_mask;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{type} = $type;
|
|
$anvil->data->{network}{$local_host}{interface}{$interface}{up_delay} = $up_delay;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"network::${local_host}::interface::${interface}::active_interface" => $anvil->data->{network}{$local_host}{interface}{$interface}{active_interface},
|
|
"network::${local_host}::interface::${interface}::bond_mode" => $anvil->data->{network}{$local_host}{interface}{$interface}{bond_mode},
|
|
"network::${local_host}::interface::${interface}::bond_master" => $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master},
|
|
"network::${local_host}::interface::${interface}::bridge_id" => $anvil->data->{network}{$local_host}{interface}{$interface}{bridge_id},
|
|
"network::${local_host}::interface::${interface}::bridge_stp_enabled" => $anvil->data->{network}{$local_host}{interface}{$interface}{bridge_stp_enabled},
|
|
"network::${local_host}::interface::${interface}::down_delay" => $anvil->data->{network}{$local_host}{interface}{$interface}{down_delay},
|
|
"network::${local_host}::interface::${interface}::duplex" => $anvil->data->{network}{$local_host}{interface}{$interface}{duplex},
|
|
"network::${local_host}::interface::${interface}::ip" => $anvil->data->{network}{$local_host}{interface}{$interface}{ip},
|
|
"network::${local_host}::interface::${interface}::link_state" => $anvil->data->{network}{$local_host}{interface}{$interface}{link_state},
|
|
"network::${local_host}::interface::${interface}::mac_address" => $anvil->data->{network}{$local_host}{interface}{$interface}{mac_address},
|
|
"network::${local_host}::interface::${interface}::media" => $anvil->data->{network}{$local_host}{interface}{$interface}{media},
|
|
"network::${local_host}::interface::${interface}::mii_polling_interval" => $anvil->data->{network}{$local_host}{interface}{$interface}{mii_polling_interval},
|
|
"network::${local_host}::interface::${interface}::mtu" => $anvil->data->{network}{$local_host}{interface}{$interface}{mtu},
|
|
"network::${local_host}::interface::${interface}::operational" => $anvil->data->{network}{$local_host}{interface}{$interface}{operational},
|
|
"network::${local_host}::interface::${interface}::primary_reselect" => $anvil->data->{network}{$local_host}{interface}{$interface}{primary_reselect},
|
|
"network::${local_host}::interface::${interface}::primary_interface" => $anvil->data->{network}{$local_host}{interface}{$interface}{primary_interface},
|
|
"network::${local_host}::interface::${interface}::speed" => $anvil->data->{network}{$local_host}{interface}{$interface}{speed},
|
|
"network::${local_host}::interface::${interface}::subnet_mask" => $anvil->data->{network}{$local_host}{interface}{$interface}{subnet_mask},
|
|
"network::${local_host}::interface::${interface}::type" => $anvil->data->{network}{$local_host}{interface}{$interface}{type},
|
|
"network::${local_host}::interface::${interface}::up_delay" => $anvil->data->{network}{$local_host}{interface}{$interface}{up_delay},
|
|
}});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"network::${local_host}::interface::${interface}::link_state" => $anvil->data->{network}{$local_host}{interface}{$interface}{link_state},
|
|
"network::${local_host}::interface::${interface}::operational" => $anvil->data->{network}{$local_host}{interface}{$interface}{operational},
|
|
}});
|
|
|
|
# If this is a link and there's no database connections, cache the data.
|
|
if (($type eq "interface") && (not $anvil->data->{sys}{database}{connections}))
|
|
{
|
|
$anvil->data->{cache}{new_file} .= $interface.",".$anvil->Database->refresh_timestamp.",".$mac_address.",".$speed.",".$link_state.",".$operational."\n";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"cache::new_file" => $anvil->data->{cache}{new_file},
|
|
}});
|
|
}
|
|
}
|
|
}
|
|
closedir(DIRECTORY);
|
|
|
|
# Find what interfaces are connected to which bridges
|
|
$anvil->Network->bridge_info({debug => 2});
|
|
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{$local_host}{interface}})
|
|
{
|
|
my $ip_address = $anvil->data->{network}{$local_host}{interface}{$interface}{ip};
|
|
my $type = $anvil->data->{network}{$local_host}{interface}{$interface}{type};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
interface => $interface,
|
|
ip_address => $ip_address,
|
|
type => $type,
|
|
}});
|
|
|
|
$anvil->data->{interface}{name_to_type}{$interface} = $type;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"interface::name_to_type::${interface}" => $anvil->data->{interface}{name_to_type}{$interface},
|
|
}});
|
|
|
|
if ($type eq "bridge")
|
|
{
|
|
# Store the bridge
|
|
$anvil->data->{new}{bridge}{$interface}{id} = $anvil->data->{network}{$local_host}{interface}{$interface}{bridge_id};
|
|
$anvil->data->{new}{bridge}{$interface}{mac_address} = $anvil->data->{network}{$local_host}{interface}{$interface}{mac_address};
|
|
$anvil->data->{new}{bridge}{$interface}{mtu} = $anvil->data->{network}{$local_host}{interface}{$interface}{mtu};
|
|
$anvil->data->{new}{bridge}{$interface}{stp_enabled} = $anvil->data->{network}{$local_host}{interface}{$interface}{bridge_stp_enabled};
|
|
$anvil->data->{new}{bridge}{$interface}{tx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes};
|
|
$anvil->data->{new}{bridge}{$interface}{rx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"new::bridge::${interface}::id" => $anvil->data->{new}{bridge}{$interface}{id},
|
|
"new::bridge::${interface}::mac_address" => $anvil->data->{new}{bridge}{$interface}{mac_address},
|
|
"new::bridge::${interface}::mtu" => $anvil->data->{new}{bridge}{$interface}{mtu},
|
|
"new::bridge::${interface}::stp_enabled" => $anvil->data->{new}{bridge}{$interface}{stp_enabled},
|
|
"new::bridge::${interface}::tx_bytes" => $anvil->data->{new}{bridge}{$interface}{tx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{bridge}{$interface}{tx_bytes}}).")",
|
|
"new::bridge::${interface}::rx_bytes" => $anvil->data->{new}{bridge}{$interface}{rx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{bridge}{$interface}{rx_bytes}}).")",
|
|
}});
|
|
}
|
|
elsif ($type eq "bond")
|
|
{
|
|
# Store the bond
|
|
$anvil->data->{new}{bond}{$interface}{mode} = $anvil->data->{network}{$local_host}{interface}{$interface}{bond_mode};
|
|
$anvil->data->{new}{bond}{$interface}{mtu} = $anvil->data->{network}{$local_host}{interface}{$interface}{mtu};
|
|
$anvil->data->{new}{bond}{$interface}{master} = $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master};
|
|
$anvil->data->{new}{bond}{$interface}{link_state} = $anvil->data->{network}{$local_host}{interface}{$interface}{link_state};
|
|
$anvil->data->{new}{bond}{$interface}{operational} = $anvil->data->{network}{$local_host}{interface}{$interface}{operational};
|
|
$anvil->data->{new}{bond}{$interface}{mac_address} = $anvil->data->{network}{$local_host}{interface}{$interface}{mac_address};
|
|
$anvil->data->{new}{bond}{$interface}{primary_interface} = $anvil->data->{network}{$local_host}{interface}{$interface}{primary_interface};
|
|
$anvil->data->{new}{bond}{$interface}{primary_reselect} = $anvil->data->{network}{$local_host}{interface}{$interface}{primary_reselect};
|
|
$anvil->data->{new}{bond}{$interface}{active_interface} = $anvil->data->{network}{$local_host}{interface}{$interface}{active_interface};
|
|
$anvil->data->{new}{bond}{$interface}{mii_polling_interval} = $anvil->data->{network}{$local_host}{interface}{$interface}{mii_polling_interval};
|
|
$anvil->data->{new}{bond}{$interface}{up_delay} = $anvil->data->{network}{$local_host}{interface}{$interface}{up_delay};
|
|
$anvil->data->{new}{bond}{$interface}{down_delay} = $anvil->data->{network}{$local_host}{interface}{$interface}{down_delay};
|
|
$anvil->data->{new}{bond}{$interface}{bridge_uuid} = ""; # We'll dig his out later as the bridge might not be in the database yet.
|
|
$anvil->data->{new}{bond}{$interface}{tx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes};
|
|
$anvil->data->{new}{bond}{$interface}{rx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"new::bond::${interface}::mode" => $anvil->data->{new}{bond}{$interface}{mode},
|
|
"new::bond::${interface}::mtu" => $anvil->data->{new}{bond}{$interface}{mtu},
|
|
"new::bond::${interface}::master" => $anvil->data->{new}{bond}{$interface}{master},
|
|
"new::bond::${interface}::link_state" => $anvil->data->{new}{bond}{$interface}{link_state},
|
|
"new::bond::${interface}::operational" => $anvil->data->{new}{bond}{$interface}{operational},
|
|
"new::bond::${interface}::mac_address" => $anvil->data->{new}{bond}{$interface}{mac_address},
|
|
"new::bond::${interface}::primary_interface" => $anvil->data->{new}{bond}{$interface}{primary_interface},
|
|
"new::bond::${interface}::primary_reselect" => $anvil->data->{new}{bond}{$interface}{primary_reselect},
|
|
"new::bond::${interface}::active_interface" => $anvil->data->{new}{bond}{$interface}{active_interface},
|
|
"new::bond::${interface}::mii_polling_interval" => $anvil->data->{new}{bond}{$interface}{mii_polling_interval},
|
|
"new::bond::${interface}::up_delay" => $anvil->data->{new}{bond}{$interface}{up_delay},
|
|
"new::bond::${interface}::down_delay" => $anvil->data->{new}{bond}{$interface}{down_delay},
|
|
"new::bond::${interface}::bridge_uuid" => $anvil->data->{new}{bond}{$interface}{bridge_uuid},
|
|
"new::bond::${interface}::tx_bytes" => $anvil->data->{new}{bond}{$interface}{tx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{bond}{$interface}{tx_bytes}}).")",
|
|
"new::bond::${interface}::rx_bytes" => $anvil->data->{new}{bond}{$interface}{rx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{bond}{$interface}{rx_bytes}}).")",
|
|
}});
|
|
}
|
|
elsif ($type eq "interface")
|
|
{
|
|
# Store the interface
|
|
$anvil->data->{new}{interface}{$interface}{bond_uuid} = "";
|
|
$anvil->data->{new}{interface}{$interface}{bond_name} = $anvil->data->{network}{$local_host}{interface}{$interface}{bond_master};
|
|
$anvil->data->{new}{interface}{$interface}{bridge_uuid} = "";
|
|
$anvil->data->{new}{interface}{$interface}{bridge_name} = "";
|
|
$anvil->data->{new}{interface}{$interface}{duplex} = $anvil->data->{network}{$local_host}{interface}{$interface}{duplex};
|
|
$anvil->data->{new}{interface}{$interface}{link_state} = $anvil->data->{network}{$local_host}{interface}{$interface}{link_state};
|
|
$anvil->data->{new}{interface}{$interface}{operational} = $anvil->data->{network}{$local_host}{interface}{$interface}{operational};
|
|
$anvil->data->{new}{interface}{$interface}{mac_address} = $anvil->data->{network}{$local_host}{interface}{$interface}{mac_address};
|
|
$anvil->data->{new}{interface}{$interface}{medium} = $anvil->data->{network}{$local_host}{interface}{$interface}{media};
|
|
$anvil->data->{new}{interface}{$interface}{mtu} = $anvil->data->{network}{$local_host}{interface}{$interface}{mtu};
|
|
$anvil->data->{new}{interface}{$interface}{speed} = $anvil->data->{network}{$local_host}{interface}{$interface}{speed};
|
|
$anvil->data->{new}{interface}{$interface}{tx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{tx_bytes};
|
|
$anvil->data->{new}{interface}{$interface}{rx_bytes} = $anvil->data->{network}{$local_host}{interface}{$interface}{rx_bytes};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"new::interface::${interface}::bond_uuid" => $anvil->data->{new}{interface}{$interface}{bond_uuid},
|
|
"new::interface::${interface}::bond_name" => $anvil->data->{new}{interface}{$interface}{bond_name},
|
|
"new::interface::${interface}::bridge_uuid" => $anvil->data->{new}{interface}{$interface}{bridge_uuid},
|
|
"new::interface::${interface}::bridge_name" => $anvil->data->{new}{interface}{$interface}{bridge_name},
|
|
"new::interface::${interface}::duplex" => $anvil->data->{new}{interface}{$interface}{duplex},
|
|
"new::interface::${interface}::link_state" => $anvil->data->{new}{interface}{$interface}{link_state},
|
|
"new::interface::${interface}::operational" => $anvil->data->{new}{interface}{$interface}{operational},
|
|
"new::interface::${interface}::mac_address" => $anvil->data->{new}{interface}{$interface}{mac_address},
|
|
"new::interface::${interface}::medium" => $anvil->data->{new}{interface}{$interface}{medium},
|
|
"new::interface::${interface}::mtu" => $anvil->data->{new}{interface}{$interface}{mtu},
|
|
"new::interface::${interface}::speed" => $anvil->data->{new}{interface}{$interface}{speed},
|
|
"new::interface::${interface}::tx_bytes" => $anvil->data->{new}{interface}{$interface}{tx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{interface}{$interface}{tx_bytes}}).")",
|
|
"new::interface::${interface}::rx_bytes" => $anvil->data->{new}{interface}{$interface}{rx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{new}{interface}{$interface}{rx_bytes}}).")",
|
|
}});
|
|
|
|
# On some occassions, an interface that is in a bond won't start. If the host uptime
|
|
# is less than ten minutes, and a bond's member interface is down, up it.
|
|
if ($uptime < 600)
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"nmcli::${local_host}::device_to_uuid::${interface}" => $anvil->data->{nmcli}{$local_host}{device_to_uuid}{$interface},
|
|
}});
|
|
my $uuid = $anvil->data->{nmcli}{$local_host}{device_to_uuid}{$interface};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid => $uuid }});
|
|
|
|
if ($uuid)
|
|
{
|
|
my $state = $anvil->data->{nmcli}{$local_host}{uuid}{$uuid}{'state'};
|
|
my $filename = $anvil->data->{nmcli}{$local_host}{uuid}{$uuid}{filename};
|
|
my $name = ($filename =~ /ifcfg-(.*?)$/)[0];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
filename => $filename,
|
|
name => $name,
|
|
'state' => $state,
|
|
}});
|
|
|
|
# This could be 'active' or 'activated'
|
|
if ($state !~ /activ/)
|
|
{
|
|
# Try brinding the interface up.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "warning_0147", variables => {
|
|
interface => $interface,
|
|
uptime => $uptime,
|
|
'state' => $state,
|
|
}});
|
|
|
|
my $shell_call = $anvil->data->{path}{exe}{ifup}." ".$name;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
output => $output,
|
|
return_code => $return_code,
|
|
}});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Record the IP address info.
|
|
if ($ip_address)
|
|
{
|
|
$anvil->data->{new}{ip_address}{$ip_address}{on_interface} = $interface;
|
|
$anvil->data->{new}{ip_address}{$ip_address}{subnet_mask} = $anvil->data->{network}{$local_host}{interface}{$interface}{subnet_mask};
|
|
$anvil->data->{new}{ip_address}{$ip_address}{gateway} = $anvil->data->{network}{$local_host}{interface}{$interface}{gateway};
|
|
$anvil->data->{new}{ip_address}{$ip_address}{default_gateway} = $anvil->data->{network}{$local_host}{interface}{$interface}{default_gateway};
|
|
$anvil->data->{new}{ip_address}{$ip_address}{dns} = $anvil->data->{network}{$local_host}{interface}{$interface}{dns};
|
|
$anvil->data->{new}{ip_address}{$ip_address}{on_uuid} = "";
|
|
$anvil->data->{new}{ip_address}{$ip_address}{note} = "";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"new::ip_address::${ip_address}::on_interface" => $anvil->data->{new}{ip_address}{$ip_address}{on_interface},
|
|
"new::ip_address::${ip_address}::subnet_mask" => $anvil->data->{new}{ip_address}{$ip_address}{subnet_mask},
|
|
"new::ip_address::${ip_address}::gateway" => $anvil->data->{new}{ip_address}{$ip_address}{gateway},
|
|
"new::ip_address::${ip_address}::default_gateway" => $anvil->data->{new}{ip_address}{$ip_address}{default_gateway},
|
|
"new::ip_address::${ip_address}::dns" => $anvil->data->{new}{ip_address}{$ip_address}{dns},
|
|
"new::ip_address::${ip_address}::on_uuid" => $anvil->data->{new}{ip_address}{$ip_address}{on_uuid},
|
|
"new::ip_address::${ip_address}::note" => $anvil->data->{new}{ip_address}{$ip_address}{note},
|
|
}});
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
# This reads in the states from the last can
|
|
sub read_last_scan
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
### NOTE: There is a bug somewhere where interfaces are periodically being added twice per host. This
|
|
### checks for / cleans those up. Remove this when the core issue is resolved.
|
|
clear_duplicates($anvil);
|
|
|
|
# Read in the old bridge data.
|
|
load_bridge_data($anvil);
|
|
load_bond_data($anvil);
|
|
load_interface_data($anvil);
|
|
load_ip_address_data($anvil);
|
|
|
|
return(0);
|
|
}
|
|
|
|
# There is a bug somewhere where interfaces, bridges and ip addresses are periodically being added twice per
|
|
# host. This checks for / cleans those up. Remove this when the core issue is resolved.
|
|
sub clear_duplicates
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Look for duplicate bridges.
|
|
my $query = "
|
|
SELECT
|
|
bridge_uuid,
|
|
bridge_name,
|
|
bridge_id,
|
|
bridge_mac_address
|
|
FROM
|
|
bridges
|
|
WHERE
|
|
bridge_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
|
|
ORDER BY
|
|
bridge_name ASC,
|
|
bridge_id DESC
|
|
;";
|
|
$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,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $bridge_uuid = $row->[0];
|
|
my $bridge_name = $row->[1];
|
|
my $bridge_id = $row->[2];
|
|
my $bridge_mac_address = $row->[3];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bridge_uuid => $bridge_uuid,
|
|
bridge_name => $bridge_name,
|
|
bridge_id => $bridge_id,
|
|
bridge_mac_address => $bridge_mac_address,
|
|
}});
|
|
|
|
if (not exists $anvil->data->{duplicate_bridges}{seen}{$bridge_name})
|
|
{
|
|
$anvil->data->{duplicate_bridges}{seen}{$bridge_name} = [];
|
|
}
|
|
push @{$anvil->data->{duplicate_bridges}{seen}{$bridge_name}}, $bridge_uuid;
|
|
|
|
$anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_name} = $bridge_name;
|
|
$anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_mac_address} = $bridge_mac_address;
|
|
$anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_id} = $bridge_id;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"duplicate_bridges::bridge_uuid::${bridge_uuid}::bridge_name" => $anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_name},
|
|
"duplicate_bridges::bridge_uuid::${bridge_uuid}::bridge_id" => $anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_id},
|
|
"duplicate_bridges::bridge_uuid::${bridge_uuid}::bridge_mac_address" => $anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_mac_address},
|
|
}});
|
|
|
|
$anvil->data->{deleted_bridges}{$bridge_uuid} = 0;
|
|
}
|
|
foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{duplicate_bridges}{seen}})
|
|
{
|
|
my $count = @{$anvil->data->{duplicate_bridges}{seen}{$bridge_name}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:bridge_name' => $bridge_name,
|
|
's2:count' => $count,
|
|
}});
|
|
|
|
if ($count > 1)
|
|
{
|
|
# Duplicate! Is one of them marked as DELETED?
|
|
foreach my $bridge_uuid (@{$anvil->data->{duplicate_bridges}{seen}{$bridge_name}})
|
|
{
|
|
# Is this one deleted?
|
|
my $bridge_mac_address = $anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_mac_address};
|
|
my $bridge_id = $anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_id};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bridge_uuid => $bridge_uuid,
|
|
bridge_mac_address => $anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_mac_address},
|
|
bridge_id => $anvil->data->{duplicate_bridges}{bridge_uuid}{$bridge_uuid}{bridge_id},
|
|
}});
|
|
if ($bridge_id eq "DELETED")
|
|
{
|
|
# Take this one out.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0685", variables => {
|
|
name => $bridge_name,
|
|
uuid => $bridge_uuid,
|
|
}});
|
|
|
|
# If there's a bond connected to this bridge, get it's bond_uuid so
|
|
# we can remove any interfaces linked to it.
|
|
my $bond_uuid = "";
|
|
my $query = "SELECT bond_uuid FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_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,
|
|
}});
|
|
if ($count)
|
|
{
|
|
$bond_uuid = $results->[0]->[0];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_uuid => $bond_uuid }});
|
|
}
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
if ($bond_uuid)
|
|
{
|
|
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
}
|
|
push @{$queries}, "DELETE FROM history.bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
push @{$queries}, "DELETE FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
push @{$queries}, "DELETE FROM history.bridges WHERE bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
push @{$queries}, "DELETE FROM bridges WHERE bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
|
|
# Write it out.
|
|
$anvil->Database->write({debug => 2, query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
|
|
$count--;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
|
|
$anvil->data->{deleted_bridges}{$bridge_uuid} = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"deleted_bridges::${bridge_uuid}" => $anvil->data->{deleted_bridges}{$bridge_uuid},
|
|
}});
|
|
}
|
|
last if $count == 1;
|
|
}
|
|
|
|
# If count is still > 1, we need to arbitrarily delete an interface.
|
|
if ($count > 1)
|
|
{
|
|
foreach my $bridge_uuid (@{$anvil->data->{duplicate_bridges}{seen}{$bridge_name}})
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0685", variables => {
|
|
name => $bridge_name,
|
|
uuid => $bridge_uuid,
|
|
}});
|
|
|
|
# If there's a bond connected to this bridge, get it's bond_uuid so
|
|
# we can remove any interfaces linked to it.
|
|
my $bond_uuid = "";
|
|
my $query = "SELECT bond_uuid FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_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,
|
|
}});
|
|
if ($count)
|
|
{
|
|
$bond_uuid = $results->[0]->[0];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_uuid => $bond_uuid }});
|
|
}
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
if ($bond_uuid)
|
|
{
|
|
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
}
|
|
push @{$queries}, "DELETE FROM history.bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
push @{$queries}, "DELETE FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
push @{$queries}, "DELETE FROM history.bridges WHERE bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
push @{$queries}, "DELETE FROM bridges WHERE bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
|
|
|
|
# Write it out.
|
|
$anvil->Database->write({debug => 2, query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
|
|
$count--;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
|
|
$anvil->data->{deleted_bridges}{$bridge_uuid} = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"deleted_bridges::${bridge_uuid}" => $anvil->data->{deleted_bridges}{$bridge_uuid},
|
|
}});
|
|
}
|
|
last if $count == 1;
|
|
}
|
|
}
|
|
}
|
|
delete $anvil->data->{duplicate_bridges};
|
|
|
|
# Load the bridges again.
|
|
$anvil->Database->get_bridges({include_deleted => 1});
|
|
|
|
# Look for duplicate bonds.
|
|
$query = "
|
|
SELECT
|
|
bond_uuid,
|
|
bond_name,
|
|
bond_operational,
|
|
bond_mac_address,
|
|
bond_bridge_uuid
|
|
FROM
|
|
bonds
|
|
WHERE
|
|
bond_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
|
|
ORDER BY
|
|
bond_name ASC,
|
|
bond_operational DESC
|
|
;";
|
|
$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 => 2, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $bond_uuid = $row->[0];
|
|
my $bond_name = $row->[1];
|
|
my $bond_operational = $row->[2];
|
|
my $bond_mac_address = $row->[3];
|
|
my $bond_bridge_uuid = defined $row->[4] ? $row->[4] : "";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bond_uuid => $bond_uuid,
|
|
bond_name => $bond_name,
|
|
bond_operational => $bond_operational,
|
|
bond_mac_address => $bond_mac_address,
|
|
bond_bridge_uuid => $bond_bridge_uuid,
|
|
}});
|
|
|
|
if (not exists $anvil->data->{duplicate_bonds}{seen}{$bond_name})
|
|
{
|
|
$anvil->data->{duplicate_bonds}{seen}{$bond_name} = [];
|
|
}
|
|
push @{$anvil->data->{duplicate_bonds}{seen}{$bond_name}}, $bond_uuid;
|
|
|
|
$anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_name} = $bond_name;
|
|
$anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_mac_address} = $bond_mac_address;
|
|
$anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_operational} = $bond_operational;
|
|
$anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_bridge_uuid} = $bond_bridge_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"duplicate_bonds::bond_uuid::${bond_uuid}::bond_name" => $anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_name},
|
|
"duplicate_bonds::bond_uuid::${bond_uuid}::bond_operational" => $anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_operational},
|
|
"duplicate_bonds::bond_uuid::${bond_uuid}::bond_mac_address" => $anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_mac_address},
|
|
"duplicate_bonds::bond_uuid::${bond_uuid}::bond_bridge_uuid" => $anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_bridge_uuid},
|
|
}});
|
|
|
|
$anvil->data->{deleted_bonds}{$bond_uuid} = 0;
|
|
}
|
|
foreach my $bond_name (sort {$a cmp $b} keys %{$anvil->data->{duplicate_bonds}{seen}})
|
|
{
|
|
my $count = @{$anvil->data->{duplicate_bonds}{seen}{$bond_name}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:bond_name' => $bond_name,
|
|
's2:count' => $count,
|
|
}});
|
|
|
|
if ($count > 1)
|
|
{
|
|
# Duplicate! Is one of them marked as DELETED?
|
|
foreach my $bond_uuid (@{$anvil->data->{duplicate_bonds}{seen}{$bond_name}})
|
|
{
|
|
# Is this one deleted?
|
|
my $bond_mac_address = $anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_mac_address};
|
|
my $bond_operational = $anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_operational};
|
|
my $bond_bridge_uuid = $anvil->data->{duplicate_bonds}{bond_uuid}{$bond_uuid}{bond_bridge_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bond_uuid => $bond_uuid,
|
|
bond_mac_address => $bond_mac_address,
|
|
bond_operational => $bond_operational,
|
|
bond_bridge_uuid => $bond_bridge_uuid,
|
|
}});
|
|
if ((($bond_bridge_uuid) && ($anvil->data->{deleted_bridges}{$bond_bridge_uuid})) or ($bond_operational eq "DELETED"))
|
|
{
|
|
# Take this one out.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0685", variables => {
|
|
name => $bond_name,
|
|
uuid => $bond_uuid,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
push @{$queries}, "DELETE FROM history.bonds WHERE bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
push @{$queries}, "DELETE FROM bonds WHERE bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
|
|
# Write it out.
|
|
$anvil->Database->write({debug => 2, query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
|
|
$count--;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
|
|
$anvil->data->{deleted_bonds}{$bond_uuid} = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"deleted_bonds::${bond_uuid}" => $anvil->data->{deleted_bonds}{$bond_uuid},
|
|
}});
|
|
}
|
|
}
|
|
|
|
# If count is still > 1, we need to arbitrarily delete an interface.
|
|
if ($count > 1)
|
|
{
|
|
foreach my $bond_uuid (@{$anvil->data->{duplicate_bonds}{seen}{$bond_name}})
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0685", variables => {
|
|
name => $bond_name,
|
|
uuid => $bond_uuid,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
push @{$queries}, "DELETE FROM history.bonds WHERE bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
push @{$queries}, "DELETE FROM bonds WHERE bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
|
|
|
|
# Write it out.
|
|
$anvil->Database->write({debug => 2, query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
|
|
$count--;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
|
|
$anvil->data->{deleted_bonds}{$bond_uuid} = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"deleted_bonds::${bond_uuid}" => $anvil->data->{deleted_bonds}{$bond_uuid},
|
|
}});
|
|
}
|
|
last if $count == 1;
|
|
}
|
|
}
|
|
}
|
|
delete $anvil->data->{duplicate_bonds};
|
|
|
|
|
|
# Look for duplicate network interfaces
|
|
$query = "
|
|
SELECT
|
|
network_interface_uuid,
|
|
network_interface_name,
|
|
network_interface_mac_address,
|
|
network_interface_operational,
|
|
network_interface_bond_uuid,
|
|
network_interface_bridge_uuid
|
|
FROM
|
|
network_interfaces
|
|
WHERE
|
|
network_interface_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
|
|
ORDER BY
|
|
network_interface_name ASC
|
|
;";
|
|
$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 => 2, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $network_interface_uuid = $row->[0];
|
|
my $network_interface_name = $row->[1];
|
|
my $network_interface_mac_address = $row->[2];
|
|
my $network_interface_operational = $row->[3];
|
|
my $network_interface_bond_uuid = defined $row->[4] ? $row->[4] : "";
|
|
my $network_interface_bridge_uuid = defined $row->[5] ? $row->[5] : "";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
network_interface_uuid => $network_interface_uuid,
|
|
network_interface_name => $network_interface_name,
|
|
network_interface_mac_address => $network_interface_mac_address,
|
|
network_interface_operational => $network_interface_operational,
|
|
network_interface_bond_uuid => $network_interface_bond_uuid,
|
|
network_interface_bridge_uuid => $network_interface_bridge_uuid,
|
|
}});
|
|
|
|
if (not exists $anvil->data->{duplicate_nics}{seen}{$network_interface_name})
|
|
{
|
|
$anvil->data->{duplicate_nics}{seen}{$network_interface_name} = [];
|
|
}
|
|
push @{$anvil->data->{duplicate_nics}{seen}{$network_interface_name}}, $network_interface_uuid;
|
|
|
|
$anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_name} = $network_interface_name;
|
|
$anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address} = $network_interface_mac_address;
|
|
$anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational} = $network_interface_operational;
|
|
$anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid} = $network_interface_bond_uuid;
|
|
$anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid} = $network_interface_bridge_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"duplicate_nics::network_interface_uuid::${network_interface_uuid}::network_interface_name" => $anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_name},
|
|
"duplicate_nics::network_interface_uuid::${network_interface_uuid}::network_interface_mac_address" => $anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address},
|
|
"duplicate_nics::network_interface_uuid::${network_interface_uuid}::network_interface_operational" => $anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational},
|
|
"duplicate_nics::network_interface_uuid::${network_interface_uuid}::network_interface_bond_uuid" => $anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid},
|
|
"duplicate_nics::network_interface_uuid::${network_interface_uuid}::network_interface_bridge_uuid" => $anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid},
|
|
}});
|
|
}
|
|
foreach my $network_interface_name (sort {$a cmp $b} keys %{$anvil->data->{duplicate_nics}{seen}})
|
|
{
|
|
my $count = @{$anvil->data->{duplicate_nics}{seen}{$network_interface_name}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:network_interface_name' => $network_interface_name,
|
|
's2:count' => $count,
|
|
}});
|
|
|
|
if ($count > 1)
|
|
{
|
|
# Duplicate! Is one of them marked as DELETED?
|
|
foreach my $network_interface_uuid (@{$anvil->data->{duplicate_nics}{seen}{$network_interface_name}})
|
|
{
|
|
# Is this one deleted?
|
|
my $network_interface_mac_address = $anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address};
|
|
my $network_interface_operational = $anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational};
|
|
my $network_interface_bond_uuid = $anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid};
|
|
my $network_interface_bridge_uuid = $anvil->data->{duplicate_nics}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
network_interface_uuid => $network_interface_uuid,
|
|
network_interface_mac_address => $network_interface_mac_address,
|
|
network_interface_operational => $network_interface_operational,
|
|
network_interface_bond_uuid => $network_interface_bond_uuid,
|
|
network_interface_bridge_uuid => $network_interface_bridge_uuid,
|
|
}});
|
|
if ((($network_interface_bond_uuid) && ($anvil->data->{deleted_bonds}{$network_interface_bond_uuid})) or
|
|
(($network_interface_bridge_uuid) && ($anvil->data->{deleted_bridges}{$network_interface_bridge_uuid})) or
|
|
($network_interface_operational eq "DELETED"))
|
|
{
|
|
# Take this one out.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0647", variables => {
|
|
name => $network_interface_name,
|
|
uuid => $network_interface_uuid,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_uuid = ".$anvil->Database->quote($network_interface_uuid).";";
|
|
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_uuid = ".$anvil->Database->quote($network_interface_uuid).";";
|
|
foreach my $query (@{$queries})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
}
|
|
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
|
|
$count--;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
}
|
|
}
|
|
|
|
# If count is still > 1, we need to arbitrarily delete an interface.
|
|
if ($count > 1)
|
|
{
|
|
foreach my $network_interface_uuid (@{$anvil->data->{duplicate_nics}{seen}{$network_interface_name}})
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0647", variables => {
|
|
name => $network_interface_name,
|
|
uuid => $network_interface_uuid,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_uuid = ".$anvil->Database->quote($network_interface_uuid).";";
|
|
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_uuid = ".$anvil->Database->quote($network_interface_uuid).";";
|
|
foreach my $query (@{$queries})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
}
|
|
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
|
|
$count--;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
}
|
|
last if $count == 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete $anvil->data->{duplicate_nics};
|
|
|
|
$query = "
|
|
SELECT
|
|
ip_address_uuid,
|
|
ip_address_address,
|
|
ip_address_note
|
|
FROM
|
|
ip_addresses
|
|
WHERE
|
|
ip_address_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
|
|
ORDER BY
|
|
ip_address_address ASC
|
|
;";
|
|
$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 => 2, list => {
|
|
results => $results,
|
|
count => $count,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $ip_address_uuid = $row->[0];
|
|
my $ip_address_address = $row->[1];
|
|
my $ip_address_note = $row->[2];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
ip_address_uuid => $ip_address_uuid,
|
|
ip_address_address => $ip_address_address,
|
|
ip_address_note => $ip_address_note,
|
|
}});
|
|
|
|
if (not exists $anvil->data->{duplicate_ips}{seen}{$ip_address_address})
|
|
{
|
|
$anvil->data->{duplicate_ips}{seen}{$ip_address_address} = [];
|
|
}
|
|
push @{$anvil->data->{duplicate_ips}{seen}{$ip_address_address}}, $ip_address_uuid;
|
|
|
|
$anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_address} = $ip_address_address;
|
|
$anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_note} = $ip_address_note;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"duplicate_ips::ip_address_uuid::${ip_address_uuid}::ip_address_address" => $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_address},
|
|
"duplicate_ips::ip_address_uuid::${ip_address_uuid}::ip_address_note" => $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_note},
|
|
}});
|
|
}
|
|
foreach my $ip_address_address (sort {$a cmp $b} keys %{$anvil->data->{duplicate_ips}{seen}})
|
|
{
|
|
my $count = @{$anvil->data->{duplicate_ips}{seen}{$ip_address_address}};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
's1:ip_address_address' => $ip_address_address,
|
|
's2:count' => $count,
|
|
}});
|
|
|
|
if ($count > 1)
|
|
{
|
|
# Duplicate! Is one of them marked as DELETED?
|
|
foreach my $ip_address_uuid (@{$anvil->data->{duplicate_ips}{seen}{$ip_address_address}})
|
|
{
|
|
# Is this one deleted?
|
|
my $ip_address_note = $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_note};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
ip_address_uuid => $ip_address_uuid,
|
|
ip_address_note => $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_note},
|
|
}});
|
|
if ($ip_address_note eq "DELETED")
|
|
{
|
|
# Take this one out.
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0664", variables => {
|
|
ip => $ip_address_address,
|
|
uuid => $ip_address_uuid,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.ip_addresses WHERE ip_address_uuid = ".$anvil->Database->quote($ip_address_uuid).";";
|
|
push @{$queries}, "DELETE FROM ip_addresses WHERE ip_address_uuid = ".$anvil->Database->quote($ip_address_uuid).";";
|
|
foreach my $query (@{$queries})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
}
|
|
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
|
|
$count--;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
}
|
|
last if $count == 1;
|
|
}
|
|
|
|
# If count is still > 1, we need to arbitrarily delete an interface.
|
|
if ($count > 1)
|
|
{
|
|
foreach my $ip_address_uuid (@{$anvil->data->{duplicate_ips}{seen}{$ip_address_address}})
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0664", variables => {
|
|
ip => $ip_address_address,
|
|
uuid => $ip_address_uuid,
|
|
}});
|
|
|
|
my $queries = [];
|
|
push @{$queries}, "DELETE FROM history.ip_addresses WHERE ip_address_uuid = ".$anvil->Database->quote($ip_address_uuid).";";
|
|
push @{$queries}, "DELETE FROM ip_addresses WHERE ip_address_uuid = ".$anvil->Database->quote($ip_address_uuid).";";
|
|
foreach my $query (@{$queries})
|
|
{
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
|
}
|
|
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
|
|
|
|
$count--;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
|
|
}
|
|
last if $count == 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub load_ip_address_data
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Now record the IPs.
|
|
my $query = "
|
|
SELECT
|
|
ip_address_uuid,
|
|
ip_address_on_type,
|
|
ip_address_on_uuid,
|
|
ip_address_address,
|
|
ip_address_subnet_mask,
|
|
ip_address_gateway,
|
|
ip_address_default_gateway,
|
|
ip_address_dns,
|
|
ip_address_note
|
|
FROM
|
|
ip_addresses
|
|
WHERE
|
|
ip_address_host_uuid = ".$anvil->Database->quote($anvil->data->{sys}{host_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,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $ip_address_uuid = $row->[0];
|
|
my $ip_address_on_type = $row->[1];
|
|
my $ip_address_address = $row->[3];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
ip_address_uuid => $ip_address_uuid,
|
|
ip_address_on_type => $ip_address_on_type,
|
|
ip_address_address => $ip_address_address,
|
|
}});
|
|
|
|
$anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_on_type} = $ip_address_on_type;
|
|
$anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_on_uuid} = $row->[2];
|
|
$anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_address} = $ip_address_address;
|
|
$anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_subnet_mask} = $row->[4];
|
|
$anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_gateway} = $row->[5];
|
|
$anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_default_gateway} = $row->[6];
|
|
$anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_dns} = $row->[7];
|
|
$anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_note} = $row->[8];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"old::ip_addresses::ip_address_uuid::${ip_address_uuid}::ip_address_on_type" => $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_on_type},
|
|
"old::ip_addresses::ip_address_uuid::${ip_address_uuid}::ip_address_on_uuid" => $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_on_uuid},
|
|
"old::ip_addresses::ip_address_uuid::${ip_address_uuid}::ip_address_address" => $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_address},
|
|
"old::ip_addresses::ip_address_uuid::${ip_address_uuid}::ip_address_subnet_mask" => $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_subnet_mask},
|
|
"old::ip_addresses::ip_address_uuid::${ip_address_uuid}::ip_address_gateway" => $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_gateway},
|
|
"old::ip_addresses::ip_address_uuid::${ip_address_uuid}::ip_address_default_gateway" => $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_default_gateway},
|
|
"old::ip_addresses::ip_address_uuid::${ip_address_uuid}::ip_address_dns" => $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_dns},
|
|
"old::ip_addresses::ip_address_uuid::${ip_address_uuid}::ip_address_note" => $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_note},
|
|
}});
|
|
|
|
$anvil->data->{old}{ip_addresses}{ip_to_uuid}{$ip_address_address} = $ip_address_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"old::ip_addresses::ip_to_uuid::${ip_address_address}" => $anvil->data->{old}{ip_addresses}{ip_to_uuid}{$ip_address_address},
|
|
}});
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub load_interface_data
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Process interfaces
|
|
my $query = "
|
|
SELECT
|
|
network_interface_uuid,
|
|
network_interface_mac_address,
|
|
network_interface_name,
|
|
network_interface_speed,
|
|
network_interface_mtu,
|
|
network_interface_link_state,
|
|
network_interface_operational,
|
|
network_interface_duplex,
|
|
network_interface_medium,
|
|
network_interface_bond_uuid,
|
|
network_interface_bridge_uuid
|
|
FROM
|
|
network_interfaces
|
|
WHERE
|
|
network_interface_host_uuid = ".$anvil->Database->quote($anvil->Get->host_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,
|
|
}});
|
|
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $network_interface_uuid = $row->[0];
|
|
my $network_interface_mac_address = $row->[1];
|
|
my $network_interface_name = $row->[2];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
network_interface_uuid => $network_interface_uuid,
|
|
network_interface_mac_address => $network_interface_mac_address,
|
|
network_interface_name => $network_interface_name,
|
|
}});
|
|
|
|
# Read in the RX/TX values, set to '0' if not found.
|
|
my ($rx_bytes, $rx_variable_uuid, $modified_date) = $anvil->Database->read_variable({
|
|
variable_name => "network_interface::".$network_interface_name."::rx_bytes",
|
|
variable_source_uuid => $network_interface_uuid,
|
|
variable_source_table => "network_interfaces",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
rx_bytes => $rx_bytes,
|
|
rx_variable_uuid => $rx_variable_uuid,
|
|
}});
|
|
(my $tx_bytes, my $tx_variable_uuid, $modified_date) = $anvil->Database->read_variable({
|
|
variable_name => "network_interface::".$network_interface_name."::tx_bytes",
|
|
variable_source_uuid => $network_interface_uuid,
|
|
variable_source_table => "network_interfaces",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
tx_bytes => $tx_bytes,
|
|
tx_variable_uuid => $tx_variable_uuid,
|
|
}});
|
|
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address} = $network_interface_mac_address;
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name} = $network_interface_name;
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_speed} = $row->[3];
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mtu} = $row->[4];
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_link_state} = $row->[5];
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational} = $row->[6];
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_duplex} = $row->[7];
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_medium} = $row->[8];
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid} = defined $row->[9] ? $row->[9] : '';
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid} = defined $row->[10] ? $row->[10] : '';
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_bytes} = $rx_bytes =~ /^\d+$/ ? $rx_bytes : 0;
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_variable_uuid} = $rx_variable_uuid;
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_bytes} = $tx_bytes =~ /^\d+$/ ? $tx_bytes : 0;
|
|
$anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_variable_uuid} = $tx_variable_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_mac_address" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_name" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_speed" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_speed},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_mtu" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mtu},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_link_state" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_link_state},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_operational" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_duplex" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_duplex},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_medium" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_medium},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_bond_uuid" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_bridge_uuid" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::rx_bytes" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_bytes}}).")",
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::rx_variable_uuid" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_variable_uuid},
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::tx_bytes" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_bytes}}).")",
|
|
"old::network_interfaces::network_interface_uuid::${network_interface_uuid}::tx_variable_uuid" => $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_variable_uuid},
|
|
}});
|
|
|
|
$anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name} = $network_interface_uuid;
|
|
$anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid} = $network_interface_name;
|
|
$anvil->data->{network_interfaces}{mac_to_uuid}{$network_interface_mac_address} = $network_interface_uuid;
|
|
$anvil->data->{interface}{name_to_uuid}{$network_interface_name} = $network_interface_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"network_interfaces::name_to_uuid::${network_interface_name}" => $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name},
|
|
"network_interfaces::uuid_to_name::${network_interface_name}" => $anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid},
|
|
"network_interfaces::mac_to_uuid::${network_interface_mac_address}" => $anvil->data->{network_interfaces}{mac_to_uuid}{$network_interface_mac_address},
|
|
"interface::name_to_uuid::${network_interface_name}" => $anvil->data->{interface}{name_to_uuid}{$network_interface_name},
|
|
}});
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub load_bond_data
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# 'bond_mode' will be 'DELETED' if the bond was removed.
|
|
my $query = "
|
|
SELECT
|
|
bond_uuid,
|
|
bond_name,
|
|
bond_mode,
|
|
bond_mtu,
|
|
bond_primary_interface,
|
|
bond_primary_reselect,
|
|
bond_active_interface,
|
|
bond_mii_polling_interval,
|
|
bond_up_delay,
|
|
bond_down_delay,
|
|
bond_mac_address,
|
|
bond_operational,
|
|
bond_bridge_uuid
|
|
FROM
|
|
bonds
|
|
WHERE
|
|
bond_host_uuid = ".$anvil->Database->quote($anvil->Get->host_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,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $bond_uuid = $row->[0];
|
|
my $bond_name = $row->[1];
|
|
my $bond_bridge_uuid = defined $row->[12] ? $row->[12] : "";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bond_uuid => $bond_uuid,
|
|
bond_name => $bond_name,
|
|
bond_bridge_uuid => $bond_bridge_uuid,
|
|
}});
|
|
|
|
# Read in the RX/TX values, set to '0' if not found.
|
|
my ($rx_bytes, $rx_variable_uuid, $modified_date) = $anvil->Database->read_variable({
|
|
variable_name => "bond::".$bond_name."::rx_bytes",
|
|
variable_source_uuid => $bond_uuid,
|
|
variable_source_table => "bonds",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
rx_bytes => $rx_bytes,
|
|
rx_variable_uuid => $rx_variable_uuid,
|
|
}});
|
|
(my $tx_bytes, my $tx_variable_uuid, $modified_date) = $anvil->Database->read_variable({
|
|
variable_name => "bond::".$bond_name."::tx_bytes",
|
|
variable_source_uuid => $bond_uuid,
|
|
variable_source_table => "bonds",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
tx_bytes => $tx_bytes,
|
|
tx_variable_uuid => $tx_variable_uuid,
|
|
}});
|
|
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_name} = $bond_name;
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mode} = $row->[2];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mtu} = $row->[3];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_primary_interface} = $row->[4];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_primary_reselect} = $row->[5];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_active_interface} = $row->[6];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mii_polling_interval} = $row->[7];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_up_delay} = $row->[8];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_down_delay} = $row->[9];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mac_address} = $row->[10];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_operational} = $row->[11];
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_bridge_uuid} = $bond_bridge_uuid;
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{rx_bytes} = $rx_bytes =~ /\d/ ? $rx_bytes : 0;
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{rx_variable_uuid} = $rx_variable_uuid;
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{tx_bytes} = $tx_bytes =~ /\d/ ? $tx_bytes : 0;
|
|
$anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{tx_variable_uuid} = $tx_variable_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_name" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_name},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_mode" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mode},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_mtu" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mtu},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_primary_interface" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_primary_interface},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_primary_reselect" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_primary_reselect},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_active_interface" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_active_interface},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_mii_polling_interval" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mii_polling_interval},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_up_delay" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_up_delay},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_down_delay" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_down_delay},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_mac_address" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mac_address},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_operational" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_operational},
|
|
"old::bonds::bond_uuid::${bond_uuid}::bond_bridge_uuid" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_bridge_uuid},
|
|
"old::bonds::bond_uuid::${bond_uuid}::rx_bytes" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{rx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{rx_bytes}}).")",
|
|
"old::bonds::bond_uuid::${bond_uuid}::rx_variable_uuid" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{rx_variable_uuid},
|
|
"old::bonds::bond_uuid::${bond_uuid}::tx_bytes" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{tx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{tx_bytes}}).")",
|
|
"old::bonds::bond_uuid::${bond_uuid}::tx_variable_uuid" => $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{tx_variable_uuid},
|
|
}});
|
|
|
|
$anvil->data->{bonds}{name_to_uuid}{$bond_name} = $bond_uuid;
|
|
$anvil->data->{bonds}{uuid_to_name}{$bond_uuid} = $bond_name;
|
|
$anvil->data->{interface}{name_to_uuid}{$bond_name} = $bond_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"bonds::name_to_uuid::${bond_name}" => $anvil->data->{bonds}{name_to_uuid}{$bond_name},
|
|
"bonds::uuid_to_name::${bond_uuid}" => $anvil->data->{bonds}{uuid_to_name}{$bond_uuid},
|
|
"interface::name_to_uuid::${bond_name}" => $anvil->data->{interface}{name_to_uuid}{$bond_name},
|
|
}});
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
sub load_bridge_data
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# The 'bridge_id' will be DELETED if the bridge was removed earlier.
|
|
my $query = "
|
|
SELECT
|
|
bridge_uuid,
|
|
bridge_name,
|
|
bridge_id,
|
|
bridge_mac_address,
|
|
bridge_mtu,
|
|
bridge_stp_enabled
|
|
FROM
|
|
bridges
|
|
WHERE
|
|
bridge_host_uuid = ".$anvil->Database->quote($anvil->Get->host_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,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
my $bridge_uuid = $row->[0];
|
|
my $bridge_name = $row->[1];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bridge_uuid => $bridge_uuid,
|
|
bridge_name => $bridge_name,
|
|
}});
|
|
|
|
# Read in the RX/TX values, set to '0' if not found.
|
|
my ($rx_bytes, $rx_variable_uuid, $modified_date) = $anvil->Database->read_variable({
|
|
variable_name => "bridge::".$bridge_name."::rx_bytes",
|
|
variable_source_uuid => $bridge_uuid,
|
|
variable_source_table => "bridges",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
rx_bytes => $rx_bytes,
|
|
rx_variable_uuid => $rx_variable_uuid,
|
|
}});
|
|
(my $tx_bytes, my $tx_variable_uuid, $modified_date) = $anvil->Database->read_variable({
|
|
variable_name => "bridge::".$bridge_name."::tx_bytes",
|
|
variable_source_uuid => $bridge_uuid,
|
|
variable_source_table => "bridges",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
tx_bytes => $tx_bytes,
|
|
tx_variable_uuid => $tx_variable_uuid,
|
|
}});
|
|
|
|
# Record the data in the hash, too.
|
|
$anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_name} = $bridge_name;
|
|
$anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_id} = $row->[2];
|
|
$anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_mac_address} = $row->[3];
|
|
$anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_mtu} = $row->[4];
|
|
$anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_stp_enabled} = $row->[5];
|
|
$anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{rx_bytes} = $rx_bytes =~ /\d/ ? $rx_bytes : 0;
|
|
$anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{rx_variable_uuid} = $rx_variable_uuid;
|
|
$anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{tx_bytes} = $tx_bytes =~ /\d/ ? $tx_bytes : 0;
|
|
$anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{tx_variable_uuid} = $tx_variable_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"old::bridges::bridge_uuid::${bridge_uuid}::bridge_name" => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_name},
|
|
"old::bridges::bridge_uuid::${bridge_uuid}::bridge_id" => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_id},
|
|
"old::bridges::bridge_uuid::${bridge_uuid}::bridge_mac_address" => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_mac_address},
|
|
"old::bridges::bridge_uuid::${bridge_uuid}::bridge_mtu" => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_mtu},
|
|
"old::bridges::bridge_uuid::${bridge_uuid}::bridge_stp_enabled" => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_stp_enabled},
|
|
"old::bridges::bridge_uuid::${bridge_uuid}::rx_bytes" => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{rx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{rx_bytes}}).")",
|
|
"old::bridges::bridge_uuid::${bridge_uuid}::rx_variable_uuid" => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{rx_variable_uuid},
|
|
"old::bridges::bridge_uuid::${bridge_uuid}::tx_bytes" => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{tx_bytes}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{tx_bytes}}).")",
|
|
"old::bridges::bridge_uuid::${bridge_uuid}::tx_variable_uuid" => $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{tx_variable_uuid},
|
|
}});
|
|
|
|
$anvil->data->{bridges}{name_to_uuid}{$bridge_name} = $bridge_uuid;
|
|
$anvil->data->{bridges}{uuid_to_name}{$bridge_uuid} = $bridge_name;
|
|
$anvil->data->{interface}{name_to_uuid}{$bridge_name} = $bridge_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"bridges::name_to_uuid::${bridge_name}" => $anvil->data->{bridges}{name_to_uuid}{$bridge_name},
|
|
"bridges::uuid_to_name::${bridge_uuid}" => $anvil->data->{bridges}{uuid_to_name}{$bridge_uuid},
|
|
"interface::name_to_uuid::${bridge_name}" => $anvil->data->{interface}{name_to_uuid}{$bridge_name},
|
|
}});
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
# This compares the last scan and the read state info and handles changes.
|
|
sub find_changes
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
check_bridges($anvil);
|
|
check_bonds($anvil);
|
|
check_interfaces($anvil);
|
|
check_ip_addresses($anvil);
|
|
|
|
return(0);
|
|
}
|
|
|
|
# Handle IP addresses
|
|
sub check_ip_addresses
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
foreach my $ip_address (sort {$a cmp $b} keys %{$anvil->data->{new}{ip_address}})
|
|
{
|
|
my $on_interface = $anvil->data->{new}{ip_address}{$ip_address}{on_interface};
|
|
my $new_on_type = $anvil->data->{interface}{name_to_type}{$on_interface};
|
|
my $new_on_uuid = $anvil->data->{interface}{name_to_uuid}{$on_interface};
|
|
my $new_subnet_mask = $anvil->data->{new}{ip_address}{$ip_address}{subnet_mask};
|
|
my $new_gateway = $anvil->data->{new}{ip_address}{$ip_address}{gateway};
|
|
my $new_default_gateway = $anvil->data->{new}{ip_address}{$ip_address}{default_gateway};
|
|
my $new_dns = $anvil->data->{new}{ip_address}{$ip_address}{dns};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
ip_address => $ip_address,
|
|
on_interface => $on_interface,
|
|
new_on_type => $new_on_type,
|
|
new_on_uuid => $new_on_uuid,
|
|
new_subnet_mask => $new_subnet_mask,
|
|
new_gateway => $new_gateway,
|
|
new_default_gateway => $new_default_gateway,
|
|
new_dns => $new_dns,
|
|
}});
|
|
|
|
if (exists $anvil->data->{old}{ip_addresses}{ip_to_uuid}{$ip_address})
|
|
{
|
|
# Existing, update?
|
|
my $ip_address_uuid = $anvil->data->{old}{ip_addresses}{ip_to_uuid}{$ip_address};
|
|
my $old_on_type = $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_on_type};
|
|
my $old_on_uuid = $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_on_uuid};
|
|
my $old_subnet_mask = $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_subnet_mask};
|
|
my $old_gateway = $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_gateway};
|
|
my $old_default_gateway = $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_default_gateway};
|
|
my $old_dns = $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_dns};
|
|
my $old_note = $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_note};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
ip_address => $ip_address,
|
|
old_on_type => $old_on_type,
|
|
old_on_uuid => $old_on_uuid,
|
|
old_subnet_mask => $old_subnet_mask,
|
|
old_gateway => $old_gateway,
|
|
old_default_gateway => $old_default_gateway,
|
|
old_dns => $old_dns,
|
|
old_note => $old_note,
|
|
}});
|
|
|
|
# Delete this old entry so we know we've processed it.
|
|
delete $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid};
|
|
|
|
my $say_old_interface = "--";
|
|
if ($old_on_type eq "bridge")
|
|
{
|
|
$say_old_interface = $anvil->data->{bridges}{uuid_to_name}{$old_on_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_old_interface => $say_old_interface }});
|
|
}
|
|
elsif ($old_on_type eq "bond")
|
|
{
|
|
$say_old_interface = $anvil->data->{bonds}{uuid_to_name}{$old_on_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_old_interface => $say_old_interface }});
|
|
}
|
|
elsif ($old_on_type eq "interface")
|
|
{
|
|
$say_old_interface = $anvil->data->{network_interfaces}{uuid_to_name}{$old_on_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_old_interface => $say_old_interface }});
|
|
}
|
|
|
|
# Now look for changes.
|
|
my $changes = 0;
|
|
|
|
# These will always change together.
|
|
if (($new_on_type ne $old_on_type) or ($new_on_uuid ne $old_on_uuid))
|
|
{
|
|
# This was likely changed by an admin, so it's a notice level alert.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
ip_address => $ip_address,
|
|
old => $say_old_interface,
|
|
new => $on_interface,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0050", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0050",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_subnet_mask ne $old_subnet_mask)
|
|
{
|
|
# This was likely changed by an admin, so it's a notice level alert.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
ip_address => $ip_address,
|
|
interface => $on_interface,
|
|
old => $ip_address."/".$old_subnet_mask,
|
|
new => $ip_address."/".$new_subnet_mask,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0051", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0051",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_gateway ne $old_gateway)
|
|
{
|
|
# This was likely changed by an admin, so it's a notice level alert.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
ip_address => $ip_address,
|
|
interface => $on_interface,
|
|
old => $old_gateway eq "" ? "--" : $old_gateway,
|
|
new => $new_gateway eq "" ? "--" : $new_gateway,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0052", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0052",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_default_gateway ne $old_default_gateway)
|
|
{
|
|
# This was likely changed by an admin, so it's a notice level alert.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
ip_address => $ip_address,
|
|
interface => $on_interface,
|
|
old => $old_default_gateway ? "#!string!unit_0001!#" : "#!string!unit_0002!#",
|
|
new => $new_default_gateway ? "#!string!unit_0001!#" : "#!string!unit_0002!#",
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0053", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0053",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_dns ne $old_dns)
|
|
{
|
|
# This was likely changed by an admin, so it's a notice level alert.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
ip_address => $ip_address,
|
|
interface => $on_interface,
|
|
old => $old_dns eq "" ? "--" : $old_dns,
|
|
new => $new_dns eq "" ? "--" : $new_dns,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0054", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0054",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
|
|
# We only care about 'old_note' if it's set to 'DELETED'.
|
|
if ($old_note eq "DELETED")
|
|
{
|
|
# This was likely changed by an admin, so it's a notice level alert.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
ip_address => $ip_address,
|
|
interface => $on_interface,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0055", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0055",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
|
|
if ($changes)
|
|
{
|
|
# If the note was 'DELETED', change it to ''. Otherwise, use the old note.
|
|
$old_note = "" if $old_note eq "DELETED";
|
|
my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({
|
|
debug => 2,
|
|
ip_address_uuid => $ip_address_uuid,
|
|
ip_address_on_type => $new_on_type,
|
|
ip_address_on_uuid => $new_on_uuid,
|
|
ip_address_address => $ip_address,
|
|
ip_address_subnet_mask => $new_subnet_mask,
|
|
ip_address_gateway => $new_gateway,
|
|
ip_address_default_gateway => $new_default_gateway,
|
|
ip_address_dns => $new_dns,
|
|
ip_address_note => $old_note,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ip_address_uuid => $ip_address_uuid }});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# New, store.
|
|
my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({
|
|
debug => 2,
|
|
ip_address_on_type => $new_on_type,
|
|
ip_address_on_uuid => $new_on_uuid,
|
|
ip_address_address => $ip_address,
|
|
ip_address_subnet_mask => $new_subnet_mask,
|
|
ip_address_gateway => $new_gateway,
|
|
ip_address_default_gateway => $new_default_gateway,
|
|
ip_address_dns => $new_dns,
|
|
ip_address_note => "",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ip_address_uuid => $ip_address_uuid }});
|
|
|
|
# Register a notice level alert.
|
|
my $variables = {
|
|
ip_address => $ip_address,
|
|
interface => $on_interface,
|
|
subnet_mask => $new_subnet_mask,
|
|
gateway => $new_gateway eq "" ? "--" : $new_gateway,
|
|
default_gateway => $new_default_gateway ? "#!string!unit_0001!#" : "#!string!unit_0002!#",
|
|
dns => $new_dns eq "" ? "--" : $new_dns,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0056", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0056",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
}
|
|
|
|
# Look for left over / deleted bonds.
|
|
foreach my $ip_address_uuid (keys %{$anvil->data->{old}{ip_addresses}{ip_address_uuid}})
|
|
{
|
|
# Skip if already deleted.
|
|
next if $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_note} eq "DELETED";
|
|
|
|
my $ip_address_address = $anvil->data->{old}{ip_addresses}{ip_address_uuid}{$ip_address_uuid}{ip_address_address};
|
|
|
|
my $variables = { ip => $ip_address_address };
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0060", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0060",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
|
|
my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({
|
|
debug => 2,
|
|
ip_address_uuid => $ip_address_uuid,
|
|
'delete' => 1,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ip_address_uuid => $ip_address_uuid }});
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
# Look for changes in network interfaces.
|
|
sub check_interfaces
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
foreach my $network_interface_name (sort {$a cmp $b} keys %{$anvil->data->{new}{interface}})
|
|
{
|
|
my $new_bond_uuid = $anvil->data->{new}{interface}{$network_interface_name}{bond_uuid};
|
|
my $new_bond_name = $anvil->data->{new}{interface}{$network_interface_name}{bond_name};
|
|
my $new_bridge_uuid = $anvil->data->{new}{interface}{$network_interface_name}{bridge_uuid};
|
|
my $new_bridge_name = $anvil->data->{new}{interface}{$network_interface_name}{bridge_name};
|
|
my $new_duplex = $anvil->data->{new}{interface}{$network_interface_name}{duplex};
|
|
my $new_link_state = $anvil->data->{new}{interface}{$network_interface_name}{link_state};
|
|
my $new_operational = $anvil->data->{new}{interface}{$network_interface_name}{operational};
|
|
my $new_mac_address = $anvil->data->{new}{interface}{$network_interface_name}{mac_address};
|
|
my $new_medium = $anvil->data->{new}{interface}{$network_interface_name}{medium};
|
|
my $new_mtu = $anvil->data->{new}{interface}{$network_interface_name}{mtu};
|
|
my $new_speed = $anvil->data->{new}{interface}{$network_interface_name}{speed};
|
|
my $new_tx_bytes = $anvil->data->{new}{interface}{$network_interface_name}{tx_bytes};
|
|
my $new_rx_bytes = $anvil->data->{new}{interface}{$network_interface_name}{rx_bytes};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
network_interface_name => $network_interface_name,
|
|
new_bond_uuid => $new_bond_uuid,
|
|
new_bond_name => $new_bond_name,
|
|
new_bridge_uuid => $new_bridge_uuid,
|
|
new_bridge_name => $new_bridge_name,
|
|
new_duplex => $new_duplex,
|
|
new_link_state => $new_link_state,
|
|
new_operational => $new_operational,
|
|
new_mac_address => $new_mac_address,
|
|
new_medium => $new_medium,
|
|
new_mtu => $new_mtu,
|
|
new_speed => $new_speed,
|
|
new_tx_bytes => $new_tx_bytes,
|
|
new_rx_bytes => $new_rx_bytes,
|
|
}});
|
|
|
|
# Find the bridge, if any, and the bond UUID, if there's a bond name.
|
|
if ($new_bond_name)
|
|
{
|
|
$new_bond_uuid = $anvil->data->{bonds}{name_to_uuid}{$new_bond_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_bond_uuid => $new_bond_uuid }});
|
|
}
|
|
if (exists $anvil->data->{interface_to_bridge}{$network_interface_name})
|
|
{
|
|
# This interface is on a bridge
|
|
$new_bridge_name = $anvil->data->{interface_to_bridge}{$network_interface_name};
|
|
$new_bridge_uuid = $anvil->data->{bridges}{name_to_uuid}{$new_bridge_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
new_bridge_name => $new_bridge_name,
|
|
new_bridge_uuid => $new_bridge_uuid,
|
|
}});
|
|
}
|
|
|
|
# New or existing?
|
|
if (exists $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name})
|
|
{
|
|
# Existing. Changes?
|
|
my $network_interface_uuid = $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name};
|
|
my $old_bond_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bond_uuid};
|
|
my $old_bond_name = "";
|
|
my $old_bridge_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_bridge_uuid};
|
|
my $old_bridge_name = "";
|
|
my $old_duplex = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_duplex};
|
|
my $old_link_state = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_link_state};
|
|
my $old_operational = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational};
|
|
my $old_mac_address = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mac_address};
|
|
my $old_medium = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_medium};
|
|
my $old_mtu = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_mtu};
|
|
my $old_speed = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_speed};
|
|
my $old_rx_bytes = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_bytes};
|
|
my $rx_variable_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_variable_uuid};
|
|
my $old_tx_bytes = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_bytes};
|
|
my $tx_variable_uuid = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_variable_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
old_bond_uuid => $old_bond_uuid,
|
|
old_bridge_uuid => $old_bridge_uuid,
|
|
old_duplex => $old_duplex,
|
|
old_link_state => $old_link_state,
|
|
old_operational => $old_operational,
|
|
old_mac_address => $old_mac_address,
|
|
old_medium => $old_medium,
|
|
old_mtu => $old_mtu,
|
|
old_speed => $old_speed,
|
|
old_tx_bytes => $old_tx_bytes,
|
|
tx_variable_uuid => $tx_variable_uuid,
|
|
old_rx_bytes => $old_rx_bytes,
|
|
rx_variable_uuid => $rx_variable_uuid,
|
|
}});
|
|
|
|
# Delete this so we know it's processed.
|
|
delete $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid};
|
|
|
|
# Get the old bridge or bond name, if required.
|
|
if ($old_bridge_uuid)
|
|
{
|
|
# Get the bridge name
|
|
$old_bridge_name = $anvil->data->{bridges}{uuid_to_name}{$old_bridge_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_bridge_name => $old_bridge_name }});
|
|
}
|
|
if ($old_bond_uuid)
|
|
{
|
|
$old_bond_name = $anvil->data->{bonds}{uuid_to_name}{$old_bond_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_bond_name => $old_bond_name }});
|
|
}
|
|
|
|
# Look for changes.
|
|
my $changes = 0;
|
|
if ($new_bond_uuid ne $old_bond_uuid)
|
|
{
|
|
# We're making this a warning level alert as it should not be changing.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $key = "scan_network_alert_0032";
|
|
if (not $new_bond_uuid)
|
|
{
|
|
# Left the bond
|
|
$key = "scan_network_alert_0031";
|
|
}
|
|
elsif (not $old_bond_uuid)
|
|
{
|
|
# Joined the bond
|
|
$key = "scan_network_alert_0030";
|
|
}
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_bond_name." (".$old_bond_uuid.")",
|
|
new => $new_bond_name." (".$new_bond_uuid.")",
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_bridge_uuid ne $old_bridge_uuid)
|
|
{
|
|
# If this is a vnet* device, it's a notice level alert. Otherwise it's a
|
|
# warning level alert. The vnetX devices come and go with VMs.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $log_level = 1;
|
|
my $alert_level = "warning";
|
|
my $key = "scan_network_alert_0035";
|
|
if ($network_interface_name =~ /^vnet/)
|
|
{
|
|
# Left the bridge
|
|
$log_level = 1;
|
|
$alert_level = "warning";
|
|
}
|
|
if ($new_bridge_uuid)
|
|
{
|
|
# Left the bridge
|
|
$key = "scan_network_alert_0034";
|
|
}
|
|
elsif (not $old_bridge_uuid)
|
|
{
|
|
# Joined the bridge
|
|
$key = "scan_network_alert_0033";
|
|
}
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_bridge_name." (".$old_bridge_uuid.")",
|
|
new => $new_bridge_name." (".$new_bridge_uuid.")",
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_duplex ne $old_duplex)
|
|
{
|
|
# This is always a warning
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $clear = 0;
|
|
my $key = "scan_network_alert_0036";
|
|
my $alert_level = "notice";
|
|
if ($new_duplex eq "full")
|
|
{
|
|
# Duplex is back to being OK
|
|
$clear = 1;
|
|
$key = "scan_network_alert_0037";
|
|
}
|
|
|
|
# Is this one of our interface?
|
|
if (not $anvil->Network->is_our_interface({interface => $network_interface_name}))
|
|
{
|
|
# Not an interface we care about.
|
|
$alert_level = "notice";
|
|
}
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_duplex,
|
|
new => $new_duplex,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
clear_alert => $clear,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_link_state ne $old_link_state)
|
|
{
|
|
# This is always a warning, if it's a NIC we care about.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $clear = 0;
|
|
my $key = "scan_network_alert_0038";
|
|
my $alert_level = "warning";
|
|
if ($new_link_state)
|
|
{
|
|
# Link is up
|
|
$clear = 1;
|
|
$key = "scan_network_alert_0039";
|
|
}
|
|
|
|
# Is this one of our interface?
|
|
if (not $anvil->Network->is_our_interface({interface => $network_interface_name}))
|
|
{
|
|
# Not an interface we care about.
|
|
$alert_level = "notice";
|
|
}
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_link_state,
|
|
new => $new_link_state,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
clear_alert => $clear,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
# Operation can be DELETED
|
|
if ($new_operational ne $old_operational)
|
|
{
|
|
# This is always a warning
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
# Is it up or down?
|
|
my $clear = 0;
|
|
my $key = "scan_network_alert_0040";
|
|
my $alert_level = "notice";
|
|
if ($old_operational eq "DELETED")
|
|
{
|
|
# Link is back. Is it up?
|
|
if ($new_operational eq "up")
|
|
{
|
|
# It's up
|
|
$clear = 1;
|
|
$key = "scan_network_alert_0042";
|
|
}
|
|
else
|
|
{
|
|
# It's back, but down
|
|
$key = "scan_network_alert_0043";
|
|
}
|
|
}
|
|
elsif ($new_operational eq "up")
|
|
{
|
|
# It's up
|
|
$clear = 1;
|
|
$key = "scan_network_alert_0041";
|
|
}
|
|
|
|
# Is this one of our interface?
|
|
if (not $anvil->Network->is_our_interface({interface => $network_interface_name}))
|
|
{
|
|
# Not an interface we care about.
|
|
$alert_level = "notice";
|
|
}
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_operational,
|
|
new => $new_operational,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
clear_alert => $clear,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_mac_address ne $old_mac_address)
|
|
{
|
|
# This is a notice level alert as it's almost certainly a NIC change
|
|
# performed by an admin.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_mac_address,
|
|
new => $new_mac_address,
|
|
};
|
|
|
|
my $key = "scan_network_alert_0044";
|
|
if ($network_interface_name =~ /^vnet/)
|
|
{
|
|
# This is a server booting or migrating
|
|
$key = "scan_network_alert_0061";
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_medium ne $old_medium)
|
|
{
|
|
# This is a notice level alert as it's almost certainly a NIC change
|
|
# performed by an admin.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_medium,
|
|
new => $new_medium,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0045", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0045",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_mtu ne $old_mtu)
|
|
{
|
|
# We're making this a warning level alert if the MTU drops.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_mtu,
|
|
new => $new_mtu,
|
|
};
|
|
|
|
my $log_level = 2;
|
|
my $alert_level = "notice";
|
|
my $key = "scan_network_alert_0046";
|
|
if ($new_mtu < $old_mtu)
|
|
{
|
|
# Make it an alert
|
|
$log_level = 1;
|
|
$alert_level = "warning";
|
|
$key = "scan_network_alert_0047";
|
|
}
|
|
|
|
# Is this one of our interface?
|
|
if (not $anvil->Network->is_our_interface({interface => $network_interface_name}))
|
|
{
|
|
# Not an interface we care about.
|
|
$alert_level = "notice";
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_speed ne $old_speed)
|
|
{
|
|
# We're making this a warning level as speed shouldn't change
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_speed,
|
|
new => $new_speed,
|
|
};
|
|
|
|
my $key = "scan_network_alert_0048";
|
|
if ($new_speed > $old_speed)
|
|
{
|
|
# Speed dropped, likely a faulty network cable
|
|
$key = "scan_network_alert_0049";
|
|
}
|
|
|
|
# Is this one of our interface?
|
|
my $alert_level = "notice";
|
|
if (not $anvil->Network->is_our_interface({interface => $network_interface_name}))
|
|
{
|
|
# Not an interface we care about.
|
|
$alert_level = "notice";
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
|
|
if ($changes)
|
|
{
|
|
my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({
|
|
debug => 2,
|
|
network_interface_bond_uuid => $new_bond_uuid,
|
|
network_interface_bridge_uuid => $new_bridge_uuid,
|
|
network_interface_name => $network_interface_name,
|
|
network_interface_duplex => $new_duplex,
|
|
network_interface_link_state => $new_link_state,
|
|
network_interface_operational => $new_operational,
|
|
network_interface_mac_address => $new_mac_address,
|
|
network_interface_medium => $new_medium,
|
|
network_interface_mtu => $new_mtu,
|
|
network_interface_speed => $new_speed,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_uuid => $network_interface_uuid }});
|
|
}
|
|
|
|
# Track usage of interfaces we care about
|
|
if ($anvil->Network->is_our_interface({interface => $network_interface_name}))
|
|
{
|
|
# Rx and Tx almost always change, so they're only info-level alerts.
|
|
if ($new_tx_bytes ne $old_tx_bytes)
|
|
{
|
|
if ($tx_variable_uuid)
|
|
{
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_uuid => $tx_variable_uuid,
|
|
update_value_only => 1,
|
|
variable_value => $new_tx_bytes,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
else
|
|
{
|
|
# No value seen before, create
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "network_interface::".$network_interface_name."::tx_bytes",
|
|
variable_value => $new_tx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0291",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $network_interface_uuid,
|
|
variable_source_table => "network_interfaces",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_tx_bytes}).")",
|
|
new => $new_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_tx_bytes}).")",
|
|
};
|
|
|
|
# Reset or normal increase?
|
|
my $key = "scan_network_alert_0007";
|
|
my $alert_level = "info";
|
|
my $log_level = 2;
|
|
if ($old_tx_bytes > $new_tx_bytes)
|
|
{
|
|
# Reset
|
|
$key = "scan_network_alert_0008";
|
|
$alert_level = "notice";
|
|
$log_level = 2;
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_rx_bytes ne $old_rx_bytes)
|
|
{
|
|
if ($rx_variable_uuid)
|
|
{
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_uuid => $rx_variable_uuid,
|
|
update_value_only => 1,
|
|
variable_value => $new_rx_bytes,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
else
|
|
{
|
|
# No value seen before, create
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "network_interface::".$network_interface_name."::rx_bytes",
|
|
variable_value => $new_rx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0290",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $network_interface_uuid,
|
|
variable_source_table => "network_interfaces",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
old => $old_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_rx_bytes}).")",
|
|
new => $new_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_rx_bytes}).")",
|
|
};
|
|
|
|
# Reset or normal increase?
|
|
my $key = "scan_network_alert_0009";
|
|
my $alert_level = "info";
|
|
my $log_level = 2;
|
|
if ($old_rx_bytes > $new_rx_bytes)
|
|
{
|
|
# Reset
|
|
$key = "scan_network_alert_0010";
|
|
$alert_level = "notice";
|
|
$log_level = 2;
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# Record the interface
|
|
my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({
|
|
debug => 2,
|
|
network_interface_bond_uuid => $new_bond_uuid,
|
|
network_interface_bridge_uuid => $new_bridge_uuid,
|
|
network_interface_name => $network_interface_name,
|
|
network_interface_duplex => $new_duplex,
|
|
network_interface_link_state => $new_link_state,
|
|
network_interface_operational => $new_operational,
|
|
network_interface_mac_address => $new_mac_address,
|
|
network_interface_medium => $new_medium,
|
|
network_interface_mtu => $new_mtu,
|
|
network_interface_speed => $new_speed,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_uuid => $network_interface_uuid }});
|
|
|
|
# Store the interface so IPs can find our UUID.
|
|
$anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name} = $network_interface_uuid;
|
|
$anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid} = $network_interface_name;
|
|
$anvil->data->{network_interfaces}{mac_to_uuid}{$new_mac_address} = $network_interface_uuid;
|
|
$anvil->data->{interface}{name_to_uuid}{$network_interface_name} = $network_interface_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"network_interfaces::name_to_uuid::${network_interface_name}" => $anvil->data->{network_interfaces}{name_to_uuid}{$network_interface_name},
|
|
"network_interfaces::uuid_to_name::${network_interface_uuid}" => $anvil->data->{network_interfaces}{uuid_to_name}{$network_interface_uuid},
|
|
"network_interfaces::mac_to_uuid::${new_mac_address}" => $anvil->data->{network_interfaces}{mac_to_uuid}{$new_mac_address},
|
|
"interface::name_to_uuid::${network_interface_name}" => $anvil->data->{interface}{name_to_uuid}{$network_interface_name},
|
|
}});
|
|
|
|
# Store the rx_bytes and tx_bytes
|
|
my $rx_variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "network_interface::".$network_interface_name."::rx_bytes",
|
|
variable_value => $new_rx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0290",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $new_bond_uuid,
|
|
variable_source_table => "bonds",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { rx_variable_uuid => $rx_variable_uuid }});
|
|
my $tx_variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "network_interface::".$network_interface_name."::tx_bytes",
|
|
variable_value => $new_tx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0291",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $new_bond_uuid,
|
|
variable_source_table => "bonds",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { tx_variable_uuid => $tx_variable_uuid }});
|
|
|
|
# Report.
|
|
my $say_duplex = "#!string!unit_0004!#";
|
|
if ($new_duplex =~ /full/i)
|
|
{
|
|
$say_duplex = "#!string!unit_0015!#";
|
|
}
|
|
elsif ($new_duplex =~ /half/i)
|
|
{
|
|
$say_duplex = "#!string!unit_0016!#";
|
|
}
|
|
my $variables = {
|
|
interface_name => $network_interface_name,
|
|
bond_name => $new_bond_name ? $new_bond_name : "--",
|
|
bridge_name => $new_bridge_name ? $new_bridge_name : "--",
|
|
duplex => $say_duplex,
|
|
link_state => $new_link_state ? "#!string!unit_0013!#" : "#!string!unit_0014!#", # up / down
|
|
operational => $new_operational,
|
|
mac_address => $new_mac_address,
|
|
medium => $new_medium,
|
|
mtu => $new_mtu,
|
|
speed => $new_speed,
|
|
say_tx => $anvil->Convert->add_commas({number => $new_tx_bytes})." #!string!suffix_0057!# (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_tx_bytes}).")",
|
|
say_rx => $anvil->Convert->add_commas({number => $new_rx_bytes})." #!string!suffix_0057!# (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_rx_bytes}).")",
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0029", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0029",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
}
|
|
|
|
# Look for left over / deleted bonds.
|
|
foreach my $network_interface_uuid (keys %{$anvil->data->{old}{network_interfaces}{network_interface_uuid}})
|
|
{
|
|
# Skip if already deleted.
|
|
next if $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_operational} eq "DELETED";
|
|
|
|
my $network_interface_name = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name};
|
|
my $tx_bytes = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{tx_bytes};
|
|
my $rx_bytes = $anvil->data->{old}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{rx_bytes};
|
|
|
|
my $variables = {
|
|
name => $network_interface_name,
|
|
tx => $anvil->Convert->add_commas({number => $tx_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $tx_bytes}).")",
|
|
rx => $anvil->Convert->add_commas({number => $rx_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $rx_bytes}).")",
|
|
};
|
|
|
|
# If this a vnet device, it's only a notice message as this is expected when a VM migrates or
|
|
# shuts down.
|
|
my $alert_level = $network_interface_name =~ /^vnet/ ? "notice" : "warning";
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0059", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0059",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
|
|
my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({
|
|
debug => 2,
|
|
network_interface_uuid => $network_interface_uuid,
|
|
'delete' => 1,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_uuid => $network_interface_uuid }});
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
# Look for changes in the bonds.
|
|
sub check_bonds
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
foreach my $bond_name (sort {$a cmp $b} keys %{$anvil->data->{new}{bond}})
|
|
{
|
|
# Store the bond
|
|
my $new_mode = $anvil->data->{new}{bond}{$bond_name}{mode};
|
|
my $new_mtu = $anvil->data->{new}{bond}{$bond_name}{mtu};
|
|
my $new_operational = $anvil->data->{new}{bond}{$bond_name}{operational};
|
|
my $new_mac_address = $anvil->data->{new}{bond}{$bond_name}{mac_address};
|
|
my $new_primary_interface = $anvil->data->{new}{bond}{$bond_name}{primary_interface};
|
|
my $new_primary_reselect = $anvil->data->{new}{bond}{$bond_name}{primary_reselect};
|
|
my $new_active_interface = $anvil->data->{new}{bond}{$bond_name}{active_interface};
|
|
my $new_mii_polling_interval = $anvil->data->{new}{bond}{$bond_name}{mii_polling_interval};
|
|
my $new_up_delay = $anvil->data->{new}{bond}{$bond_name}{up_delay};
|
|
my $new_down_delay = $anvil->data->{new}{bond}{$bond_name}{down_delay};
|
|
my $new_tx_bytes = $anvil->data->{new}{bond}{$bond_name}{tx_bytes};
|
|
my $new_rx_bytes = $anvil->data->{new}{bond}{$bond_name}{rx_bytes};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bond_name => $bond_name,
|
|
new_mode => $new_mode,
|
|
new_mtu => $new_mtu,
|
|
new_operational => $new_operational,
|
|
new_mac_address => $new_mac_address,
|
|
new_primary_interface => $new_primary_interface,
|
|
new_primary_reselect => $new_primary_reselect,
|
|
new_active_interface => $new_active_interface,
|
|
new_mii_polling_interval => $new_mii_polling_interval,
|
|
new_up_delay => $new_up_delay,
|
|
new_down_delay => $new_down_delay,
|
|
new_tx_bytes => $new_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_tx_bytes}).")",
|
|
new_rx_bytes => $new_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_rx_bytes}).")",
|
|
}});
|
|
|
|
# If we don't have a bridge_uuid, find it by the name.
|
|
my $new_bridge_uuid = "";
|
|
my $new_bridge_name = "";
|
|
if (exists $anvil->data->{interface_to_bridge}{$bond_name})
|
|
{
|
|
# This bond is on a bridge
|
|
$new_bridge_name = $anvil->data->{interface_to_bridge}{$bond_name};
|
|
$new_bridge_uuid = $anvil->data->{bridges}{name_to_uuid}{$new_bridge_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
new_bridge_name => $new_bridge_name,
|
|
new_bridge_uuid => $new_bridge_uuid,
|
|
}});
|
|
}
|
|
|
|
# New or existing?
|
|
if (exists $anvil->data->{bonds}{name_to_uuid}{$bond_name})
|
|
{
|
|
# Existing, look for changes.
|
|
my $bond_uuid = $anvil->data->{bonds}{name_to_uuid}{$bond_name};
|
|
my $old_mode = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mode};
|
|
my $old_mtu = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mtu};
|
|
my $old_primary_interface = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_primary_interface};
|
|
my $old_primary_reselect = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_primary_reselect};
|
|
my $old_active_interface = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_active_interface};
|
|
my $old_mii_polling_interval = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mii_polling_interval};
|
|
my $old_up_delay = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_up_delay};
|
|
my $old_down_delay = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_down_delay};
|
|
my $old_mac_address = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_mac_address};
|
|
my $old_operational = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_operational};
|
|
my $old_bridge_uuid = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_bridge_uuid};
|
|
my $old_rx_bytes = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{rx_bytes};
|
|
my $rx_variable_uuid = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{rx_variable_uuid};
|
|
my $old_tx_bytes = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{tx_bytes};
|
|
my $tx_variable_uuid = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{tx_variable_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bond_uuid => $bond_uuid,
|
|
old_mode => $old_mode,
|
|
old_mtu => $old_mtu,
|
|
old_primary_interface => $old_primary_interface,
|
|
old_primary_reselect => $old_primary_reselect,
|
|
old_active_interface => $old_active_interface,
|
|
old_mii_polling_interval => $old_mii_polling_interval,
|
|
old_up_delay => $old_up_delay,
|
|
old_down_delay => $old_down_delay,
|
|
old_mac_address => $old_mac_address,
|
|
old_operational => $old_operational,
|
|
old_bridge_uuid => $old_bridge_uuid,
|
|
old_rx_bytes => $old_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_rx_bytes}).")",
|
|
rx_variable_uuid => $rx_variable_uuid,
|
|
old_tx_bytes => $old_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_tx_bytes}).")",
|
|
tx_variable_uuid => $tx_variable_uuid,
|
|
}});
|
|
|
|
# Delete the old record so we know it's been processed.
|
|
delete $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid};
|
|
|
|
my $old_bridge_name = "";
|
|
if ($old_bridge_uuid)
|
|
{
|
|
$old_bridge_name = $anvil->data->{bridges}{uuid_to_name}{$old_bridge_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_bridge_name => $old_bridge_name }});
|
|
}
|
|
|
|
my $changes = 0;
|
|
if ($new_mode ne $old_mode)
|
|
{
|
|
# We're making this a warning level alert as it should not be changing.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $say_old_name = "scan_network_bond_".$old_mode."_name";
|
|
my $say_old_number = "scan_network_bond_".$old_mode."_number";
|
|
my $say_old_description = "scan_network_bond_".$old_mode."_description";
|
|
my $say_new_name = "scan_network_bond_".$new_mode."_name";
|
|
my $say_new_number = "scan_network_bond_".$new_mode."_number";
|
|
my $say_new_description = "scan_network_bond_".$new_mode."_description";
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $say_old_name,
|
|
old_number => $say_old_number,
|
|
old_description => $say_old_description,
|
|
new => $say_new_name,
|
|
new_number => $say_new_number,
|
|
new_description => $say_new_description,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_alert_0012", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0012",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_mtu ne $old_mtu)
|
|
{
|
|
# We're making this a warning level alert if the MTU drops.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_mtu,
|
|
new => $new_mtu,
|
|
};
|
|
|
|
my $log_level = 2;
|
|
my $alert_level = "notice";
|
|
my $key = "scan_network_alert_0013";
|
|
if ($new_mtu < $old_mtu)
|
|
{
|
|
# Make it an alert
|
|
$log_level = 1;
|
|
$alert_level = "warning";
|
|
$key = "scan_network_alert_0014";
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_bridge_name ne $old_bridge_name)
|
|
{
|
|
# We're making this a warning level alert as it should not be changing.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_bridge_name ? $old_bridge_name : "--",
|
|
new => $new_bridge_name ? $new_bridge_name : "--",
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0015", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0015",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_operational ne $old_operational)
|
|
{
|
|
# We're making this a warning level alert as it should not be changing.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_operational eq "up" ? "#!string!unit_0013!#" : "#!string!unit_0014!#",
|
|
new => $new_operational eq "up" ? "#!string!unit_0013!#" : "#!string!unit_0014!#",
|
|
};
|
|
|
|
# Gone up, down or returned?
|
|
my $key = "scan_network_alert_0016";
|
|
if ($old_operational eq "DELETED")
|
|
{
|
|
# Bond is back from being deleted. Is it up or down?
|
|
if ($new_operational eq "up")
|
|
{
|
|
# Back and up
|
|
$key = "scan_network_alert_0027";
|
|
}
|
|
else
|
|
{
|
|
# Back but down
|
|
$key = "scan_network_alert_0028";
|
|
}
|
|
}
|
|
elsif ($new_operational eq "up")
|
|
{
|
|
$key = "scan_network_alert_0017";
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_mac_address ne $old_mac_address)
|
|
{
|
|
# We're making this a notice as it can change with the active interface
|
|
# changing. There will be a warning if a given interface dropped.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_mac_address,
|
|
new => $new_mac_address,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_alert_0018", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0018",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_primary_interface ne $old_primary_interface)
|
|
{
|
|
# We're making this a notice as it will only change if an admin did it.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_primary_interface,
|
|
new => $new_primary_interface,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_alert_0019", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0019",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_primary_reselect ne $old_primary_reselect)
|
|
{
|
|
# We're making this a notice as it will only change if an admin did it.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_primary_reselect,
|
|
new => $new_primary_reselect,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_alert_0020", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0020",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_active_interface ne $old_active_interface)
|
|
{
|
|
# We're making this a warning as this generally happens when a link drops or returns.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_active_interface,
|
|
new => $new_active_interface,
|
|
};
|
|
|
|
# Did the primary interface return?
|
|
my $key = "scan_network_alert_0021";
|
|
if ($new_active_interface eq $new_primary_interface)
|
|
{
|
|
# Primary link is back
|
|
$key = "scan_network_alert_0022";
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_mii_polling_interval ne $old_mii_polling_interval)
|
|
{
|
|
# We're making this a notice as this will only ever change by an admin.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_mii_polling_interval,
|
|
new => $new_mii_polling_interval,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0023", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0023",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_up_delay ne $old_up_delay)
|
|
{
|
|
# We're making this a notice as this will only ever change by an admin.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_up_delay,
|
|
new => $new_up_delay,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_alert_0024", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0024",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_down_delay ne $old_down_delay)
|
|
{
|
|
# We're making this a notice as this will only ever change by an admin.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_down_delay,
|
|
new => $new_down_delay,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_alert_0024", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0024",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
|
|
# Save the changes, if any.
|
|
if ($changes)
|
|
{
|
|
my $bond_uuid = $anvil->Database->insert_or_update_bonds({
|
|
debug => 2,
|
|
bond_name => $bond_name,
|
|
bond_mode => $new_mode,
|
|
bond_mtu => $new_mtu,
|
|
bond_operational => $new_operational,
|
|
bond_mac_address => $new_mac_address,
|
|
bond_primary_interface => $new_primary_interface,
|
|
bond_primary_reselect => $new_primary_reselect,
|
|
bond_active_interface => $new_active_interface,
|
|
bond_mii_polling_interval => $new_mii_polling_interval,
|
|
bond_up_delay => $new_up_delay,
|
|
bond_down_delay => $new_down_delay,
|
|
bond_bridge_uuid => $new_bridge_uuid,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_uuid => $bond_uuid }});
|
|
}
|
|
|
|
# Rx and Tx almost always change, so they're only info-level alerts.
|
|
if ($new_tx_bytes ne $old_tx_bytes)
|
|
{
|
|
if ($tx_variable_uuid)
|
|
{
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_uuid => $tx_variable_uuid,
|
|
update_value_only => 1,
|
|
variable_value => $new_tx_bytes,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
else
|
|
{
|
|
# No value seen before, create
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "bond::".$bond_name."::tx_bytes",
|
|
variable_value => $new_tx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0291",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $bond_uuid,
|
|
variable_source_table => "bonds",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_tx_bytes}).")",
|
|
new => $new_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_tx_bytes}).")",
|
|
};
|
|
|
|
# Reset or normal increase?
|
|
my $key = "scan_network_alert_0007";
|
|
my $alert_level = "info";
|
|
my $log_level = 2;
|
|
if ($old_tx_bytes > $new_tx_bytes)
|
|
{
|
|
# Reset
|
|
$key = "scan_network_alert_0008";
|
|
$alert_level = "notice";
|
|
$log_level = 2;
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_rx_bytes ne $old_rx_bytes)
|
|
{
|
|
if ($rx_variable_uuid)
|
|
{
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_uuid => $rx_variable_uuid,
|
|
update_value_only => 1,
|
|
variable_value => $new_rx_bytes,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
else
|
|
{
|
|
# No value seen before, create
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "bond::".$bond_name."::rx_bytes",
|
|
variable_value => $new_rx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0290",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $bond_uuid,
|
|
variable_source_table => "bonds",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
old => $old_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_rx_bytes}).")",
|
|
new => $new_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_rx_bytes}).")",
|
|
};
|
|
|
|
# Reset or normal increase? Reset Normal increase
|
|
my $key = "scan_network_alert_0009";
|
|
my $alert_level = "info";
|
|
my $log_level = 2;
|
|
if ($old_rx_bytes > $new_rx_bytes)
|
|
{
|
|
# Reset
|
|
$key = "scan_network_alert_0010";
|
|
$alert_level = "notice";
|
|
$log_level = 2;
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# New bond. Is it on a bridge?
|
|
my $bridge_name = "";
|
|
my $bridge_uuid = "";
|
|
if (exists $anvil->data->{interface_to_bridge}{$bond_name})
|
|
{
|
|
$bridge_name = $anvil->data->{interface_to_bridge}{$bond_name};
|
|
$bridge_uuid = $anvil->data->{bridges}{name_to_uuid}{$bridge_name};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bridge_name => $bridge_name,
|
|
bridge_uuid => $bridge_uuid,
|
|
}});
|
|
}
|
|
|
|
# Record the bond
|
|
my $bond_uuid = $anvil->Database->insert_or_update_bonds({
|
|
debug => 2,
|
|
bond_name => $bond_name,
|
|
bond_mode => $new_mode,
|
|
bond_mtu => $new_mtu,
|
|
bond_operational => $new_operational,
|
|
bond_mac_address => $new_mac_address,
|
|
bond_primary_interface => $new_primary_interface,
|
|
bond_primary_reselect => $new_primary_reselect,
|
|
bond_active_interface => $new_active_interface,
|
|
bond_mii_polling_interval => $new_mii_polling_interval,
|
|
bond_up_delay => $new_up_delay,
|
|
bond_down_delay => $new_down_delay,
|
|
bond_bridge_uuid => $bridge_uuid,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_uuid => $bond_uuid }});
|
|
|
|
# Store the bond so our links can find our UUID.
|
|
$anvil->data->{bonds}{name_to_uuid}{$bond_name} = $bond_uuid;
|
|
$anvil->data->{bonds}{uuid_to_name}{$bond_uuid} = $bond_name;
|
|
$anvil->data->{interface}{name_to_uuid}{$bond_name} = $bond_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"bonds::name_to_uuid::${bond_name}" => $anvil->data->{bonds}{name_to_uuid}{$bond_name},
|
|
"bonds::uuid_to_name::${bond_uuid}" => $anvil->data->{bonds}{uuid_to_name}{$bond_uuid},
|
|
"interface::name_to_uuid::${bond_name}" => $anvil->data->{interface}{name_to_uuid}{$bond_name},
|
|
}});
|
|
|
|
# Store the rx_bytes and tx_bytes
|
|
my $rx_variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "bond::".$bond_name."::rx_bytes",
|
|
variable_value => $new_rx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0290",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $bond_uuid,
|
|
variable_source_table => "bonds",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { rx_variable_uuid => $rx_variable_uuid }});
|
|
my $tx_variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "bond::".$bond_name."::tx_bytes",
|
|
variable_value => $new_tx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0291",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $bond_uuid,
|
|
variable_source_table => "bonds",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { tx_variable_uuid => $tx_variable_uuid }});
|
|
|
|
# Report.
|
|
my $variables = {
|
|
bond_name => $bond_name,
|
|
mode => "scan_network_bond_".$new_mode."_name",
|
|
number => "scan_network_bond_".$new_mode."_number",
|
|
description => "scan_network_bond_".$new_mode."_description",
|
|
mtu => $new_mtu,
|
|
bridge => $bridge_name ? $bridge_name : "--",
|
|
operational => $new_operational eq "up" ? "#!string!unit_0013!#" : "#!string!unit_0014!#",
|
|
mac_address => $new_mac_address,
|
|
primary_interface => $new_primary_interface,
|
|
primary_reselect => $new_primary_reselect,
|
|
active_interface => $new_active_interface,
|
|
mii_polling_interval => $new_mii_polling_interval,
|
|
up_delay => $new_up_delay,
|
|
down_delay => $new_down_delay,
|
|
say_tx => $anvil->Convert->add_commas({number => $new_tx_bytes})." #!string!suffix_0057!# (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_tx_bytes}).")",
|
|
say_rx => $anvil->Convert->add_commas({number => $new_rx_bytes})." #!string!suffix_0057!# (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_rx_bytes}).")",
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0011", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0011",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
}
|
|
|
|
# Look for left over / deleted bonds.
|
|
foreach my $bond_uuid (keys %{$anvil->data->{old}{bonds}{bond_uuid}})
|
|
{
|
|
# Skip if already deleted.
|
|
next if $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_operational} eq "DELETED";
|
|
|
|
my $bond_name = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{bond_name};
|
|
my $tx_bytes = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{tx_bytes};
|
|
my $rx_bytes = $anvil->data->{old}{bonds}{bond_uuid}{$bond_uuid}{rx_bytes};
|
|
|
|
my $variables = {
|
|
name => $bond_name,
|
|
tx => $anvil->Convert->add_commas({number => $tx_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $tx_bytes}).")",
|
|
rx => $anvil->Convert->add_commas({number => $rx_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $rx_bytes}).")",
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0058", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0058",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
|
|
my $bond_uuid = $anvil->Database->insert_or_update_bonds({
|
|
debug => 2,
|
|
bond_uuid => $bond_uuid,
|
|
'delete' => 1,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_uuid => $bond_uuid }});
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
# Look for changes in the bridges.
|
|
sub check_bridges
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Loop through the new stuff found and look for changes. Bridges first.
|
|
foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{new}{bridge}})
|
|
{
|
|
# The RX/TX always change.
|
|
my $new_bridge_id = $anvil->data->{new}{bridge}{$bridge_name}{id};
|
|
my $new_mac_address = $anvil->data->{new}{bridge}{$bridge_name}{mac_address};
|
|
my $new_mtu = $anvil->data->{new}{bridge}{$bridge_name}{mtu};
|
|
my $new_stp_enabled = $anvil->data->{new}{bridge}{$bridge_name}{stp_enabled};
|
|
my $new_tx_bytes = $anvil->data->{new}{bridge}{$bridge_name}{tx_bytes};
|
|
my $new_rx_bytes = $anvil->data->{new}{bridge}{$bridge_name}{rx_bytes};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bridge_name => $bridge_name,
|
|
new_bridge_id => $new_bridge_id,
|
|
new_mac_address => $new_mac_address,
|
|
new_mtu => $new_mtu,
|
|
new_stp_enabled => $new_stp_enabled,
|
|
new_tx_bytes => $new_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_tx_bytes}).")",
|
|
new_rx_bytes => $new_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_rx_bytes}).")",
|
|
}});
|
|
|
|
# New or existing?
|
|
if (exists $anvil->data->{bridges}{name_to_uuid}{$bridge_name})
|
|
{
|
|
# Existing, look for changes.
|
|
my $bridge_uuid = $anvil->data->{bridges}{name_to_uuid}{$bridge_name};
|
|
my $old_bridge_id = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_id};
|
|
my $old_mac_address = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_mac_address};
|
|
my $old_mtu = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_mtu};
|
|
my $old_stp_enabled = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_stp_enabled};
|
|
my $old_tx_bytes = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{tx_bytes};
|
|
my $tx_variable_uuid = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{tx_variable_uuid};
|
|
my $old_rx_bytes = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{rx_bytes};
|
|
my $rx_variable_uuid = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{rx_variable_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bridge_uuid => $bridge_uuid,
|
|
old_bridges_id => $old_bridge_id,
|
|
old_mac_address => $old_mac_address,
|
|
old_mtu => $old_mtu,
|
|
old_stp_enabled => $old_stp_enabled,
|
|
old_tx_bytes => $old_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_tx_bytes}).")",
|
|
tx_variable_uuid => $tx_variable_uuid,
|
|
old_rx_bytes => $old_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_rx_bytes}).")",
|
|
rx_variable_uuid => $rx_variable_uuid,
|
|
}});
|
|
|
|
# Delete the old record so we know it's been processed.
|
|
delete $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid};
|
|
|
|
my $changes = 0;
|
|
if ($new_bridge_id ne $old_bridge_id)
|
|
{
|
|
# We're making this a notice level alert as it has no impact on the system,
|
|
# unless it's returned from being deleted.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bridge_name,
|
|
old => $old_bridge_id,
|
|
new => $new_bridge_id,
|
|
};
|
|
|
|
# Did the bridge return?
|
|
my $key = "scan_network_alert_0003";
|
|
my $log_level = 2;
|
|
my $alert_level = "notice";
|
|
if ($old_bridge_id eq "DELETED")
|
|
{
|
|
# Bridge is back.
|
|
$key = "scan_network_alert_0026";
|
|
$log_level = 1;
|
|
$alert_level = "warning";
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
elsif ($new_mac_address ne $old_mac_address)
|
|
{
|
|
# This is odd, but not harmful
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bridge_name,
|
|
old => $old_mac_address,
|
|
new => $new_mac_address,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_alert_0004", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0004",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
elsif ($new_mtu ne $old_mtu)
|
|
{
|
|
# This is a waning, need to ensure the client understands what's going on here.
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bridge_name,
|
|
old => $old_mtu,
|
|
new => $new_mtu,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0005", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0005",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
elsif ($new_stp_enabled ne $old_stp_enabled)
|
|
{
|
|
# This is a notice
|
|
$changes = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changes => $changes }});
|
|
|
|
my $variables = {
|
|
name => $bridge_name,
|
|
old => $old_stp_enabled,
|
|
new => $new_stp_enabled,
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_alert_0006", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "notice",
|
|
message => "scan_network_alert_0006",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
|
|
if ($changes)
|
|
{
|
|
# Update
|
|
my $bridge_uuid = $anvil->Database->insert_or_update_bridges({
|
|
debug => 2,
|
|
bridge_name => $bridge_name,
|
|
bridge_id => $new_bridge_id,
|
|
bridge_mac_address => $new_mac_address,
|
|
bridge_mtu => $new_mtu,
|
|
bridge_stp_enabled => $new_stp_enabled,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge_uuid => $bridge_uuid }});
|
|
}
|
|
|
|
# Rx and Tx almost always change, so they're only info-level alerts.
|
|
if ($new_tx_bytes ne $old_tx_bytes)
|
|
{
|
|
if ($tx_variable_uuid)
|
|
{
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_uuid => $tx_variable_uuid,
|
|
update_value_only => 1,
|
|
variable_value => $new_tx_bytes,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
else
|
|
{
|
|
# No value seen before, create
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "bridge::".$bridge_name."::tx_bytes",
|
|
variable_value => $new_tx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0291",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $bridge_uuid,
|
|
variable_source_table => "bridges",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
|
|
my $variables = {
|
|
name => $bridge_name,
|
|
old => $old_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_tx_bytes}).")",
|
|
new => $new_tx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_tx_bytes}).")",
|
|
};
|
|
|
|
# Reset or normal increase?
|
|
my $key = "scan_network_alert_0007";
|
|
my $alert_level = "info";
|
|
my $log_level = 2;
|
|
if ($old_tx_bytes > $new_tx_bytes)
|
|
{
|
|
# Reset
|
|
$key = "scan_network_alert_0008";
|
|
$alert_level = "notice";
|
|
$log_level = 2;
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
if ($new_rx_bytes ne $old_rx_bytes)
|
|
{
|
|
if ($rx_variable_uuid)
|
|
{
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_uuid => $rx_variable_uuid,
|
|
update_value_only => 1,
|
|
variable_value => $new_rx_bytes,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
else
|
|
{
|
|
# No value seen before, create
|
|
my $variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "bridge::".$bridge_name."::rx_bytes",
|
|
variable_value => $new_rx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0290",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $bridge_uuid,
|
|
variable_source_table => "bridges",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
|
|
}
|
|
|
|
my $variables = {
|
|
name => $bridge_name,
|
|
old => $old_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $old_rx_bytes}).")",
|
|
new => $new_rx_bytes." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_rx_bytes}).")",
|
|
};
|
|
|
|
# Reset or normal increase? Reset Normal increase
|
|
my $key = "scan_network_alert_0009";
|
|
my $alert_level = "info";
|
|
my $log_level = 2;
|
|
if ($old_rx_bytes > $new_rx_bytes)
|
|
{
|
|
# Reset
|
|
$key = "scan_network_alert_0010";
|
|
$alert_level = "notice";
|
|
$log_level = 2;
|
|
}
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $key, variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => $alert_level,
|
|
message => $key,
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# New, INSERT it and record the new UUID for the interfaces connected on this bridge
|
|
# to find.
|
|
my $bridge_uuid = $anvil->Database->insert_or_update_bridges({
|
|
debug => 2,
|
|
bridge_name => $bridge_name,
|
|
bridge_id => $new_bridge_id,
|
|
bridge_mac_address => $new_mac_address,
|
|
bridge_mtu => $new_mtu,
|
|
bridge_stp_enabled => $new_stp_enabled,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge_uuid => $bridge_uuid }});
|
|
|
|
$anvil->data->{bridges}{name_to_uuid}{$bridge_name} = $bridge_uuid;
|
|
$anvil->data->{bridges}{uuid_to_name}{$bridge_uuid} = $bridge_name;
|
|
$anvil->data->{interface}{name_to_uuid}{$bridge_name} = $bridge_uuid;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"old::bridges::name_to_uuid::${bridge_name}" => $anvil->data->{bridges}{name_to_uuid}{$bridge_name},
|
|
"old::bridges::uuid_to_name::${bridge_uuid}" => $anvil->data->{bridges}{uuid_to_name}{$bridge_uuid},
|
|
"interface::name_to_uuid::${bridge_name}" => $anvil->data->{interface}{name_to_uuid}{$bridge_name},
|
|
}});
|
|
|
|
# Store the rx_bytes and tx_bytes
|
|
my $rx_variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "bridge::".$bridge_name."::rx_bytes",
|
|
variable_value => $new_rx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0290",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $bridge_uuid,
|
|
variable_source_table => "bridges",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { rx_variable_uuid => $rx_variable_uuid }});
|
|
my $tx_variable_uuid = $anvil->Database->insert_or_update_variables({
|
|
debug => 2,
|
|
variable_name => "bridge::".$bridge_name."::tx_bytes",
|
|
variable_value => $new_tx_bytes,
|
|
variable_default => 0,
|
|
variable_description => "striker_0291",
|
|
variable_section => "stats",
|
|
variable_source_uuid => $bridge_uuid,
|
|
variable_source_table => "bridges",
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { tx_variable_uuid => $tx_variable_uuid }});
|
|
|
|
# Report.
|
|
my $variables = {
|
|
bridge_name => $bridge_name,
|
|
bridge_id => $new_bridge_id,
|
|
mac_address => $new_mac_address,
|
|
mtu => $new_mtu,
|
|
stp_enabled => $new_stp_enabled,
|
|
say_tx => $anvil->Convert->add_commas({number => $new_tx_bytes})." #!string!suffix_0057!# (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_tx_bytes}).")",
|
|
say_rx => $anvil->Convert->add_commas({number => $new_rx_bytes})." #!string!suffix_0057!# (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_rx_bytes}).")",
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0002", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0002",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
}
|
|
}
|
|
|
|
# Look for left over / deleted bridges.
|
|
foreach my $bridge_uuid (keys %{$anvil->data->{old}{bridges}{bridge_uuid}})
|
|
{
|
|
# Skip if already deleted.
|
|
if (not $bridge_uuid)
|
|
{
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_warning_0001"});
|
|
$anvil->nice_exit({exit_code => 1});
|
|
}
|
|
|
|
my $bridge_name = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_name};
|
|
my $bridge_id = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_id};
|
|
my $tx_bytes = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{tx_bytes};
|
|
my $rx_bytes = $anvil->data->{old}{bridges}{bridge_uuid}{$bridge_uuid}{rx_bytes};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
bridge_uuid => $bridge_uuid,
|
|
bridge_name => $bridge_name,
|
|
tx_bytes => $tx_bytes,
|
|
rx_bytes => $rx_bytes,
|
|
}});
|
|
next if $bridge_id eq "DELETED";
|
|
|
|
my $variables = {
|
|
name => $bridge_name,
|
|
tx => $anvil->Convert->add_commas({number => $tx_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $tx_bytes}).")",
|
|
rx => $anvil->Convert->add_commas({number => $rx_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $rx_bytes}).")",
|
|
};
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0057", variables => $variables});
|
|
$anvil->Alert->register({
|
|
alert_level => "warning",
|
|
message => "scan_network_alert_0057",
|
|
variables => $variables,
|
|
set_by => $THIS_FILE,
|
|
});
|
|
|
|
my $bridge_uuid = $anvil->Database->insert_or_update_bridges({
|
|
debug => 2,
|
|
bridge_uuid => $bridge_uuid,
|
|
'delete' => 1,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge_uuid => $bridge_uuid }});
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
# This handles health record changes.
|
|
sub process_health
|
|
{
|
|
my ($anvil) = @_;
|
|
|
|
# Get the existing health scores, if any.
|
|
my $query = "
|
|
SELECT
|
|
health_uuid,
|
|
health_source_name,
|
|
health_source_weight
|
|
FROM
|
|
health
|
|
WHERE
|
|
health_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
|
|
AND
|
|
health_source_name LIKE '".$THIS_FILE."%'
|
|
;";
|
|
$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,
|
|
}});
|
|
foreach my $row (@{$results})
|
|
{
|
|
# We've got an entry in the 'scan_hardware' table, so now we'll look for data in the node and
|
|
# services tables.
|
|
my $health_source_name = $row->[1];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_source_name => $health_source_name }});
|
|
|
|
$anvil->data->{old}{health}{$health_source_name}{health_uuid} = $row->[0];
|
|
$anvil->data->{old}{health}{$health_source_name}{health_source_weight} = $row->[2];
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
"old::health::${health_source_name}::health_uuid" => $anvil->data->{old}{health}{$health_source_name}{health_uuid},
|
|
"old::health::${health_source_name}::health_source_weight" => $anvil->data->{old}{health}{$health_source_name}{health_source_weight},
|
|
}});
|
|
}
|
|
|
|
# Now look for interfaces that are down. For now, that's all we look for to set / clear health.
|
|
foreach my $network_interface_name (sort {$a cmp $b} keys %{$anvil->data->{new}{interface}})
|
|
{
|
|
my $new_duplex = $anvil->data->{new}{interface}{$network_interface_name}{duplex};
|
|
my $new_link_state = $anvil->data->{new}{interface}{$network_interface_name}{link_state};
|
|
my $new_operational = $anvil->data->{new}{interface}{$network_interface_name}{operational};
|
|
my $source_name = $THIS_FILE."::".$network_interface_name."::problem";
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
network_interface_name => $network_interface_name,
|
|
new_duplex => $new_duplex,
|
|
new_link_state => $new_link_state,
|
|
new_operational => $new_operational,
|
|
source_name => $source_name,
|
|
}});
|
|
|
|
# Don't set / clear interfaces that appear down but aren't named ifn/bcn/sn as they're probably
|
|
# unconfigured/unusued interfaces.
|
|
my $problem = 0;
|
|
my $check = 0;
|
|
my $monitored = $anvil->Network->is_our_interface({interface => $network_interface_name});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { monitored => $monitored }});
|
|
if ($monitored)
|
|
{
|
|
# One we monitor
|
|
$check = 1;
|
|
}
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { check => $check }});
|
|
|
|
if (($check) && ((not $new_link_state) or ($new_operational eq "down") or ($new_duplex ne "full")))
|
|
{
|
|
$problem = 1;
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
|
|
|
|
if (exists $anvil->data->{old}{health}{$source_name})
|
|
{
|
|
# Already registered.
|
|
delete $anvil->data->{old}{health}{$source_name};
|
|
}
|
|
else
|
|
{
|
|
# Has the interface been down for at least a minute?
|
|
my $age = $anvil->Alert->check_condition_age({
|
|
debug => 2,
|
|
name => $source_name,
|
|
host_uuid => $anvil->Get->host_uuid,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { age => $age }});
|
|
if ($age > 60)
|
|
{
|
|
# New, save.
|
|
my ($health_uuid) = $anvil->Database->insert_or_update_health({
|
|
debug => 2,
|
|
health_agent_name => $THIS_FILE,
|
|
health_source_name => $source_name,
|
|
health_source_weight => 1,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_uuid => $health_uuid }});
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# Clear any old conditions.
|
|
my $age = $anvil->Alert->check_condition_age({
|
|
debug => 2,
|
|
clear => 1,
|
|
name => $source_name,
|
|
host_uuid => $anvil->Get->host_uuid,
|
|
});
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { age => $age }});
|
|
}
|
|
}
|
|
|
|
# Any remaining health scores can be deleted.
|
|
foreach my $health_source_name (sort {$a cmp $b} keys %{$anvil->data->{old}{health}})
|
|
{
|
|
my $health_uuid = $anvil->data->{old}{health}{$health_source_name}{health_uuid};
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
health_source_name => $health_source_name,
|
|
health_uuid => $health_uuid,
|
|
}});
|
|
$anvil->Database->insert_or_update_health({
|
|
debug => 2,
|
|
health_uuid => $health_uuid,
|
|
'delete' => 1,
|
|
});
|
|
}
|
|
|
|
return(0);
|
|
}
|