From 165117edfee94bd8a73cef7e85f79b6161cb08cd Mon Sep 17 00:00:00 2001 From: Digimer Date: Tue, 15 Sep 2020 02:16:35 -0400 Subject: [PATCH] * Finished scan-hardware! (though totally untested, expect bug fixes). * Created Database->insert_or_update_updated() to manage entries in the special 'updated' table. * Updated Alert->check_alert_sent() to not use the 'type' parameter, but instead use the 'clear' parameter, to be more consistent with other methods. Signed-off-by: Digimer --- Anvil/Tools/Alert.pm | 30 ++-- Anvil/Tools/Database.pm | 115 +++++++++++++- scancore-agents/scan-hardware/scan-hardware | 148 +++++------------- .../scan-hardware/scan-hardware.xml | 1 + share/words.xml | 4 +- 5 files changed, 160 insertions(+), 138 deletions(-) diff --git a/Anvil/Tools/Alert.pm b/Anvil/Tools/Alert.pm index 053a1d75..d348b51d 100644 --- a/Anvil/Tools/Alert.pm +++ b/Anvil/Tools/Alert.pm @@ -97,13 +97,11 @@ This is a record locator, which generally allows a given alert to be tied to a g This is a string, usually the name of the program, that set the alert. Usuall this is simple C<< $THIS_FILE >> or C<< $0 >>. -=head3 type (required) +=head3 clear (optional, default '0') -This is set to C<< set >> or C<< clear >>. +If set to C<< 0 >> (set the alert), C<< 1 >> will be returned if this is the first time we've tried to set this alert. If the alert was set before, C<< 0 >> is returned. -If set to C<< set >>, C<< 1 >> will be returned if this is the first time we've tried to set this alert. If the alert was set before, C<< 0 >> is returned. - -If set to C<< clear >>, C<< 1 >> will be returned if this is the alert existed and was cleared. If the alert didn't exist (and thus didn't need to be cleared), C<< 0 >> is returned. +If set to C<< 1 >> (clear the alert), C<< 1 >> will be returned if this is the alert existed and was cleared. If the alert didn't exist (and thus didn't need to be cleared), C<< 0 >> is returned. =cut sub check_alert_sent @@ -117,12 +115,12 @@ sub check_alert_sent my $name = defined $parameter->{name} ? $parameter->{name} : ""; my $record_locator = defined $parameter->{record_locator} ? $parameter->{record_locator} : ""; my $set_by = defined $parameter->{set_by} ? $parameter->{set_by} : ""; - my $type = defined $parameter->{type} ? $parameter->{type} : ""; + my $clear = defined $parameter->{clear} ? $parameter->{clear} : 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { name => $name, record_locator => $record_locator, set_by => $set_by, - type => $type, + clear => $clear, }}); # Do we have an alert name? @@ -149,14 +147,6 @@ sub check_alert_sent return("!!error!!"); } - # Are we setting or clearing? - if (not $type) - { - # Neither... - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0097"}); - return("!!error!!"); - } - # This will get set to '1' if an alert is added or removed. my $changed = 0; @@ -176,15 +166,15 @@ AND ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); - # Now, if this is type=set, register the alert if it doesn't exist. If it is type=clear, remove the + # Now, if this is clear = 0, register the alert if it doesn't exist. If it is clear = 1, remove the # alert if it exists. my $alert_sent_uuid = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0]; $alert_sent_uuid = "" if not defined $alert_sent_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - type => $type, + clear => $clear, alert_sent_uuid => $alert_sent_uuid, }}); - if (($type eq "set") && (not $alert_sent_uuid)) + if ((not $clear) && (not $alert_sent_uuid)) { ### New alert # Make sure this host is in the database... It might not be on the very first run of ScanCore @@ -209,7 +199,7 @@ WHERE { # Too early, we can't set an alert. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "log_0098", variables => { - type => $type, + clear => $clear, set_by => $set_by, record_locator => $record_locator, name => $name, @@ -249,7 +239,7 @@ INSERT INTO }}); $anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__}); } - elsif (($type eq "clear") && ($alert_sent_uuid)) + elsif (($clear) && ($alert_sent_uuid)) { # Alert previously existed, clear it. $changed = 1; diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index 81d70a6c..aa7236a6 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -61,6 +61,7 @@ my $THIS_FILE = "Database.pm"; # insert_or_update_ssh_keys # insert_or_update_states # insert_or_update_temperature +# insert_or_update_updated # insert_or_update_upses # insert_or_update_users # insert_or_update_variables @@ -526,7 +527,6 @@ sub check_agent_data debug => 2, record_locator => "schema_load_failure", set_by => $agent, - type => "set", }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) @@ -552,7 +552,7 @@ sub check_agent_data debug => 2, record_locator => "schema_load_failure", set_by => $agent, - type => "clear", + clear => 1, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) @@ -1643,7 +1643,6 @@ sub connect # If I've not sent an alert about this DB loss before, send one now. # my $set = $anvil->Alert->check_alert_sent({ # debug => $debug, -# type => "set", # set_by => $THIS_FILE, # record_locator => $uuid, # name => "connect_to_db", @@ -1704,7 +1703,7 @@ sub connect # { # my $cleared = $anvil->Alert->check_alert_sent({ # debug => $debug, -# type => "clear", +# clear => 1, # set_by => $THIS_FILE, # record_locator => $uuid, # name => "connect_to_db", @@ -9888,6 +9887,114 @@ INSERT INTO } +=head2 insert_or_update_updated + +This adds or updates an entry in the c<< updated >> tables, used to help track how long ago given programs ran. This helps with determin when scan agents, ScanCore or other programs last ran. + +B<< Note >>: This method differs from most in two ways; First, it only take one parameter, specifc entries can't be updated. Second, this is considered a "scratch" function and has no history schema version. This table is not resync'ed if/when a resync is otherwise performed. + +The C<< updated_uuid >> is returned. + +Parameters; + +=head3 updated_by (required) + +This is the name of the caller updating the entry. Usually this is C<< $THIS_FILE >> as set in the caller. + +=cut +sub insert_or_update_updated +{ + 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 => "Database->insert_or_update_updated()" }}); + + my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : ""; + my $file = defined $parameter->{file} ? $parameter->{file} : ""; + my $line = defined $parameter->{line} ? $parameter->{line} : ""; + my $updated_by = defined $parameter->{updated_by} ? $parameter->{updated_by} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + updated_by => $updated_by, + + }}); + + if (not $updated_by) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_updated()", parameter => "updated_by" }}); + return(""); + } + + # Look up the 'updated_uuid', if possible. + my $updated_uuid = ""; + my $query = " +SELECT + updated_uuid +FROM + updated +WHERE + updated_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." +AND + updated_by = ".$anvil->Database->quote($updated_by)." +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + + my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + if ($count) + { + $updated_uuid = $results->[0]->[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { updated_uuid => $updated_uuid }}); + } + + # Update or insert? + if ($updated_uuid) + { + # Update + my $query = " +UPDATE + updated +SET + updated_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).", + updated_by = ".$anvil->Database->quote($updated_by).", + modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." +WHERE + updated_uuid = ".$anvil->Database->quote($updated_uuid)." +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query =~ /passw/ ? $anvil->Log->is_secure($query) : $query }}); + $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); + } + else + { + # Insert + $updated_uuid = $anvil->Get->uuid(); + my $query = " +INSERT INTO + updated +( + updated_uuid, + updated_host_uuid, + updated_by, + modified_date +) VALUES ( + ".$anvil->Database->quote($updated_uuid).", + ".$anvil->Database->quote($anvil->Get->host_uuid).", + ".$anvil->Database->quote($updated_by).", + ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." +); +"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query =~ /passw/ ? $anvil->Log->is_secure($query) : $query }}); + $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); + } + + return($updated_uuid); +} + + =head2 insert_or_update_upses This updates (or inserts) a record in the 'upses' table. The C<< ups_uuid >> UUID will be returned. diff --git a/scancore-agents/scan-hardware/scan-hardware b/scancore-agents/scan-hardware/scan-hardware index 99deb8cf..723e11bc 100755 --- a/scancore-agents/scan-hardware/scan-hardware +++ b/scancore-agents/scan-hardware/scan-hardware @@ -66,6 +66,8 @@ find_changes($anvil); # Finally, process health weights. process_health($anvil) +# Mark that we ran. +$anvil->Database->insert_or_update_updated({debug => 2, updated_by => $THIS_FILE}); $anvil->nice_exit({exit_code => 0}); @@ -253,7 +255,7 @@ sub collect_cpu_data debug => 2, record_locator => "scan_hardware::cpu_flags_mismatch", set_by => $THIS_FILE, - type => "clear", + clear => 1, }); if ($changed) { @@ -273,7 +275,7 @@ sub collect_cpu_data debug => 2, record_locator => "scan_hardware::cpu_bugs_mismatch", set_by => $THIS_FILE, - type => "clear", + clear => 1, }); if ($changed) { @@ -293,7 +295,7 @@ sub collect_cpu_data debug => 2, record_locator => "scan_hardware::cpu_model_mismatch", set_by => $THIS_FILE, - type => "clear", + clear => 1, }); if ($changed) { @@ -834,7 +836,6 @@ sub find_changes debug => 2, record_locator => "scan_hardware::high_swap", set_by => $agent, - type => "set", }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) @@ -864,7 +865,7 @@ sub find_changes debug => 2, record_locator => "scan_hardware::high_swap", set_by => $agent, - type => "clear", + clear => 1, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) @@ -1245,11 +1246,7 @@ sub process_health $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hardware_alert_0027", variables => $variables}); $anvil->Alert->register({alert_level => "warning", message => "scan_hardware_alert_0027", message_variables => $variables, set_by => $THIS_FILE}); } - - } - $clear_alerts = 0; - my ($health_uuid) = $anvil->Database->insert_or_update_health({ debug => 2, health_agent_name => $THIS_FILE, @@ -1260,114 +1257,41 @@ sub process_health } elsif (($peer_ram_total == $hardware_ram_total) or ($difference < $anvil->data->{scancore}{'scan-hardware'}{ram}{clear_threshold})) { - ### TODO: Left off here. -=cut - # If there was a difference before, clear it. - my $clear = 0; - my $set = $an->Alert->check_alert_sent({ - type => "clear", # This is not the alert level, 'warning' == trouble, 'clear' == ok now. - alert_sent_by => $THIS_FILE, - alert_record_locator => "na", - alert_name => "less_ram_than_peer", - modified_date => $an->data->{sys}{db_timestamp}, + my $age = $anvil->Database->check_condition_age({ + debug => 2, + clear => 1, + name => "scan-hardware::less_ram_than_peer", + host_uuid => $anvil->Get->host_uuid, }); - $an->Log->entry({log_level => 2, message_key => "an_variables_0001", message_variables => { - name1 => "set", value1 => $set, - }, file => $THIS_FILE, line => __LINE__}); - if (not $set) - { - # There's a bug where the - $query = "SELECT health_uuid FROM health WHERE health_host_uuid = ".$anvil->Database->quote($an->data->{sys}{host_uuid})." AND health_source_name = 'less_ram_than_peer';"; - $an->Log->entry({log_level => 2, message_key => "an_variables_0001", message_variables => { - name1 => "query", value1 => $query, - }, file => $THIS_FILE, line => __LINE__}); - my $health_uuid = $an->DB->do_db_query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0]; - $health_uuid = "" if not defined $health_uuid; - $an->Log->entry({log_level => 2, message_key => "an_variables_0001", message_variables => { - name1 => "health_uuid", value1 => $health_uuid, - }, file => $THIS_FILE, line => __LINE__}); - - if ($health_uuid) - { - # Clear it. - $clear = 1; - $an->Log->entry({log_level => 2, message_key => "an_variables_0001", message_variables => { - name1 => "clear", value1 => $clear, - }, file => $THIS_FILE, line => __LINE__}); - } - } - if ($set) - { - # Clear the warning - $an->Alert->register_alert({ - alert_level => "clear", - alert_agent_name => $THIS_FILE, - alert_sort => $an->data->{sys}{alert_sort}++, - alert_title_key => "an_alert_title_0004", - alert_message_key => "scan_hardware_note_0010", - alert_message_variables => { - difference => $anvil->Convert->bytes_to_human_readable({'bytes' => $difference})." (".$an->Readable->comma($difference)." #!string!suffix_0009!#)", - local_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $hardware_ram_total})." (".$an->Readable->comma($hardware_ram_total)." #!string!suffix_0009!#)", - peer_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $peer_ram_total})." (".$an->Readable->comma($peer_ram_total)." #!string!suffix_0009!#)", - }, - }); - - $clear = 1;; - $an->Log->entry({log_level => 2, message_key => "an_variables_0001", message_variables => { - name1 => "clear", value1 => $clear, - }, file => $THIS_FILE, line => __LINE__}); - } - - $an->Log->entry({log_level => 2, message_key => "an_variables_0001", message_variables => { - name1 => "clear", value1 => $clear, - }, file => $THIS_FILE, line => __LINE__}); - if ($clear) + my $changed = $anvil->Alert->check_alert_sent({ + debug => 2, + record_locator => "scan_hardware::less_ram_than_peer", + set_by => $THIS_FILE, + clear => 1, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); + if ($changed) { - # Get the health_uuid - my $query = "SELECT health_uuid FROM health WHERE health_host_uuid = ".$anvil->Database->quote($an->data->{sys}{host_uuid})." AND health_source_name = 'less_ram_than_peer';"; - $an->Log->entry({log_level => 2, message_key => "an_variables_0001", message_variables => { - name1 => "query", value1 => $query, - }, file => $THIS_FILE, line => __LINE__}); - my $health_uuid = $an->DB->do_db_query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0]; - $health_uuid = "" if not defined $health_uuid; - $an->Log->entry({log_level => 2, message_key => "an_variables_0001", message_variables => { - name1 => "health_uuid", value1 => $health_uuid, - }, file => $THIS_FILE, line => __LINE__}); - - # Mark it as deleted for the history schema. - if ($health_uuid) - { - my $query = " -UPDATE - health -SET - health_source_name = 'DELETED', - health_source_weight = '0', - modified_date = ".$anvil->Database->quote($an->data->{sys}{db_timestamp})." -WHERE - health_uuid = ".$anvil->Database->quote($health_uuid)." -;"; - $an->Log->entry({log_level => 1, message_key => "an_variables_0001", message_variables => { - name1 => "query", value1 => $query, - }, file => $THIS_FILE, line => __LINE__}); - $an->DB->do_db_write({query => $query, source => $THIS_FILE, line => __LINE__}); - - # Now actually delete it. - $query = " -DELETE FROM - health -WHERE - health_uuid = ".$anvil->Database->quote($health_uuid)." -;"; - $an->Log->entry({log_level => 1, message_key => "an_variables_0001", message_variables => { - name1 => "query", value1 => $query, - }, file => $THIS_FILE, line => __LINE__}); - $an->DB->do_db_write({query => $query, source => $THIS_FILE, line => __LINE__}); - } + # Clear the alert. + my $variables = { + ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $hardware_ram_total})." (".$an->Readable->comma($hardware_ram_total)." #!string!suffix_0009!#)", + }; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hardware_alert_0028", variables => $variables}); + $anvil->Alert->register({alert_level => "warning", message => "scan_hardware_alert_0028", message_variables => $variables, set_by => $THIS_FILE}); } -=cut + my ($health_uuid) = $anvil->Database->insert_or_update_health({ + debug => 2, + health_agent_name => $THIS_FILE, + health_source_name => "less_ram_than_peer", + health_source_weight => 0, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_uuid => $health_uuid }}); } } + else + { + # We don't know how much RAM our peer has yet, so do nothing. + } return(0); } diff --git a/scancore-agents/scan-hardware/scan-hardware.xml b/scancore-agents/scan-hardware/scan-hardware.xml index f7db19a2..10779adb 100644 --- a/scancore-agents/scan-hardware/scan-hardware.xml +++ b/scancore-agents/scan-hardware/scan-hardware.xml @@ -145,6 +145,7 @@ If the RAM is being updated, this alert will clear once this node has been upgra - Local RAM: [#!variable!local_ram!#] - Peer's RAM: [#!variable!peer_ram!#] + The amount of RAM on both nodes is back to being the same. They both have: [#!variable!ram!#] now. Starting: [#!variable!program!#]. diff --git a/share/words.xml b/share/words.xml index 478950cb..d2f29e8c 100644 --- a/share/words.xml +++ b/share/words.xml @@ -518,12 +518,12 @@ The database connection error was: [ Error ] - Failed to start the Postgres server. Please check the system logs for details. The database user: [#!variable!user!#] was created with UUID: [#!variable!id!#]. [ Error ] - Failed to add the database user: [#!variable!user!#]! Unable to proceed. - check_alert_sent() was called but the 'set' parameter was not passed or it is empty. It should be 'set' or 'clear'.]]> + [ Warning ] - Failed to set an alert because this host is not yet in the database. This can happen if the alert was set before this host was added to the database. * Details of the alert: - Type: ......... [#!variable!type!#] -- Set By: ....... [#!variable!set_by!#] +- Clear? ........ [#!variable!clear!#] - Record Locator: [#!variable!record_locator!#] - Name: ......... [#!variable!name!#] - Timestamp: .... [#!variable!modified_date!#]