From 32d47f70f1de4036456359ccfc33da119e9acddc Mon Sep 17 00:00:00 2001 From: Digimer Date: Mon, 11 Oct 2021 21:57:35 -0400 Subject: [PATCH] * Fixed bugs around ScanCore->check_power() so that it now returns time on batteries and highest charge are returned properly. * Created Network->is_our_interface() which returns '1' if an interface is one managed by an Anvil!. Also updated scan-network to use this to determine when an interface alert should be a warning or notice level alert. Signed-off-by: Digimer --- Anvil/Tools/Network.pm | 45 ++++ Anvil/Tools/ScanCore.pm | 23 +- notes | 2 + scancore-agents/scan-apc-ups/scan-apc-ups | 6 +- scancore-agents/scan-network/scan-network | 277 ++++++++++++---------- tools/anvil-safe-start | 2 +- 6 files changed, 222 insertions(+), 133 deletions(-) diff --git a/Anvil/Tools/Network.pm b/Anvil/Tools/Network.pm index c658e8c1..4cb7cd2a 100644 --- a/Anvil/Tools/Network.pm +++ b/Anvil/Tools/Network.pm @@ -23,6 +23,7 @@ my $THIS_FILE = "Network.pm"; # get_ips # get_network # is_local +# is_our_interface # load_interfces # load_ips # is_ip_in_network @@ -2544,6 +2545,7 @@ sub get_network return($network); } + =head2 is_local This method takes a host name or IP address and looks to see if it matches the local system. If it does, it returns C<< 1 >>. Otherwise it returns C<< 0 >>. @@ -2609,6 +2611,49 @@ sub is_local return($anvil->data->{cache}{is_local}{$host}); } + +=head2 is_our_interface + +This method takes an interface name and returns C<< 1 >> if the interface is one of the ones we manage (A C<< BCN >>, C<< IFN >>, C<< SN >> or C<< MN >> interface). If not, C<< 0 >> is returned. + +Parameters; + +=head3 interface (required) + +This is the name of the interface being evaluated. + +=cut +sub is_our_interface +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Network->is_our_interface()" }}); + + my $interface = $parameter->{interface} ? $parameter->{interface} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + interface => $interface, + }}); + + if (not $interface) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->is_our_interface()", parameter => "interface" }}); + return(0); + } + + my $ours = 0; + if (($interface =~ /^bcn/i) or + ($interface =~ /^sn/i) or + ($interface =~ /^ifn/i) or + ($interface =~ /^mn/i)) + { + $ours = 1; + } + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ours => $ours }}); + return($ours); +} + =head2 is_ip_in_network This takes an IP address, along with network and subnet mask and sees if the IP address is within the network. If it is, it returns C<< 1 >>. If the IP address doesn't match the network, C<< 0 >> is returned. diff --git a/Anvil/Tools/ScanCore.pm b/Anvil/Tools/ScanCore.pm index 52272477..9b50f8c0 100644 --- a/Anvil/Tools/ScanCore.pm +++ b/Anvil/Tools/ScanCore.pm @@ -697,6 +697,12 @@ sub check_power last_updated => $last_updated." (".$anvil->Convert->time({'time' => $last_updated, long => 1, translate => 1}).")", }}); + if ($power_charge_percentage > $highest_charge_percentage) + { + $highest_charge_percentage = $power_charge_percentage; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { highest_charge_percentage => $highest_charge_percentage }}); + } + if ($power_on_battery) { # We're on battery, so see what the hold up time is. @@ -726,6 +732,7 @@ ORDER BY modified_date DESC LIMIT 1 ;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, 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 => $debug, list => { @@ -743,14 +750,16 @@ LIMIT 1 } else { - my $time_on_batteries = $results->[0]->[0]; + my $last_on_batteries = $results->[0]->[0]; + my $time_on_batteries = (time - $last_on_batteries); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + last_on_batteries => $last_on_batteries." (".$anvil->Get->date_and_time({use_time => $last_on_batteries}).")", time_on_batteries => $time_on_batteries." (".$anvil->Convert->time({'time' => $time_on_batteries, long => 1, translate => 1}).")", }}); if ($time_on_batteries < $shortest_time_on_batteries) { - $shortest_time_on_batteries = $shortest_time_on_batteries; + $shortest_time_on_batteries = $time_on_batteries; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shortest_time_on_batteries => $shortest_time_on_batteries." (".$anvil->Convert->time({'time' => $shortest_time_on_batteries, long => 1, translate => 1}).")", }}); @@ -767,18 +776,12 @@ LIMIT 1 ups_with_mains_found => $ups_with_mains_found, shortest_time_on_batteries => $shortest_time_on_batteries, }}); - - if ($power_charge_percentage > $highest_charge_percentage) - { - $highest_charge_percentage = $power_charge_percentage; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { highest_charge_percentage => $highest_charge_percentage }}); - } } } } } - if ($ups_count) + if (not $ups_count) { # No UPSes found. $shortest_time_on_batteries = 0; @@ -824,7 +827,7 @@ sub check_temperature my $parameter = shift; my $anvil = $self->parent; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "ScanCore->post_scan_analysis_node()" }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "ScanCore->check_temperature()" }}); my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : $anvil->Get->host_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { diff --git a/notes b/notes index 4f0b574b..7fa37928 100644 --- a/notes +++ b/notes @@ -14,6 +14,8 @@ su - postgres -c "pg_dump --schema-only anvil > /var/lib/pgsql/anvil_schema.out" su - postgres -c "dropdb anvil" && su - postgres -c "createdb --owner admin anvil" && su - postgres -c "psql anvil < /var/lib/pgsql/anvil.out" su postgres -c "psql anvil" +SELECT a.scan_apc_ups_name AS name, a.scan_apc_ups_serial_number AS sn, a.scan_apc_ups_health AS health, a.scan_apc_ups_nmc_serial_number AS nmc_sn, a.scan_apc_ups_nmc_mac_address AS mac, a.scan_apc_ups_ip AS ip, b._percentage_charge AS charge, d.scan_apc_ups_battery_temperature AS btemp FROM scan_apc_upses a, scan_apc_ups_input b, scan_apc_ups_output c, scan_apc_ups_batteries d WHERE a.scan_apc_ups_uuid = b.scan_apc_ups_input_scan_apc_ups_uuid AND a.scan_apc_ups_uuid = c.scan_apc_ups_output_scan_apc_ups_uuid AND a.scan_apc_ups_uuid = d.scan_apc_ups_battery_scan_apc_ups_uuid ORDER BY name ASC; + ============ diff --git a/scancore-agents/scan-apc-ups/scan-apc-ups b/scancore-agents/scan-apc-ups/scan-apc-ups index 2f9b5b55..3c5b2b15 100755 --- a/scancore-agents/scan-apc-ups/scan-apc-ups +++ b/scancore-agents/scan-apc-ups/scan-apc-ups @@ -2099,7 +2099,7 @@ sub gather_ups_data } # Can I ping it? This returns '1' if it was pingable, '0' if not. - my ($pinged, $average_time) = $anvil->Network->ping({ping => $ups_ip}); + my ($pinged, $average_time) = $anvil->Network->ping({ping => $ups_ip, debug => 2}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { pinged => $pinged, average_time => $average_time, @@ -3042,7 +3042,7 @@ WHERE ORDER BY ups_name ASC ;"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }}); + $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}; @@ -3070,7 +3070,7 @@ ORDER BY } my $ups_count = keys %{$anvil->data->{upses}{ups_uuid}}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { ups_count => $ups_count }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ups_count => $ups_count }}); return($ups_count); } diff --git a/scancore-agents/scan-network/scan-network b/scancore-agents/scan-network/scan-network index 9ed8f1d4..71fc5b73 100755 --- a/scancore-agents/scan-network/scan-network +++ b/scancore-agents/scan-network/scan-network @@ -1865,8 +1865,9 @@ sub check_interfaces $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 $clear = 0; + my $key = "scan_network_alert_0036"; + my $alert_level = "notice"; if ($new_duplex eq "full") { # Duplex is back to being OK @@ -1874,6 +1875,13 @@ sub check_interfaces $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, @@ -1882,7 +1890,7 @@ sub check_interfaces $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables}); $anvil->Alert->register({ - alert_level => "warning", + alert_level => $alert_level, clear_alert => $clear, message => $key, variables => $variables, @@ -1891,12 +1899,13 @@ sub check_interfaces } if ($new_link_state ne $old_link_state) { - # This is always a warning + # 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 $clear = 0; + my $key = "scan_network_alert_0038"; + my $alert_level = "warning"; if ($new_link_state) { # Link is up @@ -1904,6 +1913,13 @@ sub check_interfaces $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, @@ -1912,7 +1928,7 @@ sub check_interfaces $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables}); $anvil->Alert->register({ - alert_level => "warning", + alert_level => $alert_level, clear_alert => $clear, message => $key, variables => $variables, @@ -1927,8 +1943,9 @@ sub check_interfaces $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 $clear = 0; + my $key = "scan_network_alert_0040"; + my $alert_level = "notice"; if ($old_operational eq "DELETED") { # Link is back. Is it up? @@ -1951,6 +1968,13 @@ sub check_interfaces $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, @@ -1959,7 +1983,7 @@ sub check_interfaces $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $key, variables => $variables}); $anvil->Alert->register({ - alert_level => "warning", + alert_level => $alert_level, clear_alert => $clear, message => $key, variables => $variables, @@ -2038,6 +2062,13 @@ sub check_interfaces $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, @@ -2065,9 +2096,17 @@ sub check_interfaces $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 => "warning", + alert_level => $alert_level, message => $key, variables => $variables, set_by => $THIS_FILE, @@ -2092,116 +2131,118 @@ sub check_interfaces $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_uuid => $network_interface_uuid }}); } - # Speed changes? Likely. - - # Rx and Tx almost always change, so they're only info-level alerts. - if ($new_tx_bytes ne $old_tx_bytes) + # Track usage of interfaces we care about + if ($anvil->Network->is_our_interface({interface => $network_interface_name})) { - 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) + # Rx and Tx almost always change, so they're only info-level alerts. + if ($new_tx_bytes ne $old_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, + 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, }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }}); } - else + if ($new_rx_bytes ne $old_rx_bytes) { - # 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", + 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, }); - $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 @@ -3407,13 +3448,11 @@ AND source_name => $source_name, }}); - ### TODO: Don't set / clear interfaces that appear down but aren't named ifn/bcn/sn as they're probably unconfigured/unusued interfaces. + # 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; - if (($network_interface_name =~ /ifn/i) or - ($network_interface_name =~ /sn/i) or - ($network_interface_name =~ /bcn/i) or - ($network_interface_name =~ /mn/i)) + if ($anvil->Network->is_our_interface({interface => $network_interface_name})) { # One we monitor $check = 1; diff --git a/tools/anvil-safe-start b/tools/anvil-safe-start index fb2a194f..e88672f0 100755 --- a/tools/anvil-safe-start +++ b/tools/anvil-safe-start @@ -413,7 +413,7 @@ sub wait_for_access # Only care about our networks. next if $waiting; - if (($interface !~ /^bcn/) && ($interface !~ /^sn/) && ($interface !~ /^ifn/)) + if (not $anvil->Network->is_our_interface({interface => $interface})) { # Not an interface we care about next;