#!/usr/bin/perl # # This software was created by Alteeve's Niche! Inc. and has been released # under the terms of the GNU GPL version 2. # # ScanCore Scan Agent for HPE type RAID controllers using the 'hpacucli' command line tool. # # https://alteeve.com # # Exit Codes: # 0 - Success # 1 - hpacucli not installed # 2 - hpacucli is installed but it is not executable. # 3 - No HPE type controllers found. # 4 - Controller numeric value is invalid. # 5 - Cache module numeric value is invalid. # 6 - Array numeric value is invalid. # 7 - Logical drive numeric value is invalid. # 8 - Physical drive numeric value is invalid. # 9 - Physical drive has no serial number. # # 255 - The host's UUID isn't in the hosts table yet, ScanCore itself hasn't been run. # # TODO: # - # # NOTE: # - Health values # - Controller - Correctable errors = 1 # - Controller - Uncorrectable errors = 5 # - Controller - Status changes = 5 # - Drive group - partially degraded = 5 # - Drive group - degraded = 10 # - Cachevault - Replacement needed = 5 # - BBU - Replacement needed = 5 # - Temperature - Critical = 2 # - Temperature - Warning = 1 # Use my modules. use strict; use warnings; use Anvil::Tools; use Data::Dumper; use Math::BigInt; no warnings 'recursion'; # 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}); } # Here we store data and variables for this agent. $anvil->data->{'scan-hpacucli'} = { health => { old => {}, new => {}, }, # This will keep track of devices with serial numbers so that it is easy to look up # the UUID from the serial numbers and vice versa. controllers => { by_serial => {}, by_uuid => {}, }, physical_drives => { by_serial => {}, by_uuid => {}, }, # Checking the drives for errors is expensive, so it is only done every hour (or # there abouts). Change the interval if you want to check more or less often. diagnostics_interval => 1800, disable => 0, ignore_maximum_temperature => 0, language => "en_CA", log_level => 1, log_language => "en_CA", log_file => "/var/log/ScanCore.log", log_db_transactions => 0, thresholds => { # This is used for unknown sensors and really shouldn't be used at all. 'default' => { high_warning => 50, high_critical => 55, low_warning => 15, low_critical => 10, jump => 5, buffer => 3, }, drives => { # http://storage.toshiba.com/docs/product-datasheets/mk01grrb-r.pdf # http://toshiba.semicon-storage.com/us/product/storage-products/enterprise-ssd/px02smb-px02smfxxx.html high_warning => 50, high_critical => 55, low_warning => 5, low_critical => 0, jump => 5, buffer => 2, }, # I've not found official ranges on this yet... These are best-guess values controller_temperature => { high_warning => 100, high_critical => 105, low_warning => 15, low_critical => 10, jump => 10, buffer => 5, }, # I've not found official ranges on this yet... These are best-guess values capacitor => { high_warning => 50, high_critical => 55, low_warning => 15, low_critical => 10, jump => 5, buffer => 3, }, # https://support.hpe.com/hpsc/doc/public/display?docId=c04441382 cache => { high_warning => 50, high_critical => 55, low_warning => 15, low_critical => 10, jump => 5, buffer => 3, }, }, sys => { alert_sort => 2, controller => {}, controller_count => 0, # When a lock is requested, this is set to the time the lock was set. # DB->do_db_write() and DB->do_db_read() will check this and if its age is >50% of # scancore::locking::reap_age, it will renew the lock. lock_active => 0, process_diagnostics => 0, }, queries => [], }; $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->data->{switches}{force} = 0; $anvil->data->{switches}{purge} = 0; $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}); } $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "scan_hpacucli_message_0001"}); # This does two things; It checks to see if hpacucli is installed (exits '1' if not, exits '2' if not # executable) and then checks to see if any controllers are found in the system (exits '3' if not). find_hp_controllers($anvil); # If we're still alive, start gathering data. gather_data($anvil); # Figure out, other than temperatures, what should be added to or removed from health. pre_process_health($anvil); # Look for changes. find_changes($anvil); # Process temperatures! This also sets health values for warning and critical temperatures so make sure we # always call this before process_health(). process_temperatures($anvil); # Finally, process health weights. process_health($anvil); # Shut down. $anvil->ScanCore->agent_shutdown({agent => $THIS_FILE}); ############################################################################################################# # Function below # ############################################################################################################# # This reads in the last scan data from one of the databases and compares it against the just-read data. If # anything changed, register an alert. sub find_changes { my ($anvil) = @_; # Read in the old data. As we compare and UPDATE if needed, then we'll delete. If any are not found, # then it must be new and will be INSERTed. Any old records left over will have vanished. read_last_scan($anvil); ### NOTE: We will loop through each section of data we scanned, deleting records as we process them ### that existed in the DB, and then marking as removed anything left in the databased data not ### seen in this scan. process_controllers($anvil); # Now that controllers have been proceesed, we can process drives (and their arrays) process_drives($anvil); # If we processed diagnostics, update if ($anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics}) { my $query = " UPDATE scan_hpacucli_controllers SET scan_hpacucli_controller_last_diagnostics = ".time.", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_controller_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); $anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__}); } return(0); } # This reads in all health wieghts previously set, alters ones as needed, INSERTs new ones and DELETEs old # ones. sub process_health { my ($anvil) = @_; # This will hold our updates. $anvil->data->{'scan-hpacucli'}{queries} = []; # Read in previous health values. my $query = " SELECT health_uuid, health_agent_name, health_source_name, health_source_weight FROM health WHERE health_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." AND health_agent_name = ".$anvil->Database->quote($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}) { my $health_uuid = $row->[0]; my $health_agent_name = $row->[1]; my $health_source_name = $row->[2]; my $health_source_weight = $row->[3]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_uuid => $health_uuid, health_agent_name => $health_agent_name, health_source_name => $health_source_name, health_source_weight => $health_source_weight, }}); $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{uuid} = $health_uuid; $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{value} = $health_source_weight; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::health::old::${health_source_name}::uuid" => $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{uuid}, "scan-hpacucli::health::old::${health_source_name}::value" => $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{value}, }}); } # Read in the new ones foreach my $health_source_name (sort {$a cmp $b} keys %{$anvil->data->{'scan-hpacucli'}{health}{new}}) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); my $health_uuid = ""; if (exists $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}) { $health_uuid = $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{uuid}; } $health_uuid = $anvil->Database->insert_or_update_health({ debug => 2, cache => $anvil->data->{'scan-hpacucli'}{queries}, health_uuid => $health_uuid, health_host_uuid => $anvil->Get->host_uuid, health_agent_name => $THIS_FILE, health_source_name => $health_source_name, health_source_weight => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_uuid => $health_uuid }}); if (exists $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}) { # Delete the new old key, regardless of whether it has changed now. delete $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}; } } # Delete any old entries that are left. foreach my $health_source_name (sort {$a cmp $b} keys %{$anvil->data->{'scan-hpacucli'}{health}{old}}) { # Well set the source name to 'DELETED'. my $health_uuid = $anvil->Database->insert_or_update_health({ debug => 2, cache => $anvil->data->{'scan-hpacucli'}{queries}, 'delete' => 1, health_uuid => $anvil->data->{'scan-hpacucli'}{health}{old}{$health_source_name}{uuid}, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { health_uuid => $health_uuid }}); } # Now commit the changes. $anvil->Database->write({query => $anvil->data->{'scan-hpacucli'}{queries}, source => $THIS_FILE, line => __LINE__}); $anvil->data->{'scan-hpacucli'}{queries} = []; return(0); } # This reads in the various temperature sensors we read from this run and will set the temperature table # and/or set/clear warnings/critical states. sub process_temperatures { my ($anvil) = @_; ### NOTE: We use 'sensor_host' to hold the serial number of the device hosting the sensor. # First, read in all existing entries. We'll compare and UPDATE or INSERT as needed and DELETE any # stale entries. my $query = " SELECT temperature_uuid, temperature_sensor_name, temperature_sensor_host, temperature_value_c, temperature_state, temperature_is FROM temperature WHERE temperature_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." AND temperature_agent_name = ".$anvil->Database->quote($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__}); # One or more records were found. foreach my $row (@{$results}) { my $temperature_sensor_name = $row->[1]; my $temperature_sensor_host = $row->[2]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_sensor_name => $temperature_sensor_name, temperature_sensor_host => $temperature_sensor_host, }}); $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_uuid} = $row->[0]; $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_value_c} = $row->[3]; $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_state} = $row->[4]; $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_is} = $row->[5]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "old::temperature::${temperature_sensor_name}::${temperature_sensor_host}::temperature_uuid" => $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_uuid}, "old::temperature::${temperature_sensor_name}::${temperature_sensor_host}::temperature_value_c" => $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_value_c}, "old::temperature::${temperature_sensor_name}::${temperature_sensor_host}::temperature_state" => $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_state}, "old::temperature::${temperature_sensor_name}::${temperature_sensor_host}::temperature_is" => $anvil->data->{old}{temperature}{$temperature_sensor_name}{$temperature_sensor_host}{temperature_is}, }}); } # Loop through the temperature from this scan. foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{new}{temperature}}) { foreach my $serial_number (sort {$a cmp $b} keys %{$anvil->data->{new}{temperature}{$variable}}) { my $new_temperature_value_c = $anvil->data->{new}{temperature}{$variable}{$serial_number}{temperature_value_c}; my $new_temperature_state = $anvil->data->{new}{temperature}{$variable}{$serial_number}{temperature_state}; my $new_temperature_is = $anvil->data->{new}{temperature}{$variable}{$serial_number}{temperature_is}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable => $variable, serial_number => $serial_number, new_temperature_value_c => $new_temperature_value_c, new_temperature_state => $new_temperature_state, new_temperature_is => $new_temperature_is, }}); # If the state is 'warning', set a health weight of 1 and set critical to 2. my $health_source_name = "temperature:".$serial_number; $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 0; if ($new_temperature_state eq "warning") { $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 1; } elsif ($new_temperature_state eq "critical") { $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2; } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); my $temperature_uuid = ""; if (exists $anvil->data->{old}{temperature}{$variable}{$serial_number}) { $temperature_uuid = $anvil->data->{old}{temperature}{$variable}{$serial_number}{temperature_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_uuid => $temperature_uuid }}); delete $anvil->data->{old}{temperature}{$variable}{$serial_number}; } $temperature_uuid = $anvil->Database->insert_or_update_temperature({ cache => $anvil->data->{'scan-hpacucli'}{queries}, debug => 2, temperature_uuid => $temperature_uuid, temperature_host_uuid => $anvil->Get->host_uuid, temperature_agent_name => $THIS_FILE, temperature_sensor_host => $serial_number, temperature_sensor_name => $variable, temperature_value_c => $new_temperature_value_c, temperature_state => $new_temperature_state, temperature_is => $new_temperature_is, temperature_weight => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_uuid => $temperature_uuid }}); } } # Now, if any undeleted old entries remain, delete them from the database. foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{old}{temperature}}) { foreach my $serial_number (sort {$a cmp $b} keys %{$anvil->data->{old}{temperature}{$variable}}) { my $temperature_uuid = $anvil->data->{old}{temperature}{$variable}{$serial_number}{temperature_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "variable" => $variable, "serial_number" => $serial_number, "temperature_uuid" => $temperature_uuid, }}); # Mark the sensor as DELETEd. $anvil->Database->insert_or_update_temperature({ cache => $anvil->data->{'scan-hpacucli'}{queries}, debug => 2, 'delete' => 1, temperature_uuid => $temperature_uuid, }); } } # Commit the queries. $anvil->Database->write({query => $anvil->data->{'scan-hpacucli'}{queries}, source => $THIS_FILE, line => __LINE__}); $anvil->data->{'scan-hpacucli'}{queries} = []; return(0); } # Process drives (and their arrays and logical drives). sub process_drives { my ($anvil) = @_; # Look for new, changed or deleted controllers. $anvil->data->{'scan-hpacucli'}{queries} = []; # This is to collected data from every sweep. foreach my $scan_hpacucli_controller_serial_number (sort {$a cmp $b} keys %{$anvil->data->{controller}}) { # Controller data; next if $scan_hpacucli_controller_serial_number eq "metadata"; my $scan_hpacucli_controller_uuid = $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number, scan_hpacucli_controller_uuid => $scan_hpacucli_controller_uuid, }}); # Array foreach my $scan_hpacucli_array_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}}) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_array_name => $scan_hpacucli_array_name }}); # Data, there is no temperature my $new_scan_hpacucli_array_type = "virtual"; my $new_scan_hpacucli_array_status = "virtual"; my $new_scan_hpacucli_array_error_message = ""; if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{array_type}) { $new_scan_hpacucli_array_type = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{array_type}; } if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{status}) { # Array transitions (OK -> Eject -> Plug back in) #scan-hpacucli 3117; - Data; status: [OK] #scan-hpacucli 3117; - Data; status: [Failed Physical Drive] #scan-hpacucli 3148; - Data; status: [OK] $new_scan_hpacucli_array_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{status}; } if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message}) { $new_scan_hpacucli_array_error_message = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message}; } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_array_name => $scan_hpacucli_array_name, new_scan_hpacucli_array_type => $new_scan_hpacucli_array_type, new_scan_hpacucli_array_status => $new_scan_hpacucli_array_status, new_scan_hpacucli_array_error_message => $new_scan_hpacucli_array_error_message, }}); # Does this array exist already? my $scan_hpacucli_array_uuid = $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_name}{$scan_hpacucli_array_name} ? $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_name}{$scan_hpacucli_array_name} : ""; if (($scan_hpacucli_array_uuid) && (exists $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid})) { # Look for changes. my $old_scan_hpacucli_array_controller_uuid = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_controller_uuid}; my $old_scan_hpacucli_controller_serial_number = $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$old_scan_hpacucli_array_controller_uuid}; my $old_scan_hpacucli_array_type = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_type}; my $old_scan_hpacucli_array_status = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_status}; my $old_scan_hpacucli_array_error_message = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_error_message}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_scan_hpacucli_array_controller_uuid => $old_scan_hpacucli_array_controller_uuid, old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number, old_scan_hpacucli_array_type => $old_scan_hpacucli_array_type, old_scan_hpacucli_array_status => $old_scan_hpacucli_array_status, old_scan_hpacucli_array_error_message => $old_scan_hpacucli_array_error_message, }}); # Delete the old one so we know we've seen it. delete $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}; # Has anything changed? Note that we don't check the name as that is how we # find if it exists already or not. if (($scan_hpacucli_controller_serial_number ne $old_scan_hpacucli_controller_serial_number) or ($new_scan_hpacucli_array_type ne $old_scan_hpacucli_array_type) or ($new_scan_hpacucli_array_status ne $old_scan_hpacucli_array_status) or ($new_scan_hpacucli_array_error_message ne $old_scan_hpacucli_array_error_message)) { ### Something changed. # If the array is not OK, clear alerts. if ($new_scan_hpacucli_array_status ne $old_scan_hpacucli_array_status) { my $cleared = 0; my $message_key = "scan_hpacucli_note_0023"; # Came back or went OK? if ($old_scan_hpacucli_array_status eq "VANISHED") { $message_key = "scan_hpacucli_note_0032"; } elsif (lc($new_scan_hpacucli_array_status) eq "ok") { $cleared = 1; $message_key = "scan_hpacucli_note_0024"; } my $variables = { name => $scan_hpacucli_array_name, serial_number => $scan_hpacucli_controller_serial_number, new_status => $new_scan_hpacucli_array_status, old_status => $old_scan_hpacucli_array_status, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => "warning", message => $message_key, variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } # Did the controller change? if ($scan_hpacucli_controller_serial_number ne $old_scan_hpacucli_controller_serial_number) { # yup. This is a notice as the new controller will have # generated a warning alert. my $variables = { name => $scan_hpacucli_array_name, new_serial_number => $scan_hpacucli_controller_serial_number, old_serial_number => $old_scan_hpacucli_controller_serial_number, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0025", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0025", variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } # Has the error message changed? if ($new_scan_hpacucli_array_error_message ne $old_scan_hpacucli_array_error_message) { # Default is 'changed' my $cleared = 0; my $message_key = "scan_hpacucli_note_0026"; if (not $new_scan_hpacucli_array_error_message) { # Cleared $cleared = 0; $message_key = "scan_hpacucli_note_0027"; } elsif (not $old_scan_hpacucli_array_error_message) { # New error $message_key = "scan_hpacucli_note_0028"; } my $variables = { name => $scan_hpacucli_array_name, new_error_message => $new_scan_hpacucli_array_error_message, old_error_message => $old_scan_hpacucli_array_error_message, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => "warning", message => $message_key, variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } # Did the controller change? if ($new_scan_hpacucli_array_type ne $old_scan_hpacucli_array_type) { # yup. This is a warning because it should never change. my $variables = { name => $scan_hpacucli_array_name, new_type => $new_scan_hpacucli_array_type, old_type => $old_scan_hpacucli_array_type, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0030", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0030", variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } # UPDATE my $query = " UPDATE scan_hpacucli_arrays SET scan_hpacucli_array_controller_uuid = ".$anvil->Database->quote($scan_hpacucli_controller_uuid).", scan_hpacucli_array_type = ".$anvil->Database->quote($new_scan_hpacucli_array_type).", scan_hpacucli_array_status = ".$anvil->Database->quote($new_scan_hpacucli_array_status).", scan_hpacucli_array_error_message = ".$anvil->Database->quote($new_scan_hpacucli_array_error_message).", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_array_uuid = ".$anvil->Database->quote($scan_hpacucli_array_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } else { # New. $scan_hpacucli_array_uuid = $anvil->Get->uuid(); $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number} = $scan_hpacucli_controller_uuid; $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid} = $scan_hpacucli_controller_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::controllers::by_serial::${scan_hpacucli_controller_serial_number}" => $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number}, "scan-hpacucli::controllers::by_uuid::${scan_hpacucli_controller_uuid}" => $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid}, }}); print $THIS_FILE." ".__LINE__."; - New Array: [$scan_hpacucli_array_name] (UUID: [$scan_hpacucli_array_uuid]); Type: [$new_scan_hpacucli_array_type], status: [$new_scan_hpacucli_array_status], error message: [$new_scan_hpacucli_array_error_message]\n"; # Alert the user if this isn't the virtual array. if ($scan_hpacucli_array_name ne "ZZZZ") { # If the array is OK, it will be a notice. my $alert_level = "notice"; my $message_key = "scan_hpacucli_note_0021"; if (lc($new_scan_hpacucli_array_status) ne "ok") { $alert_level = "warning"; $message_key = "scan_hpacucli_note_0022"; } my $variables = { name => $scan_hpacucli_array_name, type => $new_scan_hpacucli_array_type, status => $new_scan_hpacucli_array_status, error => $new_scan_hpacucli_array_error_message, }; my $log_level = $alert_level eq "warning" ? 1 : 2; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => $alert_level, message => $message_key, variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } my $query = " INSERT INTO scan_hpacucli_arrays ( scan_hpacucli_array_uuid, scan_hpacucli_array_host_uuid, scan_hpacucli_array_controller_uuid, scan_hpacucli_array_name, scan_hpacucli_array_type, scan_hpacucli_array_status, scan_hpacucli_array_error_message, modified_date ) VALUES ( ".$anvil->Database->quote($scan_hpacucli_array_uuid).", ".$anvil->Database->quote($anvil->Get->host_uuid).", ".$anvil->Database->quote($scan_hpacucli_controller_uuid).", ".$anvil->Database->quote($scan_hpacucli_array_name).", ".$anvil->Database->quote($new_scan_hpacucli_array_type).", ".$anvil->Database->quote($new_scan_hpacucli_array_status).", ".$anvil->Database->quote($new_scan_hpacucli_array_error_message).", ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." );"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } # Logical Drive foreach my $scan_hpacucli_logical_drive_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}}) { # No thermal data my $scan_hpacucli_logical_drive_uuid = $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name} ? $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name} : ""; my $new_scan_hpacucli_logical_drive_caching = ""; my $new_scan_hpacucli_logical_drive_os_device_name = ""; my $new_scan_hpacucli_logical_drive_type = ""; my $new_scan_hpacucli_logical_drive_raid_level = ""; my $new_scan_hpacucli_logical_drive_size = ""; my $new_scan_hpacucli_logical_drive_strip_size = ""; my $new_scan_hpacucli_logical_drive_stripe_size = ""; my $new_scan_hpacucli_logical_drive_status = ""; # If this is the virtual array, set the sizes to 0. if ($scan_hpacucli_logical_drive_name eq "9999") { $new_scan_hpacucli_logical_drive_size = 0; $new_scan_hpacucli_logical_drive_strip_size = 0; $new_scan_hpacucli_logical_drive_stripe_size = 0; } ### Gather the variables. # Caching if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{caching}) { $new_scan_hpacucli_logical_drive_caching = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{caching}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_caching => $new_scan_hpacucli_logical_drive_caching }}); } # Disk name (in the OS) if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{disk_name}) { $new_scan_hpacucli_logical_drive_os_device_name = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{disk_name}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_os_device_name => $new_scan_hpacucli_logical_drive_os_device_name }}); } # Drive type if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{drive_type}) { $new_scan_hpacucli_logical_drive_type = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{drive_type}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_type => $new_scan_hpacucli_logical_drive_type }}); } # RAID level if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{fault_tolerance}) { $new_scan_hpacucli_logical_drive_raid_level = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{fault_tolerance}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_raid_level => $new_scan_hpacucli_logical_drive_raid_level }}); } # Drive size - Needs to be converted to bytes at initial processing. if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{size}) { $new_scan_hpacucli_logical_drive_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{size}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "new_scan_hpacucli_logical_drive_size" => $new_scan_hpacucli_logical_drive_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_size}).")", }}); } # Strip size if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{strip_size}) { $new_scan_hpacucli_logical_drive_strip_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{strip_size}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "new_scan_hpacucli_logical_drive_strip_size" => $new_scan_hpacucli_logical_drive_strip_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_strip_size}).")", }}); } # Stripe size if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{full_stripe_size}) { $new_scan_hpacucli_logical_drive_stripe_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{full_stripe_size}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "new_scan_hpacucli_logical_drive_stripe_size" => $new_scan_hpacucli_logical_drive_stripe_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_stripe_size}).")", }}); } # Status if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{status}) { $new_scan_hpacucli_logical_drive_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{status}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_status => $new_scan_hpacucli_logical_drive_status }}); } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_logical_drive_caching => $new_scan_hpacucli_logical_drive_caching, new_scan_hpacucli_logical_drive_os_device_name => $new_scan_hpacucli_logical_drive_os_device_name, new_scan_hpacucli_logical_drive_type => $new_scan_hpacucli_logical_drive_type, new_scan_hpacucli_logical_drive_raid_level => $new_scan_hpacucli_logical_drive_raid_level, new_scan_hpacucli_logical_drive_size => $new_scan_hpacucli_logical_drive_size, new_scan_hpacucli_logical_drive_strip_size => $new_scan_hpacucli_logical_drive_strip_size, new_scan_hpacucli_logical_drive_stripe_size => $new_scan_hpacucli_logical_drive_stripe_size, new_scan_hpacucli_logical_drive_status => $new_scan_hpacucli_logical_drive_status, }}); if (($scan_hpacucli_logical_drive_uuid) && (exists $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid})) { my $old_scan_hpacucli_logical_drive_array_uuid = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_array_uuid}; my $old_scan_hpacucli_logical_drive_name = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_name}; my $old_scan_hpacucli_logical_drive_caching = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_caching}; my $old_scan_hpacucli_logical_drive_os_device_name = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_os_device_name}; my $old_scan_hpacucli_logical_drive_type = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_type}; my $old_scan_hpacucli_logical_drive_raid_level = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_raid_level}; my $old_scan_hpacucli_logical_drive_size = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_size}; my $old_scan_hpacucli_logical_drive_strip_size = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_strip_size}; my $old_scan_hpacucli_logical_drive_stripe_size = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_stripe_size}; my $old_scan_hpacucli_logical_drive_status = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_status}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_logical_drive_uuid => $scan_hpacucli_logical_drive_uuid, old_scan_hpacucli_logical_drive_array_uuid => $old_scan_hpacucli_logical_drive_array_uuid, old_scan_hpacucli_logical_drive_name => $old_scan_hpacucli_logical_drive_name, old_scan_hpacucli_logical_drive_caching => $old_scan_hpacucli_logical_drive_caching, old_scan_hpacucli_logical_drive_os_device_name => $old_scan_hpacucli_logical_drive_os_device_name, old_scan_hpacucli_logical_drive_type => $old_scan_hpacucli_logical_drive_type, old_scan_hpacucli_logical_drive_raid_level => $old_scan_hpacucli_logical_drive_raid_level, old_scan_hpacucli_logical_drive_size => $old_scan_hpacucli_logical_drive_size, old_scan_hpacucli_logical_drive_strip_size => $old_scan_hpacucli_logical_drive_strip_size, old_scan_hpacucli_logical_drive_stripe_size => $old_scan_hpacucli_logical_drive_stripe_size, old_scan_hpacucli_logical_drive_status => $old_scan_hpacucli_logical_drive_status, }}); # Delete this so we know it was processed delete $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}; my $update = 0; my $recovered = ""; if ($new_scan_hpacucli_logical_drive_caching ne $old_scan_hpacucli_logical_drive_caching) { # Did it go enabled or disabled? $update = 1; my $cleared = 0; my $message_key = "scan_hpacucli_note_0034"; if (lc($new_scan_hpacucli_logical_drive_caching) eq "enabled") { # We're back. $cleared = 1; $message_key = "scan_hpacucli_note_0035"; } if (lc($new_scan_hpacucli_logical_drive_caching) eq "disabled") { # Warn the user about a possible performance hit. $message_key = "scan_hpacucli_note_0036"; } # Send an alert telling the user that we've found a new controller. my $variables = { logical_drive => $scan_hpacucli_logical_drive_name, array => $scan_hpacucli_array_name, serial_number => $scan_hpacucli_controller_serial_number, new_value => $new_scan_hpacucli_logical_drive_caching, old_value => $old_scan_hpacucli_logical_drive_caching, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => "warning", message => $message_key, variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } elsif ($new_scan_hpacucli_logical_drive_status ne $old_scan_hpacucli_logical_drive_status) { # NOTE: Auto-restored a drive that was re-inserted # Example messages; "Interim Recovery Mode" # "Recovering, 0% complete" # LD transitions (OK -> Eject -> Plug back in) $update = 1; my $cleared = 0; my $alert_level = "warning"; my $message_key = "scan_hpacucli_note_0037"; if ($old_scan_hpacucli_logical_drive_status eq "VANISHED") { # It's back $cleared = 1; $message_key = "scan_hpacucli_note_0045"; } elsif (lc($new_scan_hpacucli_logical_drive_status) eq "ok") { # Back to healthy. $cleared = 1; $alert_level = "critical"; $message_key = "scan_hpacucli_note_0038"; my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_logical_drive_uuid.":rebuilding_logical_drive:".$scan_hpacucli_logical_drive_name, set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); } elsif ($new_scan_hpacucli_logical_drive_status =~ /Recovering, (.*?)% complete/i) { # We'll set an alert so that one alert goes out when # the rebuild starts. $recovered = $1; my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_logical_drive_uuid.":rebuilding_logical_drive:".$scan_hpacucli_logical_drive_name, set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { recovered => $recovered, changed => $changed, }}); if ($changed) { # Let the user know the rebuild has started. $message_key = "scan_hpacucli_note_0039"; } else { # Still under way $alert_level = "notice"; $message_key = "scan_hpacucli_note_0040"; } } elsif (lc($new_scan_hpacucli_logical_drive_status) eq "interim recovery mode") { # Drive just failed. $alert_level = "critical"; $message_key = "scan_hpacucli_note_0041"; } # Send the alert my $variables = { logical_drive => $scan_hpacucli_logical_drive_name, array => $scan_hpacucli_array_name, serial_number => $scan_hpacucli_controller_serial_number, new_value => $new_scan_hpacucli_logical_drive_status, old_value => $old_scan_hpacucli_logical_drive_status, recovered => $recovered, }; my $log_level = (($alert_level eq "warning") or ($alert_level eq "critical")) ? 1 : 2; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => $alert_level, message => $message_key, variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } elsif (($new_scan_hpacucli_logical_drive_os_device_name ne $old_scan_hpacucli_logical_drive_os_device_name) or ($new_scan_hpacucli_logical_drive_type ne $old_scan_hpacucli_logical_drive_type) or ($new_scan_hpacucli_logical_drive_raid_level ne $old_scan_hpacucli_logical_drive_raid_level) or ($new_scan_hpacucli_logical_drive_size ne $old_scan_hpacucli_logical_drive_size) or ($new_scan_hpacucli_logical_drive_strip_size ne $old_scan_hpacucli_logical_drive_strip_size) or ($new_scan_hpacucli_logical_drive_stripe_size ne $old_scan_hpacucli_logical_drive_stripe_size)) { # Something else changed. This should normally never happen. $update = 1; my $variables = { logical_drive => $scan_hpacucli_logical_drive_name, array => $scan_hpacucli_array_name, serial_number => $scan_hpacucli_controller_serial_number, new_os_drive_name => $new_scan_hpacucli_logical_drive_os_device_name, old_os_drive_name => $old_scan_hpacucli_logical_drive_os_device_name, new_type => $new_scan_hpacucli_logical_drive_type, old_type => $old_scan_hpacucli_logical_drive_type, new_raid_level => $new_scan_hpacucli_logical_drive_raid_level, old_raid_level => $old_scan_hpacucli_logical_drive_raid_level, new_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_size}), old_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_hpacucli_logical_drive_size}), new_strip_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_strip_size}), old_strip_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_hpacucli_logical_drive_strip_size}), new_stripe_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_stripe_size}), old_stripe_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_hpacucli_logical_drive_stripe_size}), }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0042", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0042", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } # If something changed, UPDATE. if ($update) { # Quote the numbers. my $quoted_scan_hpacucli_logical_drive_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_size); my $quoted_scan_hpacucli_logical_drive_strip_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_strip_size); my $quoted_scan_hpacucli_logical_drive_stripe_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_stripe_size); $quoted_scan_hpacucli_logical_drive_size =~ s/^'(.*?)'$/$1/; $quoted_scan_hpacucli_logical_drive_strip_size =~ s/^'(.*?)'$/$1/; $quoted_scan_hpacucli_logical_drive_stripe_size =~ s/^'(.*?)'$/$1/; # Do the update my $query = " UPDATE scan_hpacucli_logical_drives SET scan_hpacucli_logical_drive_array_uuid = ".$anvil->Database->quote($scan_hpacucli_array_uuid).", scan_hpacucli_logical_drive_name = ".$anvil->Database->quote($scan_hpacucli_logical_drive_name).", scan_hpacucli_logical_drive_caching = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_caching).", scan_hpacucli_logical_drive_os_device_name = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_os_device_name).", scan_hpacucli_logical_drive_type = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_type).", scan_hpacucli_logical_drive_raid_level = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_raid_level).", scan_hpacucli_logical_drive_size = $quoted_scan_hpacucli_logical_drive_size, scan_hpacucli_logical_drive_strip_size = $quoted_scan_hpacucli_logical_drive_strip_size, scan_hpacucli_logical_drive_stripe_size = $quoted_scan_hpacucli_logical_drive_stripe_size, scan_hpacucli_logical_drive_status = ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_status).", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_logical_drive_uuid = ".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } else { # New, INSERT. $scan_hpacucli_logical_drive_uuid = $anvil->Get->uuid(); $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name} = $scan_hpacucli_logical_drive_uuid; $anvil->data->{'scan-hpacucli'}{logical_drives}{by_uuid}{$scan_hpacucli_logical_drive_uuid} = $scan_hpacucli_logical_drive_name; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::logical_drives::by_name::${scan_hpacucli_logical_drive_name}" => $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name}, "scan-hpacucli::logical_drives::by_uuid::${scan_hpacucli_logical_drive_uuid}" => $anvil->data->{'scan-hpacucli'}{logical_drives}{by_uuid}{$scan_hpacucli_logical_drive_uuid}, }}); # Send an alert telling the user that we've found a new controller. my $variables = { name => $scan_hpacucli_array_name, logical_drive => $scan_hpacucli_logical_drive_name, new_caching => $new_scan_hpacucli_logical_drive_caching, new_os_device_name => $new_scan_hpacucli_logical_drive_os_device_name, new_type => $new_scan_hpacucli_logical_drive_type, new_raid_level => $new_scan_hpacucli_logical_drive_raid_level, new_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_size}), new_strip_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_strip_size}), new_stripe_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_logical_drive_stripe_size}), new_status => $new_scan_hpacucli_logical_drive_status, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0033", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0033", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); ### NOTE: The rest of the alerts will be in the format '- Variable: [$value]'. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0003", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0003", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # Quote some stuff manually my $quoted_scan_hpacucli_logical_drive_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_size); my $quoted_scan_hpacucli_logical_drive_strip_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_strip_size); my $quoted_scan_hpacucli_logical_drive_stripe_size = $anvil->Database->quote($new_scan_hpacucli_logical_drive_stripe_size); $quoted_scan_hpacucli_logical_drive_size =~ s/^'(.*?)'$/$1/; $quoted_scan_hpacucli_logical_drive_strip_size =~ s/^'(.*?)'$/$1/; $quoted_scan_hpacucli_logical_drive_stripe_size =~ s/^'(.*?)'$/$1/; # Now INERT variables. my $query = " INSERT INTO scan_hpacucli_logical_drives ( scan_hpacucli_logical_drive_uuid, scan_hpacucli_logical_drive_host_uuid, scan_hpacucli_logical_drive_array_uuid, scan_hpacucli_logical_drive_name, scan_hpacucli_logical_drive_caching, scan_hpacucli_logical_drive_os_device_name, scan_hpacucli_logical_drive_type, scan_hpacucli_logical_drive_raid_level, scan_hpacucli_logical_drive_size, scan_hpacucli_logical_drive_strip_size, scan_hpacucli_logical_drive_stripe_size, scan_hpacucli_logical_drive_status, modified_date ) VALUES ( ".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid).", ".$anvil->Database->quote($anvil->Get->host_uuid).", ".$anvil->Database->quote($scan_hpacucli_array_uuid).", ".$anvil->Database->quote($scan_hpacucli_logical_drive_name).", ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_caching).", ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_os_device_name).", ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_type).", ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_raid_level).", $quoted_scan_hpacucli_logical_drive_size, $quoted_scan_hpacucli_logical_drive_strip_size, $quoted_scan_hpacucli_logical_drive_stripe_size, ".$anvil->Database->quote($new_scan_hpacucli_logical_drive_status).", ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." );"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } # Process logical drive variables now. Note that there are no temperatures. foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}}) { # Insert the variables. my $new_scan_hpacucli_variable_value = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{data}{detail}{$scan_hpacucli_variable_name}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_variable_name => $scan_hpacucli_variable_name, new_scan_hpacucli_variable_value => $new_scan_hpacucli_variable_value, }}); # Have we seen this variable before? $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::scan_hpacucli_logical_drives::source_uuid::${scan_hpacucli_logical_drive_uuid}::detail::${scan_hpacucli_variable_name}::scan_hpacucli_variable_uuid" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}, }}); if ($anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}) { # Exists. Has it changed? my $scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}; my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid, old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value, }}); # delete this so that we know it was processed. delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_logical_drives}{source_uuid}{$scan_hpacucli_logical_drive_uuid}{detail}{$scan_hpacucli_variable_name}; if ($old_scan_hpacucli_variable_value ne $new_scan_hpacucli_variable_value) { # Now update. Alert the user as a warning, this # should rarely ever change. my $variables = { logical_drive => $scan_hpacucli_logical_drive_name, array => $scan_hpacucli_array_name, serial_number => $scan_hpacucli_controller_serial_number, variable_name => $scan_hpacucli_variable_name, old_value => $old_scan_hpacucli_variable_value ? $old_scan_hpacucli_variable_value : "--", new_value => $new_scan_hpacucli_variable_value ? $new_scan_hpacucli_variable_value : "--", }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0066", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0066", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # UPDATE my $query = " UPDATE scan_hpacucli_variables SET scan_hpacucli_variable_value = ".$anvil->Database->quote($new_scan_hpacucli_variable_value).", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_variable_uuid = ".$anvil->Database->quote($scan_hpacucli_variable_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } else { # New. Alert the user. my $variables = { name => $scan_hpacucli_variable_name, value => $new_scan_hpacucli_variable_value, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0004", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0004", variables => $variables, show_header => 0, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # INSERT my $query = " INSERT INTO scan_hpacucli_variables ( scan_hpacucli_variable_uuid, scan_hpacucli_variable_host_uuid, scan_hpacucli_variable_source_table, scan_hpacucli_variable_source_uuid, scan_hpacucli_variable_is_temperature, scan_hpacucli_variable_name, scan_hpacucli_variable_value, modified_date ) VALUES ( ".$anvil->Database->quote($anvil->Get->uuid()).", ".$anvil->Database->quote($anvil->Get->host_uuid).", 'scan_hpacucli_logical_drives', ".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid).", FALSE, ".$anvil->Database->quote($scan_hpacucli_variable_name).", ".$anvil->Database->quote($new_scan_hpacucli_variable_value).", ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." );"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } # Physical Disks. foreach my $port (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}}) { foreach my $box (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}}) { foreach my $bay (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}}) { # Throw this into a function to get out of # indent-hell. process_a_drive($anvil, $scan_hpacucli_controller_serial_number, $scan_hpacucli_logical_drive_uuid, $scan_hpacucli_array_name, $scan_hpacucli_logical_drive_name, $port, $box, $bay); } } } } } # Look for deleted arrays. foreach my $scan_hpacucli_array_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}}) { my $old_scan_hpacucli_array_name = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_name}; my $old_scan_hpacucli_array_controller_uuid = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_controller_uuid}; my $old_scan_hpacucli_controller_serial_number = $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$old_scan_hpacucli_array_controller_uuid}; my $old_scan_hpacucli_array_status = $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_status}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_scan_hpacucli_array_name => $old_scan_hpacucli_array_name, old_scan_hpacucli_array_controller_uuid => $old_scan_hpacucli_array_controller_uuid, old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number, old_scan_hpacucli_array_status => $old_scan_hpacucli_array_status, }}); next if $old_scan_hpacucli_array_name eq "ZZZZ"; next if $old_scan_hpacucli_array_status eq "VANISHED"; my $variables = { name => $old_scan_hpacucli_array_name, serial_number => $old_scan_hpacucli_controller_serial_number, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0031", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0031", variables => $variables, show_header => 0, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); my $query = " UPDATE scan_hpacucli_arrays SET scan_hpacucli_array_status = 'VANISHED', modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_array_uuid = ".$anvil->Database->quote($scan_hpacucli_array_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } # Look for deleted logical drives. foreach my $scan_hpacucli_logical_drive_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}}) { # Look for changes my $old_scan_hpacucli_logical_drive_array_uuid = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_array_uuid}; my $old_scan_hpacucli_logical_drive_name = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_name}; my $old_scan_hpacucli_logical_drive_status = $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_status}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_logical_drive_uuid => $scan_hpacucli_logical_drive_uuid, old_scan_hpacucli_logical_drive_array_uuid => $old_scan_hpacucli_logical_drive_array_uuid, old_scan_hpacucli_logical_drive_name => $old_scan_hpacucli_logical_drive_name, old_scan_hpacucli_logical_drive_status => $old_scan_hpacucli_logical_drive_status, }}); next if $old_scan_hpacucli_logical_drive_name eq "9999"; next if $old_scan_hpacucli_logical_drive_status eq "VANISHED"; my $variables = { logical_drive => $old_scan_hpacucli_logical_drive_name, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0044", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0044", variables => $variables, show_header => 0, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); my $query = " UPDATE scan_hpacucli_logical_drives SET scan_hpacucli_logical_drive_status = 'VANISHED', modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_logical_drive_uuid = ".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } # Now commit the changes. $anvil->Database->write({query => $anvil->data->{'scan-hpacucli'}{queries}, source => $THIS_FILE, line => __LINE__}); $anvil->data->{'scan-hpacucli'}{queries} = []; return(0); } # Process a specific drive sub process_a_drive { my ($anvil, $scan_hpacucli_controller_serial_number, $scan_hpacucli_logical_drive_uuid, $scan_hpacucli_array_name, $scan_hpacucli_logical_drive_name, $port, $box, $bay) = @_; my $scan_hpacucli_physical_drive_uuid = ""; my $scan_hpacucli_physical_drive_serial_number = ""; my $new_scan_hpacucli_physical_drive_model = ""; my $new_scan_hpacucli_physical_drive_interface = ""; my $new_scan_hpacucli_physical_drive_status = ""; my $new_scan_hpacucli_physical_drive_size = 0; my $new_scan_hpacucli_physical_drive_type = ""; my $new_scan_hpacucli_physical_drive_rpm = 0; my $new_scan_hpacucli_physical_drive_temperature = ""; my $new_scan_hpacucli_physical_drive_last_failure_reason = ""; my $maximum_drive_temperature = 0; # Serial Number if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{serial_number}) { $scan_hpacucli_physical_drive_serial_number = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{serial_number}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_physical_drive_serial_number => $scan_hpacucli_physical_drive_serial_number }}); } # Model if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{model}) { $new_scan_hpacucli_physical_drive_model = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{model}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_model => $new_scan_hpacucli_physical_drive_model }}); } # Interface if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{interface_type}) { $new_scan_hpacucli_physical_drive_interface = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{interface_type}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_interface => $new_scan_hpacucli_physical_drive_interface }}); } # Status if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{status}) { $new_scan_hpacucli_physical_drive_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{status}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_status => $new_scan_hpacucli_physical_drive_status }}); } # Size if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{size}) { $new_scan_hpacucli_physical_drive_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{size}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "new_scan_hpacucli_physical_drive_size" => $new_scan_hpacucli_physical_drive_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_physical_drive_size}).")", }}); } # Type if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{drive_type}) { $new_scan_hpacucli_physical_drive_type = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{drive_type}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_type => $new_scan_hpacucli_physical_drive_type }}); } # RPM (0 if SSD) if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{rotational_speed}) { $new_scan_hpacucli_physical_drive_rpm = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{rotational_speed}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_rpm => $new_scan_hpacucli_physical_drive_rpm }}); } # Temperature if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{temperature}{current_temperature}) { $new_scan_hpacucli_physical_drive_temperature = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{temperature}{current_temperature}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_temperature => $new_scan_hpacucli_physical_drive_temperature }}); } # Last failure reason if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{last_failure_reason}) { $new_scan_hpacucli_physical_drive_last_failure_reason = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{last_failure_reason}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_physical_drive_last_failure_reason => $new_scan_hpacucli_physical_drive_last_failure_reason }}); } # Maximum temperature if ($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{temperature}{maximum_temperature}) { $maximum_drive_temperature = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{temperature}{maximum_temperature}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { maximum_drive_temperature => $maximum_drive_temperature }}); } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_physical_drive_serial_number => $scan_hpacucli_physical_drive_serial_number, new_scan_hpacucli_physical_drive_model => $new_scan_hpacucli_physical_drive_model, new_scan_hpacucli_physical_drive_interface => $new_scan_hpacucli_physical_drive_interface, new_scan_hpacucli_physical_drive_status => $new_scan_hpacucli_physical_drive_status, new_scan_hpacucli_physical_drive_size => $new_scan_hpacucli_physical_drive_size, new_scan_hpacucli_physical_drive_type => $new_scan_hpacucli_physical_drive_type, new_scan_hpacucli_physical_drive_rpm => $new_scan_hpacucli_physical_drive_rpm, new_scan_hpacucli_physical_drive_temperature => $new_scan_hpacucli_physical_drive_temperature, new_scan_hpacucli_physical_drive_last_failure_reason => $new_scan_hpacucli_physical_drive_last_failure_reason, maximum_drive_temperature => $maximum_drive_temperature, }}); # Delete the Port, Box and Bay values so that they don't get processed as their own variables. delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{port}; delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{box}; delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{bay}; # Die if we don't have a serial number if (not $scan_hpacucli_physical_drive_serial_number) { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0011", variables => { serial_number => $scan_hpacucli_controller_serial_number, array_name => $scan_hpacucli_array_name, logical_drive_name => $scan_hpacucli_logical_drive_name, port => $port, box => $box, bay => $bay, }}); $anvil->nice_exit({exit_code => 9}); } # Have we seen this drive before? if ($anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number}) { # Yup! Look for changes. $scan_hpacucli_physical_drive_uuid = $anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_physical_drive_uuid => $scan_hpacucli_physical_drive_uuid }}); # Gather the old data. my $old_scan_hpacucli_logical_drive_uuid = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_logical_drive_uuid}; my $old_scan_hpacucli_physical_drive_model = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_model}; my $old_scan_hpacucli_physical_drive_interface = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_interface}; my $old_scan_hpacucli_physical_drive_status = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_status}; my $old_scan_hpacucli_physical_drive_size = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_size}; my $old_scan_hpacucli_physical_drive_type = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_type}; my $old_scan_hpacucli_physical_drive_rpm = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_rpm}; my $old_scan_hpacucli_physical_drive_temperature = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_temperature}; my $old_scan_hpacucli_physical_drive_last_failure_reason = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_last_failure_reason}; my $old_scan_hpacucli_physical_drive_port = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_port}; my $old_scan_hpacucli_physical_drive_box = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_box}; my $old_scan_hpacucli_physical_drive_bay = $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_bay}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_scan_hpacucli_logical_drive_uuid => $old_scan_hpacucli_logical_drive_uuid, old_scan_hpacucli_physical_drive_model => $old_scan_hpacucli_physical_drive_model, old_scan_hpacucli_physical_drive_interface => $old_scan_hpacucli_physical_drive_interface, old_scan_hpacucli_physical_drive_status => $old_scan_hpacucli_physical_drive_status, old_scan_hpacucli_physical_drive_size => $old_scan_hpacucli_physical_drive_size, old_scan_hpacucli_physical_drive_type => $old_scan_hpacucli_physical_drive_type, old_scan_hpacucli_physical_drive_rpm => $old_scan_hpacucli_physical_drive_rpm, old_scan_hpacucli_physical_drive_temperature => $old_scan_hpacucli_physical_drive_temperature, old_scan_hpacucli_physical_drive_last_failure_reason => $old_scan_hpacucli_physical_drive_last_failure_reason, old_scan_hpacucli_physical_drive_port => $old_scan_hpacucli_physical_drive_port, old_scan_hpacucli_physical_drive_box => $old_scan_hpacucli_physical_drive_box, old_scan_hpacucli_physical_drive_bay => $old_scan_hpacucli_physical_drive_bay, }}); # delete this so that we know it was processed. delete $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}; my $update = 0; # Did the drive move between logical drives? if ($scan_hpacucli_logical_drive_uuid ne $old_scan_hpacucli_logical_drive_uuid) { $update = 1; # We'll need to get the host, controller serial number and array name my $query = " SELECT a.host_name, b.scan_hpacucli_controller_serial_number, c.scan_hpacucli_array_name, d.scan_hpacucli_logical_drive_name FROM hosts a, scan_hpacucli_controllers b, scan_hpacucli_arrays c, scan_hpacucli_logical_drives d WHERE a.host_uuid = b.scan_hpacucli_controller_host_uuid AND b.scan_hpacucli_controller_uuid = c.scan_hpacucli_array_controller_uuid AND c.scan_hpacucli_array_uuid = d.scan_hpacucli_logical_drive_array_uuid AND c.scan_hpacucli_array_uuid = ".$anvil->Database->quote($old_scan_hpacucli_logical_drive_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); my $count = @{$results}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { results => $results, count => $count, }}); my $old_host_name = $results->[0]->[0] ? $results->[0]->[0] : "--"; my $old_scan_hpacucli_controller_serial_number = $results->[0]->[1] ? $results->[0]->[1] : "--"; my $old_scan_hpacucli_array_name = $results->[0]->[2] ? $results->[0]->[2] : "--"; my $old_scan_hpacucli_logical_drive_name = $results->[0]->[3] ? $results->[0]->[3] : "--"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_host_name => $old_host_name, old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number, old_scan_hpacucli_array_name => $old_scan_hpacucli_array_name, old_scan_hpacucli_logical_drive_name => $old_scan_hpacucli_logical_drive_name, }}); # Send an alert telling the drive has moved. my $variables = { drive_serial_number => $scan_hpacucli_physical_drive_serial_number, old_host_name => $old_host_name, new_host_name => $anvil->Get->host_name, new_controller_serial_number => $scan_hpacucli_controller_serial_number, old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number, new_array_name => $scan_hpacucli_array_name, old_array_name => $scan_hpacucli_array_name, new_logical_drive_name => $scan_hpacucli_logical_drive_name, old_logical_drive_name => $old_scan_hpacucli_logical_drive_name }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0047", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0047", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } # Has the status changed? if ($old_scan_hpacucli_physical_drive_status ne $new_scan_hpacucli_physical_drive_status) { $update = 1; # Yup. Start with an alert about it being not OK, and change if it is now OK. my $cleared = 0; my $message_key = "scan_hpacucli_note_0048"; # Did it return? if ($old_scan_hpacucli_physical_drive_status eq "VANISHED") { # The drive is back. $message_key = "scan_hpacucli_note_0050"; } elsif (lc($new_scan_hpacucli_physical_drive_status) eq "ok") { # Drive is OK again. $cleared = 1; $message_key = "scan_hpacucli_note_0051"; } my $variables = { serial_number => $scan_hpacucli_physical_drive_serial_number, old_status => $old_scan_hpacucli_physical_drive_status, new_status => $new_scan_hpacucli_physical_drive_status, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => "warning", message => $message_key, variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } # Did the temperature change? Whether it did or not, we need to record the current # temperature state. ### NOTE: HP tells us the maximum temperature each of its drives can handle. This is ### a low number, so we need to tighten up some thresholds compared to usual ### ranges. # Set defaults my $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{high_critical}; my $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{high_warning}; my $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{low_warning}; my $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{low_critical}; my $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{jump}; my $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{buffer}; my $clear_high_critical = $high_critical - $buffer; my $clear_high_warning = $high_warning - $buffer; my $clear_low_critical = $low_critical - $buffer; my $clear_low_warning = $low_warning - $buffer; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { high_critical => $high_critical, high_warning => $high_warning, low_warning => $low_warning, low_critical => $low_critical, jump => $jump, buffer => $buffer, clear_high_critical => $clear_high_critical, clear_high_warning => $clear_high_warning, clear_low_critical => $clear_low_critical, clear_low_warning => $clear_low_warning, }}); # Fine-tune the alert thresholds if ($clear_high_critical < $high_warning) { $clear_high_critical = $high_warning + 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }}); } if ($clear_low_critical > $low_warning) { $clear_low_critical = $low_warning - 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }}); } # Did we get a maximum temperature from the drive? $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { maximum_drive_temperature => $maximum_drive_temperature, "scan-hpacucli::ignore_maximum_temperature" => $anvil->data->{'scan-hpacucli'}{ignore_maximum_temperature}, }}); if (($maximum_drive_temperature) && (not $anvil->data->{'scan-hpacucli'}{ignore_maximum_temperature})) { $high_critical = $maximum_drive_temperature; $high_warning = $maximum_drive_temperature - 2; $clear_high_critical = $high_critical - $buffer; $clear_high_warning = $high_warning - $buffer; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { high_critical => $high_critical, high_warning => $high_warning, clear_high_critical => $clear_high_critical, clear_high_warning => $clear_high_warning, }}); # Fine-tune the alert thresholds if ($clear_high_critical < $high_warning) { $clear_high_critical = $high_warning + 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }}); } if ($clear_low_critical > $low_warning) { $clear_low_critical = $low_warning - 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }}); } } # Clear alerts, if needed. The order is important as clearing a warning will replace # clearing a critical when a sensor goes critical -> ok in one scan. Once done, we'll # check if we've crossed into a warning or critical state. If so, those will replace # any cleared messages. my $cleared = 0; my $alert_level = "info"; my $message_key = "scan_hpacucli_note_0053"; my $delta = 0; if ($new_scan_hpacucli_physical_drive_temperature) { if ($new_scan_hpacucli_physical_drive_temperature < $clear_high_critical) { my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $cleared = 1; $alert_level = "critical"; $message_key = "scan_hpacucli_note_0054"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cleared => $cleared, alert_level => $alert_level, message_key => $message_key, }}); } } if ($new_scan_hpacucli_physical_drive_temperature < $clear_high_warning) { my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { # The temperature is no longer # warning, and it didn't just go # critical $cleared = 1; $alert_level = "warning"; $message_key = "scan_hpacucli_note_0055"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cleared => $cleared, alert_level => $alert_level, message_key => $message_key, }}); } } if ($new_scan_hpacucli_physical_drive_temperature > $clear_low_critical) { my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $cleared = 1; $alert_level = "critical"; $message_key = "scan_hpacucli_note_0056"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cleared => $cleared, alert_level => $alert_level, message_key => $message_key, }}); } } if ($new_scan_hpacucli_physical_drive_temperature > $clear_low_warning) { my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $cleared = 1; $alert_level = "warning"; $message_key = "scan_hpacucli_note_0057"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cleared => $cleared, alert_level => $alert_level, message_key => $message_key, }}); } } # Now see if the temperature has crossed into a warning or critical state. my $temperature_state = "ok"; my $temperature_is = "nominal"; if ($new_scan_hpacucli_physical_drive_temperature > $high_critical) { # Crossed the high critical threshold. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "critical"; $message_key = "scan_hpacucli_note_0060"; } $temperature_state = "critical"; $temperature_is = "high"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_physical_drive_temperature > $high_warning) { # Crossed the high warning threshold. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "warning"; $message_key = "scan_hpacucli_note_0061"; } $temperature_state = "warning"; $temperature_is = "high"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_physical_drive_temperature < $low_critical) { # Dropped below the low critical threshold. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "critical"; $message_key = "scan_hpacucli_note_0062"; } $temperature_state = "critical"; $temperature_is = "low"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "temperature_state" => $temperature_state, "temperature_is" => $temperature_is, }}); } elsif ($new_scan_hpacucli_physical_drive_temperature < $low_warning) { # Crossed the low warning threshold. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "warning"; $message_key = "scan_hpacucli_note_0063"; } $temperature_state = "warning"; $temperature_is = "low"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } else { # Did it change enough to trigger a jump alert? if ($new_scan_hpacucli_physical_drive_temperature > $old_scan_hpacucli_physical_drive_temperature) { # Jumped $delta = $new_scan_hpacucli_physical_drive_temperature - $old_scan_hpacucli_physical_drive_temperature; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { delta => $delta }}); if ($delta >= $jump) { # Big jump. $alert_level = "warning"; $message_key = "scan_hpacucli_note_0058"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { alert_level => $alert_level, message_key => $message_key, }}); } } else { # Dropped $delta = $old_scan_hpacucli_physical_drive_temperature - $new_scan_hpacucli_physical_drive_temperature; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { delta => $delta }}); if ($delta >= $jump) { # Big drop. $alert_level = "warning"; $message_key = "scan_hpacucli_note_0059"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { alert_level => $alert_level, message_key => $message_key, }}); } } } # Record this for later processing into the 'temperature' table. my $sensor_host_key = "physical_drive:".$scan_hpacucli_physical_drive_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sensor_host_key => $sensor_host_key }}); $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_value_c} = $new_scan_hpacucli_physical_drive_temperature; $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_state} = $temperature_state; $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_is} = $temperature_is; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_value_c" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_value_c}, "new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_state" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_state}, "new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_is" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_is}, }}); } # Now, if the temperature changed, update and send an alert if appropriate. if ($new_scan_hpacucli_physical_drive_temperature ne $old_scan_hpacucli_physical_drive_temperature) { # Yup. Analyze $update = 1; # Send an alert telling the user that we've found a variable for this drive. Note # that we add ' C' to the temperatures so that they get translated to '°F' if desired # by the reader. my $variables = { serial_number => $scan_hpacucli_physical_drive_serial_number, old_temperature => $old_scan_hpacucli_physical_drive_temperature ? $old_scan_hpacucli_physical_drive_temperature." °C" : "--", new_temperature => $new_scan_hpacucli_physical_drive_temperature ? $new_scan_hpacucli_physical_drive_temperature." °C" : "--", delta => $delta." °C", high_critical_temperature => $high_critical." °C", high_warning_temperature => $high_warning." °C", low_critical_temperature => $low_critical." °C", low_warning_temperature => $low_warning." °C", }; my $log_level = (($alert_level eq "warning") or ($alert_level eq "critical")) ? 1 : 2; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => $alert_level, message => $message_key, variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } # Anything else? if (($old_scan_hpacucli_physical_drive_model ne $new_scan_hpacucli_physical_drive_model) or ($old_scan_hpacucli_physical_drive_interface ne $new_scan_hpacucli_physical_drive_interface) or ($old_scan_hpacucli_physical_drive_size ne $new_scan_hpacucli_physical_drive_size) or ($old_scan_hpacucli_physical_drive_rpm ne $new_scan_hpacucli_physical_drive_rpm) or ($new_scan_hpacucli_physical_drive_last_failure_reason ne $old_scan_hpacucli_physical_drive_last_failure_reason) or ($port ne $old_scan_hpacucli_physical_drive_port) or ($box ne $old_scan_hpacucli_physical_drive_box) or ($bay ne $old_scan_hpacucli_physical_drive_bay)) { # Something else changed. These normally shouldn't change... $update = 1; my $variables = { serial_number => $scan_hpacucli_physical_drive_serial_number, old_model => $old_scan_hpacucli_physical_drive_model, new_model => $new_scan_hpacucli_physical_drive_model, old_interface => $old_scan_hpacucli_physical_drive_interface, new_interface => $new_scan_hpacucli_physical_drive_interface, old_size => $anvil->Database->quote($old_scan_hpacucli_physical_drive_size), new_size => $anvil->Database->quote($new_scan_hpacucli_physical_drive_size), old_rpm => $old_scan_hpacucli_physical_drive_rpm, new_rpm => $new_scan_hpacucli_physical_drive_rpm, old_last_failure_reason => $old_scan_hpacucli_physical_drive_last_failure_reason ? $old_scan_hpacucli_physical_drive_last_failure_reason : "--", new_last_failure_reason => $new_scan_hpacucli_physical_drive_last_failure_reason ? $new_scan_hpacucli_physical_drive_last_failure_reason : "--", old_port => $old_scan_hpacucli_physical_drive_port, new_port => $port, old_box => $old_scan_hpacucli_physical_drive_box, new_box => $box, old_bay => $old_scan_hpacucli_physical_drive_bay, new_bay => $bay, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0052", variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => "warning", message => "scan_hpacucli_note_0052", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } if ($update) { # UPDATE my $query = " UPDATE scan_hpacucli_physical_drives SET scan_hpacucli_physical_drive_logical_drive_uuid = ".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid).", scan_hpacucli_physical_drive_serial_number = ".$anvil->Database->quote($scan_hpacucli_physical_drive_serial_number).", scan_hpacucli_physical_drive_model = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_model).", scan_hpacucli_physical_drive_interface = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_interface).", scan_hpacucli_physical_drive_status = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_status).", scan_hpacucli_physical_drive_size = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_size).", scan_hpacucli_physical_drive_type = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_type).", scan_hpacucli_physical_drive_rpm = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_rpm).", scan_hpacucli_physical_drive_temperature = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_temperature).", scan_hpacucli_physical_drive_last_failure_reason = ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_last_failure_reason).", scan_hpacucli_physical_drive_port = ".$anvil->Database->quote($port).", scan_hpacucli_physical_drive_box = ".$anvil->Database->quote($box).", scan_hpacucli_physical_drive_bay = ".$anvil->Database->quote($bay).", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_physical_drive_uuid = ".$anvil->Database->quote($scan_hpacucli_physical_drive_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } else { # New, INSERT it. $scan_hpacucli_physical_drive_uuid = $anvil->Get->uuid(); $anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number} = $scan_hpacucli_physical_drive_uuid; $anvil->data->{'scan-hpacucli'}{physical_drives}{by_uuid}{$scan_hpacucli_physical_drive_uuid} = $scan_hpacucli_physical_drive_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::physical_drives::by_serial::${scan_hpacucli_physical_drive_serial_number}" => $anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number}, "scan-hpacucli::physical_drives::by_uuid::${scan_hpacucli_physical_drive_uuid}" => $anvil->data->{'scan-hpacucli'}{physical_drives}{by_uuid}{$scan_hpacucli_physical_drive_uuid}, }}); # Send an alert telling the user we found a new drive. my $variables = { controller_serial_number => $scan_hpacucli_controller_serial_number, array_name => $scan_hpacucli_array_name, logical_drive_name => $scan_hpacucli_logical_drive_name, port => $port, box => $box, bay => $bay, drive_serial_number => $scan_hpacucli_physical_drive_serial_number, model => $new_scan_hpacucli_physical_drive_model, interface => $new_scan_hpacucli_physical_drive_interface, status => $new_scan_hpacucli_physical_drive_status, size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_physical_drive_size}), type => $new_scan_hpacucli_physical_drive_type, rpm => $new_scan_hpacucli_physical_drive_rpm, temperature => $new_scan_hpacucli_physical_drive_temperature ? $new_scan_hpacucli_physical_drive_temperature." °C" : "--", last_failure_reason => $new_scan_hpacucli_physical_drive_last_failure_reason ? $new_scan_hpacucli_physical_drive_last_failure_reason : "--", }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0046", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0046", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # Check for problems with this new drive. if (lc($new_scan_hpacucli_physical_drive_status) ne "ok") { # There's a problem, send an alert. my $variables = { controller_serial_number => $scan_hpacucli_controller_serial_number, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0064", variables => $variables}); $anvil->Alert->register({ alert_level => "warning", message => "scan_hpacucli_note_0064", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } # Check the temperature, if we read one. if ($new_scan_hpacucli_physical_drive_temperature =~ /^\d+/) { ### NOTE: HP tells us the maximum temperature each of its drives can handle. This is ### a low number, so we need to tighten up some thresholds compared to usual ### ranges. # Set defaults my $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{high_critical}; my $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{high_warning}; my $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{low_warning}; my $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{low_critical}; my $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{jump}; my $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{drives}{buffer}; my $clear_high_critical = $high_critical - $buffer; my $clear_high_warning = $high_warning - $buffer; my $clear_low_critical = $low_critical - $buffer; my $clear_low_warning = $low_warning - $buffer; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { high_critical => $high_critical, high_warning => $high_warning, low_warning => $low_warning, low_critical => $low_critical, jump => $jump, buffer => $buffer, clear_high_critical => $clear_high_critical, clear_high_warning => $clear_high_warning, clear_low_critical => $clear_low_critical, clear_low_warning => $clear_low_warning, }}); # Fine-tune the alert thresholds if ($clear_high_critical < $high_warning) { $clear_high_critical = $high_warning + 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }}); } if ($clear_low_critical > $low_warning) { $clear_low_critical = $low_warning - 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }}); } # Did we get a maximum temperature from the drive? $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { maximum_drive_temperature => $maximum_drive_temperature, "scan-hpacucli::ignore_maximum_temperature" => $anvil->data->{'scan-hpacucli'}{ignore_maximum_temperature}, }}); if (($maximum_drive_temperature) && (not $anvil->data->{'scan-hpacucli'}{ignore_maximum_temperature})) { $high_critical = $maximum_drive_temperature; $high_warning = $maximum_drive_temperature - 2; $clear_high_critical = $high_critical - $buffer; $clear_high_warning = $high_warning - $buffer; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { high_critical => $high_critical, high_warning => $high_warning, clear_high_critical => $clear_high_critical, clear_high_warning => $clear_high_warning, }}); # Fine-tune the alert thresholds if ($clear_high_critical < $high_warning) { $clear_high_critical = $high_warning + 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }}); } if ($clear_low_critical > $low_warning) { $clear_low_critical = $low_warning - 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }}); } } # See if the temperature outside of the warning or critical thresholds. my $temperature_state = "ok"; my $temperature_is = "nominal"; my $alert_level = "warning"; my $message_key = ""; if ($new_scan_hpacucli_physical_drive_temperature > $high_critical) { # Crossed the high critical threshold. This should always be unset because it # is a new variable, but check anyway. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "critical"; $message_key = "scan_hpacucli_note_0060"; } $temperature_state = "critical"; $temperature_is = "high"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_physical_drive_temperature > $high_warning) { # Crossed the high warning threshold. This should always be unset because it # is a new variable, but check anyway. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_high_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "warning"; $message_key = "scan_hpacucli_note_0061"; } $temperature_state = "warning"; $temperature_is = "high"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_physical_drive_temperature < $low_critical) { # Dropped below the low critical threshold. This should always be unset # because it is a new variable, but check anyway. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "critical"; $message_key = "scan_hpacucli_note_0062"; } $temperature_state = "critical"; $temperature_is = "low"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_physical_drive_temperature < $low_warning) { # Crossed the low warning threshold. This should always be unset because it # is a new variable, but check anyway. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":physical_drive_low_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "warning"; $message_key = "scan_hpacucli_note_0063"; } $temperature_state = "warning"; $temperature_is = "low"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } # Record this for later processing into the 'temperature' table. my $sensor_host_key = "physical_drive:".$scan_hpacucli_physical_drive_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sensor_host_key => $sensor_host_key }}); $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_value_c} = $new_scan_hpacucli_physical_drive_temperature; $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_state} = $temperature_state; $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_is} = $temperature_is; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_value_c" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_value_c}, "new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_state" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_state}, "new::temperature::scan_hpacucli_physical_drive_temperature::${sensor_host_key}::temperature_is" => $anvil->data->{new}{temperature}{scan_hpacucli_physical_drive_temperature}{$sensor_host_key}{temperature_is}, }}); if ($message_key) { # Send an alert telling the user that we've found a drive outside nominal # temperature. Note that we add ' C' to the temperatures so that they get # translated to '°F' if desired by the reader. my $variables = { serial_number => $scan_hpacucli_controller_serial_number, temperature => $new_scan_hpacucli_physical_drive_temperature ? $new_scan_hpacucli_physical_drive_temperature." °C" : "--", high_critical_temperature => $high_critical." °C", high_warning_temperature => $high_warning." °C", low_critical_temperature => $low_critical." °C", low_warning_temperature => $low_warning." °C", }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => $alert_level, message => $message_key, variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); ### NOTE: The rest of the alerts will be in the format '- Variable: [$value]'. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0003", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0003", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); } } my $query = " INSERT INTO scan_hpacucli_physical_drives ( scan_hpacucli_physical_drive_uuid, scan_hpacucli_physical_drive_host_uuid, scan_hpacucli_physical_drive_logical_drive_uuid, scan_hpacucli_physical_drive_serial_number, scan_hpacucli_physical_drive_model, scan_hpacucli_physical_drive_interface, scan_hpacucli_physical_drive_status, scan_hpacucli_physical_drive_size, scan_hpacucli_physical_drive_type, scan_hpacucli_physical_drive_rpm, scan_hpacucli_physical_drive_temperature, scan_hpacucli_physical_drive_last_failure_reason, scan_hpacucli_physical_drive_port, scan_hpacucli_physical_drive_box, scan_hpacucli_physical_drive_bay, modified_date ) VALUES ( ".$anvil->Database->quote($scan_hpacucli_physical_drive_uuid).", ".$anvil->Database->quote($anvil->Get->host_uuid).", ".$anvil->Database->quote($scan_hpacucli_logical_drive_uuid).", ".$anvil->Database->quote($scan_hpacucli_physical_drive_serial_number).", ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_model).", ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_interface).", ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_status).", ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_size).", ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_type).", ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_rpm).", ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_temperature).", ".$anvil->Database->quote($new_scan_hpacucli_physical_drive_last_failure_reason).", ".$anvil->Database->quote($port).", ".$anvil->Database->quote($box).", ".$anvil->Database->quote($bay).", ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." );"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } # Process physical drive variables now. Note that there are no temperatures. foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}}) { my $new_scan_hpacucli_variable_value = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{$scan_hpacucli_variable_name}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan_hpacucli_variable_name" => $scan_hpacucli_variable_name, "new_scan_hpacucli_variable_value" => $new_scan_hpacucli_variable_value, }}); # Have we seen this variable before? $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::scan_hpacucli_physical_drives::source_uuid::${scan_hpacucli_physical_drive_uuid}::detail::${scan_hpacucli_variable_name}::scan_hpacucli_variable_uuid" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}, }}); if ($anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}) { # Exists. Has it changed? my $scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}; my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid, old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value, }}); # delete this so that we know it was processed. delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}; if ($old_scan_hpacucli_variable_value ne $new_scan_hpacucli_variable_value) { # Now update. Alert the user as a warning, these should rarely ever change. my $variables = { serial_number => $scan_hpacucli_physical_drive_serial_number, variable_name => $scan_hpacucli_variable_name, old_value => $old_scan_hpacucli_variable_value ? $old_scan_hpacucli_variable_value : "--", new_value => $new_scan_hpacucli_variable_value ? $new_scan_hpacucli_variable_value : "--", }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0065", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0065", variables => $variables, show_header => 0, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # UPDATE my $query = " UPDATE scan_hpacucli_variables SET scan_hpacucli_variable_value = ".$anvil->Database->quote($new_scan_hpacucli_variable_value).", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_variable_uuid = ".$anvil->Database->quote($scan_hpacucli_variable_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } else { # Clear the hash key that was autovivified in the previous check so that it doesn't # cause a loop when looking for vanished values. delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}; # New. Alert the user. my $variables = { name => $scan_hpacucli_variable_name, value => $new_scan_hpacucli_variable_value, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0004", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0004", variables => $variables, show_header => 0, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # INSERT my $query = " INSERT INTO scan_hpacucli_variables ( scan_hpacucli_variable_uuid, scan_hpacucli_variable_host_uuid, scan_hpacucli_variable_source_table, scan_hpacucli_variable_source_uuid, scan_hpacucli_variable_is_temperature, scan_hpacucli_variable_name, scan_hpacucli_variable_value, modified_date ) VALUES ( ".$anvil->Database->quote($anvil->Get->uuid()).", ".$anvil->Database->quote($anvil->Get->host_uuid).", 'scan_hpacucli_physical_drives', ".$anvil->Database->quote($scan_hpacucli_physical_drive_uuid).", FALSE, ".$anvil->Database->quote($scan_hpacucli_variable_name).", ".$anvil->Database->quote($new_scan_hpacucli_variable_value).", ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." );"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } # Look for vanished variables for this drive. foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}}) { my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value}; my $old_scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drives}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{detail}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_variable_name => $scan_hpacucli_variable_name, old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value, old_scan_hpacucli_variable_uuid => $old_scan_hpacucli_variable_uuid, }}); # If the old alarm state is already 'VANISHED', ignore it. next if $old_scan_hpacucli_variable_value eq "VANISHED"; # Still here? Alert and UPDATE. ### NOTE: For now, we're going to use warning level because cache_modules ### should never vanish unless one failed. If that is the case, the ### admin already knows, but this will let other notification targets ### know that the change has happened. my $variables = { serial_number => $scan_hpacucli_physical_drive_serial_number, name => $scan_hpacucli_variable_name, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0067", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0067", variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); my $query = " UPDATE scan_hpacucli_variables SET scan_hpacucli_variable_value = 'VANISHED', modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_variable_uuid = ".$anvil->Database->quote($old_scan_hpacucli_variable_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } # If this was a diagnostics run, check for error counters if ($anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics}) { # These are stored in the DB as standard variables, but we use the source is # 'scan_hpacucli_physical_drive_diagnostics' to distinguish them. if (exists $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_hard}) { # We got the data foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}}) { # Store this in the main hash. my $new_scan_hpacucli_variable_value = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$scan_hpacucli_logical_drive_name}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{'diagnostics'}{$scan_hpacucli_variable_name}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_variable_name => $scan_hpacucli_variable_name, new_scan_hpacucli_variable_value => $new_scan_hpacucli_variable_value, }}); ### TODO # If the variable name has 'error' in it and the value is numeric, see if it # is > 5 and, if so, set the health. # Have we seen this variable before? $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::scan_hpacucli_physical_drive_diagnostics::source_uuid::${scan_hpacucli_physical_drive_uuid}::diagnostics::${scan_hpacucli_variable_name}::scan_hpacucli_variable_uuid" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}, }}); if ($anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}) { # Exists. Has it changed? my $scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}; my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid, old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value, }}); # Delete this so that we know it was processed. delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}; if ($old_scan_hpacucli_variable_value ne $new_scan_hpacucli_variable_value) { # Now update. Alert the user as a warning, these should rarely ever change. my $variables = { serial_number => $scan_hpacucli_physical_drive_serial_number, variable_name => $scan_hpacucli_variable_name, old_value => $old_scan_hpacucli_variable_value ? $old_scan_hpacucli_variable_value : "--", new_value => $new_scan_hpacucli_variable_value ? $new_scan_hpacucli_variable_value : "--", }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0065", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0065", variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # UPDATE my $query = " UPDATE scan_hpacucli_variables SET scan_hpacucli_variable_value = ".$anvil->Database->quote($new_scan_hpacucli_variable_value).", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_variable_uuid = ".$anvil->Database->quote($scan_hpacucli_variable_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } else { # Clear the hash key that was autovivified in the previous check so # that it doesn't cause a loop when looking for vanished values. delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}; # New. Alert the user. my $variables = { name => $scan_hpacucli_variable_name, value => $new_scan_hpacucli_variable_value, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0004", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0004", show_header => 0, variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # INSERT my $query = " INSERT INTO scan_hpacucli_variables ( scan_hpacucli_variable_uuid, scan_hpacucli_variable_host_uuid, scan_hpacucli_variable_source_table, scan_hpacucli_variable_source_uuid, scan_hpacucli_variable_is_temperature, scan_hpacucli_variable_name, scan_hpacucli_variable_value, modified_date ) VALUES ( ".$anvil->Database->quote($anvil->Get->uuid()).", ".$anvil->Database->quote($anvil->Get->host_uuid).", 'scan_hpacucli_physical_drive_diagnostics', ".$anvil->Database->quote($scan_hpacucli_physical_drive_uuid).", FALSE, ".$anvil->Database->quote($scan_hpacucli_variable_name).", ".$anvil->Database->quote($new_scan_hpacucli_variable_value).", ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." );"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } } # Look for vanished diagnostics variables. foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}}) { my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value}; my $old_scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_physical_drive_diagnostics}{source_uuid}{$scan_hpacucli_physical_drive_uuid}{'diagnostics'}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_variable_name => $scan_hpacucli_variable_name, old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value, old_scan_hpacucli_variable_uuid => $old_scan_hpacucli_variable_uuid, }}); # If the old alarm state is already 'VANISHED', ignore it. next if $old_scan_hpacucli_variable_value eq "VANISHED"; # Still here? Alert and UPDATE. ### NOTE: For now, we're going to use warning level because cache_modules ### should never vanish unless one failed. If that is the case, the ### admin already knows, but this will let other notification targets ### know that the change has happened. my $variables = { serial_number => $scan_hpacucli_physical_drive_serial_number, name => $scan_hpacucli_variable_name, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0068", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0068", show_header => 1, variables => $variables, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); my $query = " UPDATE scan_hpacucli_variables SET scan_hpacucli_variable_value = 'VANISHED', modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_variable_uuid = ".$anvil->Database->quote($old_scan_hpacucli_variable_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } return(0); } # Look for added, changed or deleted controllers. sub process_controllers { my ($anvil) = @_; # Look for new, changed or deleted controllers. $anvil->data->{'scan-hpacucli'}{queries} = []; foreach my $scan_hpacucli_controller_serial_number (sort {$a cmp $b} keys %{$anvil->data->{controller}}) { # Controller data; next if $scan_hpacucli_controller_serial_number eq "metadata"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number, "scan-hpacucli::controllers::by_serial::$scan_hpacucli_controller_serial_number" => $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number}, }}); # Have we seen this controller before? my $scan_hpacucli_controller_uuid = ""; my $controller_is_new = 0; if ($anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number}) { # Yup! $scan_hpacucli_controller_uuid = $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_uuid => $scan_hpacucli_controller_uuid }}); } else { # No, this is a new controller. Create a new UUID for it. $scan_hpacucli_controller_uuid = $anvil->Get->uuid(); $controller_is_new = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_uuid => $scan_hpacucli_controller_uuid, controller_is_new => $controller_is_new, }}); # Add the keys for looking it up by UUID or serial number. $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number} = $scan_hpacucli_controller_uuid; $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid} = $scan_hpacucli_controller_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::controllers::by_serial::$scan_hpacucli_controller_serial_number" => $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number}, "scan-hpacucli::controllers::by_uuid::$scan_hpacucli_controller_uuid" => $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid}, }}); } # These are the values for the controller and cache tables. Anything else will go in the # variables table which will be processed after the controller. # Controller my $new_scan_hpacucli_controller_model = ""; my $new_scan_hpacucli_controller_status = ""; my $new_scan_hpacucli_controller_last_diagnostics = $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics} ? time : ""; my $new_scan_hpacucli_controller_cache_present = "unknown"; my $new_scan_hpacucli_controller_drive_write_cache = ""; my $new_scan_hpacucli_controller_firmware_version = ""; my $new_scan_hpacucli_controller_unsafe_writeback_cache = ""; # Cache my $new_scan_hpacucli_cache_module_size = ""; my $new_scan_hpacucli_cache_module_serial_number = ""; my $new_scan_hpacucli_cache_module_status = ""; my $new_scan_hpacucli_cache_module_type = ""; foreach my $type ("detail", "temperature") { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }}); foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}}) { # Pick up the variables for the controller if (($type eq "detail") && ($variable eq "model_name")) { # Store and delete the value $new_scan_hpacucli_controller_model = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_model => $new_scan_hpacucli_controller_model }}); next; } elsif (($type eq "detail") && ($variable eq "controller_status")) { # Store and delete the value $new_scan_hpacucli_controller_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $new_scan_hpacucli_controller_status = lc($new_scan_hpacucli_controller_status); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_status => $new_scan_hpacucli_controller_status }}); next; } elsif (($type eq "detail") && ($variable eq "cache_board_present")) { # Store and delete the value $new_scan_hpacucli_controller_cache_present = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $new_scan_hpacucli_controller_cache_present = lc($new_scan_hpacucli_controller_cache_present); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_cache_present => $new_scan_hpacucli_controller_cache_present }}); next; } elsif (($type eq "detail") && ($variable eq "drive_write_cache")) { # Store and delete the value $new_scan_hpacucli_controller_drive_write_cache = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $new_scan_hpacucli_controller_drive_write_cache = lc($new_scan_hpacucli_controller_drive_write_cache); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_drive_write_cache => $new_scan_hpacucli_controller_drive_write_cache }}); next; } elsif (($type eq "detail") && ($variable eq "firmware_version")) { # Store and delete the value $new_scan_hpacucli_controller_firmware_version = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_firmware_version => $new_scan_hpacucli_controller_firmware_version }}); next; } elsif (($type eq "detail") && ($variable eq "no_battery_write_cache")) { # Store and delete the value $new_scan_hpacucli_controller_unsafe_writeback_cache = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $new_scan_hpacucli_controller_unsafe_writeback_cache = lc($new_scan_hpacucli_controller_unsafe_writeback_cache); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_controller_unsafe_writeback_cache => $new_scan_hpacucli_controller_unsafe_writeback_cache }}); next; } # Pick up the data for the cache. elsif (($type eq "detail") && ($variable eq "total_cache_size")) { # Store and delete the value $new_scan_hpacucli_cache_module_size = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_cache_module_size => $new_scan_hpacucli_cache_module_size }}); next; } elsif (($type eq "detail") && ($variable eq "cache_serial_number")) { # Store and delete the value $new_scan_hpacucli_cache_module_serial_number = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_cache_module_serial_number => $new_scan_hpacucli_cache_module_serial_number }}); next; } elsif (($type eq "detail") && ($variable eq "cache_status")) { # Store and delete the value $new_scan_hpacucli_cache_module_status = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $new_scan_hpacucli_cache_module_status = lc($new_scan_hpacucli_cache_module_status); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_cache_module_status => $new_scan_hpacucli_cache_module_status }}); next; } elsif (($type eq "detail") && ($variable eq "cache_backup_power_source")) { # Store and delete the value $new_scan_hpacucli_cache_module_type = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; $new_scan_hpacucli_cache_module_type = lc($new_scan_hpacucli_cache_module_type); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_cache_module_type => $new_scan_hpacucli_cache_module_type }}); next; } else { # Just for debug $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::data::${type}::${variable}" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}, }}); } } } # Pull out the rest of the variables now. If the controller is new, all variables will be # INSERTed. If the controller exists, each variable will be examined and new ones will be # INSERTed, existing ones will be checked for changes and UPDATEd as needed. If the # controller is NOT new, then variables from the old data will be deleted as we go and any # not found in the current data set will be left over. We'll use this to determine variables # that have vanished. They will not be deleted, but their value will be set to 'VANISHED'. if ($controller_is_new) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number, new_scan_hpacucli_controller_model => $new_scan_hpacucli_controller_model, new_scan_hpacucli_controller_cache_present => $new_scan_hpacucli_controller_cache_present, new_scan_hpacucli_controller_drive_write_cache => $new_scan_hpacucli_controller_drive_write_cache, new_scan_hpacucli_controller_firmware_version => $new_scan_hpacucli_controller_firmware_version, new_scan_hpacucli_controller_unsafe_writeback_cache => $new_scan_hpacucli_controller_unsafe_writeback_cache, }}); # Send an alert telling the user that we've found a new controller. my $variables = { model => $new_scan_hpacucli_controller_model, serial_number => $scan_hpacucli_controller_serial_number, status => $new_scan_hpacucli_controller_status, drive_write_cache => $new_scan_hpacucli_controller_drive_write_cache, firmware_version => $new_scan_hpacucli_controller_firmware_version, unsafe_writeback_cache => $new_scan_hpacucli_controller_unsafe_writeback_cache, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0001", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0001", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # INSERT my $query = " INSERT INTO scan_hpacucli_controllers ( scan_hpacucli_controller_uuid, scan_hpacucli_controller_host_uuid, scan_hpacucli_controller_serial_number, scan_hpacucli_controller_model, scan_hpacucli_controller_status, scan_hpacucli_controller_last_diagnostics, scan_hpacucli_controller_cache_present, scan_hpacucli_controller_drive_write_cache, scan_hpacucli_controller_firmware_version, scan_hpacucli_controller_unsafe_writeback_cache, modified_date ) VALUES ( ".$anvil->Database->quote($scan_hpacucli_controller_uuid).", ".$anvil->Database->quote($anvil->Get->host_uuid).", ".$anvil->Database->quote($scan_hpacucli_controller_serial_number).", ".$anvil->Database->quote($new_scan_hpacucli_controller_model).", ".$anvil->Database->quote($new_scan_hpacucli_controller_status).", ".$anvil->Database->quote($new_scan_hpacucli_controller_last_diagnostics).", ".$anvil->Database->quote($new_scan_hpacucli_controller_cache_present).", ".$anvil->Database->quote($new_scan_hpacucli_controller_drive_write_cache).", ".$anvil->Database->quote($new_scan_hpacucli_controller_firmware_version).", ".$anvil->Database->quote($new_scan_hpacucli_controller_unsafe_writeback_cache).", ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." );"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } else { ### NOTE: The serial number and model should never change (a changed SN/controller ### should be picked up as a new controller), but we check/update just to be ### safe. # Controller already exists, check for changes. my $old_scan_hpacucli_controller_serial_number = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_serial_number}; my $old_scan_hpacucli_controller_model = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_model}; my $old_scan_hpacucli_controller_status = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_status}; my $old_scan_hpacucli_controller_last_diagnostics = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_last_diagnostics}; my $old_scan_hpacucli_controller_cache_present = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_cache_present}; my $old_scan_hpacucli_controller_drive_write_cache = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_drive_write_cache}; my $old_scan_hpacucli_controller_firmware_version = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_firmware_version}; my $old_scan_hpacucli_controller_unsafe_writeback_cache = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_unsafe_writeback_cache}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number, old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number, old_scan_hpacucli_controller_model => $old_scan_hpacucli_controller_model, old_scan_hpacucli_controller_status => $old_scan_hpacucli_controller_status, old_scan_hpacucli_controller_last_diagnostics => $old_scan_hpacucli_controller_last_diagnostics, old_scan_hpacucli_controller_cache_present => $old_scan_hpacucli_controller_cache_present, old_scan_hpacucli_controller_drive_write_cache => $old_scan_hpacucli_controller_drive_write_cache, old_scan_hpacucli_controller_firmware_version => $old_scan_hpacucli_controller_firmware_version, old_scan_hpacucli_controller_unsafe_writeback_cache => $old_scan_hpacucli_controller_unsafe_writeback_cache, }}); # Delete this from the old cache. delete $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}; # NOTE: We don't check if the last diagnostics changed because it will change every # 10 minutes or so. if (($scan_hpacucli_controller_serial_number ne $old_scan_hpacucli_controller_serial_number) or ($new_scan_hpacucli_controller_model ne $old_scan_hpacucli_controller_model) or ($new_scan_hpacucli_controller_status ne $old_scan_hpacucli_controller_status) or ($new_scan_hpacucli_controller_cache_present ne $old_scan_hpacucli_controller_cache_present) or ($new_scan_hpacucli_controller_drive_write_cache ne $old_scan_hpacucli_controller_drive_write_cache) or ($new_scan_hpacucli_controller_firmware_version ne $old_scan_hpacucli_controller_firmware_version) or ($new_scan_hpacucli_controller_unsafe_writeback_cache ne $old_scan_hpacucli_controller_unsafe_writeback_cache)) { # Send a warning level alert because the most likely change is 'status'. If, # however, the status is now 'ok', then we'll clear the alert. my $cleared = 0; my $message_key = "scan_hpacucli_warning_0002"; if ($new_scan_hpacucli_controller_status ne $old_scan_hpacucli_controller_status) { if (($new_scan_hpacucli_controller_status ne $old_scan_hpacucli_controller_status) && ($old_scan_hpacucli_controller_status eq "VANISHED")) { # Controller has returned. $message_key = "scan_hpacucli_warning_0003"; } if (($new_scan_hpacucli_controller_status ne $old_scan_hpacucli_controller_status) && ($new_scan_hpacucli_controller_status =~ /ok/i)) { # Clear the alert, the controller is OK again. $cleared = 1; } } my $variables = { new_serial_number => $scan_hpacucli_controller_serial_number, old_serial_number => $old_scan_hpacucli_controller_serial_number, new_model_name => $new_scan_hpacucli_controller_model, old_model_name => $old_scan_hpacucli_controller_model, new_status => $new_scan_hpacucli_controller_status, old_status => $old_scan_hpacucli_controller_status, new_cache_present => $new_scan_hpacucli_controller_cache_present, old_cache_present => $old_scan_hpacucli_controller_cache_present, new_drive_write_cache => $new_scan_hpacucli_controller_drive_write_cache, old_drive_write_cache => $old_scan_hpacucli_controller_drive_write_cache, new_firmware_version => $new_scan_hpacucli_controller_firmware_version, old_firmware_version => $old_scan_hpacucli_controller_firmware_version, new_unsafe_writeback_cache => $new_scan_hpacucli_controller_unsafe_writeback_cache, old_unsafe_writeback_cache => $old_scan_hpacucli_controller_unsafe_writeback_cache, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => "warning", message => $message_key, variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); my $query = " UPDATE scan_hpacucli_controllers SET scan_hpacucli_controller_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).", scan_hpacucli_controller_serial_number = ".$anvil->Database->quote($scan_hpacucli_controller_serial_number).", scan_hpacucli_controller_model = ".$anvil->Database->quote($new_scan_hpacucli_controller_model).", scan_hpacucli_controller_status = ".$anvil->Database->quote($new_scan_hpacucli_controller_status).", scan_hpacucli_controller_cache_present = ".$anvil->Database->quote($new_scan_hpacucli_controller_cache_present).", scan_hpacucli_controller_drive_write_cache = ".$anvil->Database->quote($new_scan_hpacucli_controller_drive_write_cache).", scan_hpacucli_controller_firmware_version = ".$anvil->Database->quote($new_scan_hpacucli_controller_firmware_version).", scan_hpacucli_controller_unsafe_writeback_cache = ".$anvil->Database->quote($new_scan_hpacucli_controller_unsafe_writeback_cache).", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_controller_uuid = ".$anvil->Database->quote($scan_hpacucli_controller_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } # Now, if we had a cache module on this controller, see if we knew about it already. my $scan_hpacucli_cache_module_uuid = ""; my $cache_is_new = 0; if ($new_scan_hpacucli_cache_module_serial_number) { if ($anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$new_scan_hpacucli_cache_module_serial_number}) { # Yup! $scan_hpacucli_cache_module_uuid = $anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$new_scan_hpacucli_cache_module_serial_number}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_cache_module_uuid => $scan_hpacucli_cache_module_uuid }}); } else { # No, this is a new cache module. Create a new UUID for it. $scan_hpacucli_cache_module_uuid = $anvil->Get->uuid(); $cache_is_new = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_cache_module_uuid => $scan_hpacucli_cache_module_uuid, cache_is_new => $cache_is_new, }}); # Add the keys for looking it up by UUID or serial number. $anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$new_scan_hpacucli_cache_module_serial_number} = $scan_hpacucli_cache_module_uuid; $anvil->data->{'scan-hpacucli'}{cache_modules}{by_uuid}{$scan_hpacucli_cache_module_uuid} = $new_scan_hpacucli_cache_module_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::cache_modules::by_serial::$new_scan_hpacucli_cache_module_serial_number" => $anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$new_scan_hpacucli_cache_module_serial_number}, "scan-hpacucli::cache_modules::by_uuid::$scan_hpacucli_cache_module_uuid" => $anvil->data->{'scan-hpacucli'}{cache_modules}{by_uuid}{$scan_hpacucli_cache_module_uuid}, }}); } if ($cache_is_new) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_cache_module_uuid => $scan_hpacucli_cache_module_uuid, new_scan_hpacucli_cache_module_size => $new_scan_hpacucli_cache_module_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_cache_module_size}).")", new_scan_hpacucli_cache_module_serial_number => $new_scan_hpacucli_cache_module_serial_number, new_scan_hpacucli_cache_module_status => $new_scan_hpacucli_cache_module_status, new_scan_hpacucli_cache_module_type => $new_scan_hpacucli_cache_module_type, }}); # Send an alert telling the user that we've found a new controller. my $variables = { serial_number => $new_scan_hpacucli_cache_module_serial_number, cache_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_cache_module_size}), status => $new_scan_hpacucli_cache_module_status, type => $new_scan_hpacucli_cache_module_type, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0002", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0002", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); ### NOTE: The rest of the alerts will be in the format '- Variable: [$value]'. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_note_0003"}); $anvil->Alert->register({ clear_alert => 0, alert_level => "notice", message => "scan_hpacucli_note_0003", variables => {}, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # INSERT my $query = " INSERT INTO scan_hpacucli_cache_modules ( scan_hpacucli_cache_module_uuid, scan_hpacucli_cache_module_host_uuid, scan_hpacucli_cache_module_controller_uuid, scan_hpacucli_cache_module_serial_number, scan_hpacucli_cache_module_status, scan_hpacucli_cache_module_type, scan_hpacucli_cache_module_size, modified_date ) VALUES ( ".$anvil->Database->quote($scan_hpacucli_cache_module_uuid).", ".$anvil->Database->quote($anvil->Get->host_uuid).", ".$anvil->Database->quote($scan_hpacucli_controller_uuid).", ".$anvil->Database->quote($new_scan_hpacucli_cache_module_serial_number).", ".$anvil->Database->quote($new_scan_hpacucli_cache_module_status).", ".$anvil->Database->quote($new_scan_hpacucli_cache_module_type).", ".$anvil->Database->quote($new_scan_hpacucli_cache_module_size).", ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." );"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } else { # Exists already, look for changes. The serial number should never change, # buuuut... my $old_scan_hpacucli_cache_module_controller_uuid = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_controller_uuid}; my $old_scan_hpacucli_cache_module_serial_number = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_serial_number}; my $old_scan_hpacucli_cache_module_status = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_status}; my $old_scan_hpacucli_cache_module_type = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_type}; my $old_scan_hpacucli_cache_module_size = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_size}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_scan_hpacucli_cache_module_controller_uuid => $old_scan_hpacucli_cache_module_controller_uuid, old_scan_hpacucli_cache_module_serial_number => $old_scan_hpacucli_cache_module_serial_number, old_scan_hpacucli_cache_module_status => $old_scan_hpacucli_cache_module_status, old_scan_hpacucli_cache_module_type => $old_scan_hpacucli_cache_module_type, old_scan_hpacucli_cache_module_size => $old_scan_hpacucli_cache_module_size, }}); # Delete this so we know we saw it. delete $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}; if (($scan_hpacucli_controller_uuid ne $old_scan_hpacucli_cache_module_controller_uuid) or ($new_scan_hpacucli_cache_module_serial_number ne $old_scan_hpacucli_cache_module_serial_number) or ($new_scan_hpacucli_cache_module_status ne $old_scan_hpacucli_cache_module_status) or ($new_scan_hpacucli_cache_module_type ne $old_scan_hpacucli_cache_module_type) or ($new_scan_hpacucli_cache_module_size ne $old_scan_hpacucli_cache_module_size)) { # Something has changed, but what? Any change is likely bad, so we # default to 'warning'. my $cleared = 0; my $message_key = "scan_hpacucli_warning_0004"; # Did the status return to 'ok'? if (($old_scan_hpacucli_cache_module_status ne $new_scan_hpacucli_cache_module_status) && ($old_scan_hpacucli_cache_module_status eq "VANISHED")) { # The cache module is back $message_key = "scan_hpacucli_warning_0005"; } elsif (($old_scan_hpacucli_cache_module_status ne $new_scan_hpacucli_cache_module_status) && ($new_scan_hpacucli_cache_module_status eq "ok")) { # The status is good now, clear the alert $cleared = 1; } # Convert the old controller UUID to a serial number. my $query = "SELECT scan_hpacucli_controller_serial_number FROM scan_hpacucli_controllers WHERE scan_hpacucli_controller_uuid = ".$anvil->Database->quote($old_scan_hpacucli_cache_module_controller_uuid).";"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); my $old_scan_hpacucli_controller_serial_number = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0]; $old_scan_hpacucli_controller_serial_number = "--" if not defined $old_scan_hpacucli_controller_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number }}); # Send the alert my $variables = { old_serial_number => $old_scan_hpacucli_cache_module_serial_number, new_serial_number => $new_scan_hpacucli_cache_module_serial_number, old_scan_hpacucli_controller_serial_number => $old_scan_hpacucli_controller_serial_number, new_controller_serial_number => $scan_hpacucli_controller_serial_number, old_status => $old_scan_hpacucli_cache_module_status, new_status => $old_scan_hpacucli_cache_module_status, old_type => $new_scan_hpacucli_cache_module_type, new_type => $old_scan_hpacucli_cache_module_type, say_old_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $old_scan_hpacucli_cache_module_size}), say_new_size => $anvil->Convert->bytes_to_human_readable({'bytes' => $new_scan_hpacucli_cache_module_size}), }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0002", variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => "warning", message => $message_key, variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); ### NOTE: The rest of the alerts will be in the format '- Variable: [$value]'. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0003"}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0003", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # Update the database. $query = " UPDATE scan_hpacucli_cache_modules SET scan_hpacucli_cache_module_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).", scan_hpacucli_cache_module_controller_uuid = ".$anvil->Database->quote($scan_hpacucli_controller_uuid).", scan_hpacucli_cache_module_serial_number = ".$anvil->Database->quote($new_scan_hpacucli_cache_module_serial_number).", scan_hpacucli_cache_module_status = ".$anvil->Database->quote($new_scan_hpacucli_cache_module_status).", scan_hpacucli_cache_module_type = ".$anvil->Database->quote($new_scan_hpacucli_cache_module_type).", scan_hpacucli_cache_module_size = ".$anvil->Database->quote($new_scan_hpacucli_cache_module_size).", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_cache_module_uuid = ".$anvil->Database->quote($scan_hpacucli_cache_module_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } } # We do this after the cache so that the alerts make since when a new controller is found. foreach my $type ("detail", "temperature") { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }}); foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}}) { my $new_scan_hpacucli_variable_value = delete $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}; my $temperature = $type eq "temperature" ? "TRUE" : "FALSE"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable => $variable, new_scan_hpacucli_variable_value => $new_scan_hpacucli_variable_value, temperature => $temperature, }}); # Now, if the variable doesn't exist, INSERT it. If it does exist, see if it # changed and UPDATE it if so. if (exists $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$variable}) { # Look for changes my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$variable}{scan_hpacucli_variable_value}; my $variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$variable}{scan_hpacucli_variable_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_scan_hpacucli_variable_value => $new_scan_hpacucli_variable_value, old_scan_hpacucli_variable_value => $old_scan_hpacucli_variable_value, variable_uuid => $variable_uuid, }}); # Delete it so that we know it has been processed. delete $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$variable}; # Set defaults my $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{high_critical}; my $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{high_warning}; my $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{low_warning}; my $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{low_critical}; my $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{jump}; my $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{buffer}; my $clear_high_critical = $high_critical - $buffer; my $clear_high_warning = $high_warning - $buffer; my $clear_low_critical = $low_critical - $buffer; my $clear_low_warning = $low_warning - $buffer; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { high_critical => $high_critical, high_warning => $high_warning, low_warning => $low_warning, low_critical => $low_critical, jump => $jump, buffer => $buffer, clear_high_critical => $clear_high_critical, clear_high_warning => $clear_high_warning, clear_low_critical => $clear_low_critical, clear_low_warning => $clear_low_warning, }}); # Fine-tune the alert thresholds if ($clear_high_critical < $high_warning) { $clear_high_critical = $high_warning + 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }}); } if ($clear_low_critical > $low_warning) { $clear_low_critical = $low_warning - 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }}); } # Does this variable have defined limits? if (exists $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_critical}) { $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_critical}; $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_warning}; $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{low_warning}; $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{low_critical}; $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{jump}; $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{buffer}; $clear_high_critical = $high_critical - $buffer; $clear_high_warning = $high_warning - $buffer; $clear_low_critical = $low_critical - $buffer; $clear_low_warning = $low_warning - $buffer; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { high_critical => $high_critical, high_warning => $high_warning, low_warning => $low_warning, low_critical => $low_critical, jump => $jump, buffer => $buffer, clear_high_critical => $clear_high_critical, clear_high_warning => $clear_high_warning, clear_low_critical => $clear_low_critical, clear_low_warning => $clear_low_warning, }}); # Fine-tune the alert thresholds if ($clear_high_critical < $high_warning) { $clear_high_critical = $high_warning + 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }}); } if ($clear_low_critical > $low_warning) { $clear_low_critical = $low_warning - 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }}); } } # If it's a temperature, we need to analyze it and store it, # regardless of if it changed this pass. my $cleared = 0; my $temperature_state = "ok"; my $temperature_is = "nominal"; my $message_key = "scan_hpacucli_note_0009"; my $alert_level = "notice"; my $delta = 0; if ($type eq "temperature") { # Change the log level to info as temperatures change often. $alert_level = "info"; # Now see if the temperature has crossed into a # warning or critical state. if ($new_scan_hpacucli_variable_value > $high_critical) { # Crossed the high critical threshold. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "critical"; $message_key = "scan_hpacucli_note_0005"; } $temperature_state = "critical"; $temperature_is = "high"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_variable_value > $high_warning) { # Crossed the high warning threshold. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "warning"; $message_key = "scan_hpacucli_note_0006"; } $temperature_state = "warning"; $temperature_is = "high"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_variable_value < $low_critical) { # Dropped below the low critical threshold. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "critical"; $message_key = "scan_hpacucli_note_0007"; } $temperature_state = "critical"; $temperature_is = "low"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_variable_value < $low_warning) { # Crossed the low warning threshold. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "warning"; $message_key = "scan_hpacucli_note_0008"; } $temperature_state = "warning"; $temperature_is = "low"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } else { # Did it change enough to trigger a jump # alert? if ($new_scan_hpacucli_variable_value > $old_scan_hpacucli_variable_value) { # Jumped $delta = $new_scan_hpacucli_variable_value - $old_scan_hpacucli_variable_value; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { delta => $delta }}); if ($delta >= $jump) { # Big jump. $alert_level = "warning"; $message_key = "scan_hpacucli_note_0015"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { alert_level => $alert_level, message_key => $message_key, }}); } } else { # Dropped $delta = $old_scan_hpacucli_variable_value - $new_scan_hpacucli_variable_value; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { delta => $delta }}); if ($delta >= $jump) { # Big drop. $alert_level = "warning"; $message_key = "scan_hpacucli_note_0016"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { alert_level => $alert_level, message_key => $message_key, }}); } } } # Record this for later processing into the 'temperature' # table. my $sensor_host_key = "controller:$scan_hpacucli_controller_serial_number"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sensor_host_key => $sensor_host_key }}); $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_value_c} = $new_scan_hpacucli_variable_value; $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_state} = $temperature_state; $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_is} = $temperature_is; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "new::temperature::${variable}::${sensor_host_key}::temperature_value_c" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_value_c}, "new::temperature::${variable}::${sensor_host_key}::temperature_state" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_state}, "new::temperature::${variable}::${sensor_host_key}::temperature_is" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_is}, }}); } # Did the variable change? if ($new_scan_hpacucli_variable_value ne $old_scan_hpacucli_variable_value) { # How has it changed? if ($old_scan_hpacucli_variable_value eq "VANISHED") { $message_key = "scan_hpacucli_note_0010"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { message_key => $message_key }}); } elsif ($type eq "temperature") { # Clear alerts, if needed. The order is important as # clearing a warning will replace clearing a critical # when a sensor goes critical -> ok in one scan. Once # done, we'll check if we've crossed into a warning # or critical state. If so, those will replace any # cleared messages. if ($new_scan_hpacucli_variable_value < $clear_high_critical) { my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $cleared = 1; $alert_level = "critical"; $message_key = "scan_hpacucli_note_0011"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cleared => $cleared, alert_level => $alert_level, message_key => $message_key, }}); } } if ($new_scan_hpacucli_variable_value < $clear_high_warning) { my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { # The temperature is no longer # warning, and it didn't just go # critical $cleared = 1; $alert_level = "warning"; $message_key = "scan_hpacucli_note_0012"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cleared => $cleared, alert_level => $alert_level, message_key => $message_key, }}); } } if ($new_scan_hpacucli_variable_value > $clear_low_critical) { my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $cleared = 1; $alert_level = "critical"; $message_key = "scan_hpacucli_note_0013"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cleared => $cleared, alert_level => $alert_level, message_key => $message_key, }}); } } if ($new_scan_hpacucli_variable_value > $clear_low_warning) { my $changed = $anvil->Alert->check_alert_sent({clear => 1, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $cleared = 1; $alert_level = "warning"; $message_key = "scan_hpacucli_note_0014"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cleared => $cleared, alert_level => $alert_level, message_key => $message_key, }}); } } } # Send an alert telling the user that we've found a variable for this # controller. Note that we add ' C' to the temperatures so that they get # translated to '°F' if desired by the reader. my $variables = { sensor_name => $variable, serial_number => $scan_hpacucli_controller_serial_number, name => $variable, old_value => $type eq "temperature" ? $old_scan_hpacucli_variable_value." °C" : $old_scan_hpacucli_variable_value, new_value => $type eq "temperature" ? $new_scan_hpacucli_variable_value." °C" : $new_scan_hpacucli_variable_value, high_critical_temperature => $high_critical." °C", high_warning_temperature => $high_warning." °C", low_critical_temperature => $low_critical." °C", low_warning_temperature => $low_warning." °C", delta => $delta, }; my $log_level = (($alert_level eq "warning") or ($alert_level eq "critical")) ? 1 : 2; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => $cleared, alert_level => $alert_level, message => $message_key, variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # UPDATE my $query = " UPDATE scan_hpacucli_variables SET scan_hpacucli_variable_value = ".$anvil->Database->quote($new_scan_hpacucli_variable_value).", modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_variable_uuid = ".$anvil->Database->quote($variable_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } else { # New, record. my $message_key = "scan_hpacucli_note_0004"; my $alert_level = "notice"; # Set defaults my $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{high_critical}; my $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{high_warning}; my $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{low_warning}; my $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{low_critical}; my $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{jump}; my $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{'default'}{buffer}; my $clear_high_critical = $high_critical - $buffer; my $clear_high_warning = $high_warning - $buffer; my $clear_low_critical = $low_critical - $buffer; my $clear_low_warning = $low_warning - $buffer; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "high_critical" => $high_critical, "high_warning" => $high_warning, "low_warning" => $low_warning, "low_critical" => $low_critical, "jump" => $jump, "buffer" => $buffer, "clear_high_critical" => $clear_high_critical, "clear_high_warning" => $clear_high_warning, "clear_low_critical" => $clear_low_critical, "clear_low_warning" => $clear_low_warning, }}); # Fine-tune the alert thresholds if ($clear_high_critical < $high_warning) { $clear_high_critical = $high_warning + 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }}); } if ($clear_low_critical > $low_warning) { $clear_low_critical = $low_warning - 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }}); } if ($type eq "temperature") { # Does this variable have defined limits? if (exists $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_critical}) { $high_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_critical}; $high_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{high_warning}; $low_warning = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{low_warning}; $low_critical = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{low_critical}; $jump = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{jump}; $buffer = $anvil->data->{'scan-hpacucli'}{thresholds}{$variable}{buffer}; $clear_high_critical = $high_critical - $buffer; $clear_high_warning = $high_warning - $buffer; $clear_low_critical = $low_critical - $buffer; $clear_low_warning = $low_warning - $buffer; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { high_critical => $high_critical, high_warning => $high_warning, low_warning => $low_warning, low_critical => $low_critical, jump => $jump, buffer => $buffer, clear_high_critical => $clear_high_critical, clear_high_warning => $clear_high_warning, clear_low_critical => $clear_low_critical, clear_low_warning => $clear_low_warning, }}); # Fine-tune the alert thresholds if ($clear_high_critical < $high_warning) { $clear_high_critical = $high_warning + 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_high_critical => $clear_high_critical }}); } if ($clear_low_critical > $low_warning) { $clear_low_critical = $low_warning - 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { clear_low_critical => $clear_low_critical }}); } } # This is a temperature, so see if the temperature outside of # the warning or critical thresholds. This is a new sensor, # so nothing to compare against. my $temperature_state = "ok"; my $temperature_is = "nominal"; if ($new_scan_hpacucli_variable_value > $high_critical) { # Crossed the high critical threshold. This should # always be unset because it is a new variable, but # check anyway. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "critical"; $message_key = "scan_hpacucli_note_0005"; } $temperature_state = "critical"; $temperature_is = "high"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_variable_value > $high_warning) { # Crossed the high warning threshold. This should # always be unset because it is a new variable, but # check anyway. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_high_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "warning"; $message_key = "scan_hpacucli_note_0006"; } $temperature_state = "warning"; $temperature_is = "high"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } elsif ($new_scan_hpacucli_variable_value < $low_critical) { # Dropped below the low critical threshold. This # should always be unset because it is a new # variable, but check anyway. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_critical", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "critical"; $message_key = "scan_hpacucli_note_0007"; } $temperature_state = "critical"; $temperature_is = "low"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "temperature_state" => $temperature_state, "temperature_is" => $temperature_is, }}); } elsif ($new_scan_hpacucli_variable_value < $low_warning) { # Crossed the low warning threshold. This should # always be unset because it is a new variable, but # check anyway. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_controller_serial_number.":".$variable."_low_warning", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { $alert_level = "warning"; $message_key = "scan_hpacucli_note_0008"; } $temperature_state = "warning"; $temperature_is = "low"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { temperature_state => $temperature_state, temperature_is => $temperature_is, }}); } # Record this for later processing into the 'temperature' # table. my $sensor_host_key = "controller:".$scan_hpacucli_controller_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sensor_host_key => $sensor_host_key }}); $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_value_c} = $new_scan_hpacucli_variable_value; $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_state} = $temperature_state; $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_is} = $temperature_is; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "new::temperature::${variable}::${sensor_host_key}::temperature_value_c" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_value_c}, "new::temperature::${variable}::${sensor_host_key}::temperature_state" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_state}, "new::temperature::${variable}::${sensor_host_key}::temperature_is" => $anvil->data->{new}{temperature}{$variable}{$sensor_host_key}{temperature_is}, }}); } # Send an alert telling the user that we've found a variable for this # controller. my $variables = { sensor_name => $variable, serial_number => $scan_hpacucli_controller_serial_number, name => $variable, value => $type eq "temperature" ? $new_scan_hpacucli_variable_value." °C" : $new_scan_hpacucli_variable_value, high_critical_temperature => $high_critical." °C", high_warning_temperature => $high_warning." °C", low_critical_temperature => $low_critical." °C", low_warning_temperature => $low_warning." °C", }; my $log_level = (($alert_level eq "warning") or ($alert_level eq "critical")) ? 1 : 2; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $log_level, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => $alert_level, message => $message_key, variables => $variables, show_header => 0, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); # INSERT my $query = " INSERT INTO scan_hpacucli_variables ( scan_hpacucli_variable_uuid, scan_hpacucli_variable_host_uuid, scan_hpacucli_variable_source_table, scan_hpacucli_variable_source_uuid, scan_hpacucli_variable_is_temperature, scan_hpacucli_variable_name, scan_hpacucli_variable_value, modified_date ) VALUES ( ".$anvil->Database->quote($anvil->Get->uuid()).", ".$anvil->Database->quote($anvil->Get->host_uuid).", 'scan_hpacucli_controllers', ".$anvil->Database->quote($scan_hpacucli_controller_uuid).", ".$anvil->Database->quote($temperature).", ".$anvil->Database->quote($variable).", ".$anvil->Database->quote($new_scan_hpacucli_variable_value).", ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." );"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } } } # Look for removed controllers foreach my $scan_hpacucli_controller_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}}) { # Controller vanished! my $old_scan_hpacucli_controller_serial_number = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_serial_number}; my $old_scan_hpacucli_controller_model = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_model}; my $old_scan_hpacucli_controller_status = $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_status}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan_hpacucli_controller_uuid" => $scan_hpacucli_controller_uuid, "old_scan_hpacucli_controller_serial_number" => $old_scan_hpacucli_controller_serial_number, "old_scan_hpacucli_controller_model" => $old_scan_hpacucli_controller_model, "old_scan_hpacucli_controller_status" => $old_scan_hpacucli_controller_status, }}); # Delete it so that we know it has been processed. delete $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}; # If the old alarm state is already 'VANISHED', ignore it. next if $old_scan_hpacucli_controller_status eq "VANISHED"; # Still here? Alert and UPDATE. ### NOTE: For now, we're going to use warning level because controllers should never vanish ### unless one failed. If that is the case, the admin already knows, but this will let ### other notification targets know that the change has happened. my $variables = { model => $old_scan_hpacucli_controller_model, serial_number => $old_scan_hpacucli_controller_serial_number, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0017", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0017", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); my $query = " UPDATE scan_hpacucli_controllers SET scan_hpacucli_controller_status = 'VANISHED', modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_controller_uuid = ".$anvil->Database->quote($scan_hpacucli_controller_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } # Look for removed cache modules foreach my $scan_hpacucli_cache_module_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}}) { # Controller vanished! my $old_scan_hpacucli_cache_module_serial_number = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_serial_number}; my $old_scan_hpacucli_cache_module_status = $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_status}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan_hpacucli_cache_module_uuid" => $scan_hpacucli_cache_module_uuid, "old_scan_hpacucli_cache_module_serial_number" => $old_scan_hpacucli_cache_module_serial_number, "old_scan_hpacucli_cache_module_status" => $old_scan_hpacucli_cache_module_status, }}); # Delete it so that we know it has been processed. delete $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}; # If the old alarm state is already 'VANISHED', ignore it. next if $old_scan_hpacucli_cache_module_status eq "VANISHED"; # Still here? Alert and UPDATE. ### NOTE: For now, we're going to use warning level because cache_modules should never vanish ### unless one failed. If that is the case, the admin already knows, but this will let ### other notification targets know that the change has happened. my $variables = { serial_number => $old_scan_hpacucli_cache_module_serial_number, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_note_0018", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_note_0018", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); my $query = " UPDATE scan_hpacucli_cache_modules SET scan_hpacucli_cache_module_status = 'VANISHED', modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_cache_module_uuid = ".$anvil->Database->quote($scan_hpacucli_cache_module_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } # Look for removed controller variables. foreach my $scan_hpacucli_controller_uuid (keys %{$anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}}) { # Get the serial numbre for this contrller my $scan_hpacucli_controller_serial_number = $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan_hpacucli_controller_uuid" => $scan_hpacucli_controller_uuid, "scan_hpacucli_controller_serial_number" => $scan_hpacucli_controller_serial_number, }}); foreach my $type ("detail", "temperature") { foreach my $scan_hpacucli_variable_name (sort {$a cmp $b} keys %{$anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}}) { my $old_scan_hpacucli_variable_value = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value}; my $old_scan_hpacucli_variable_uuid = $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{scan_hpacucli_controllers}{source_uuid}{$scan_hpacucli_controller_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "type" => $type, "scan_hpacucli_variable_name" => $scan_hpacucli_variable_name, "old_scan_hpacucli_variable_value" => $old_scan_hpacucli_variable_value, "old_scan_hpacucli_variable_uuid" => $old_scan_hpacucli_variable_uuid, }}); # If the old alarm state is already 'VANISHED', ignore it. next if $old_scan_hpacucli_variable_value eq "VANISHED"; # Still here? Alert and UPDATE. ### NOTE: For now, we're going to use warning level because cache_modules ### should never vanish unless one failed. If that is the case, the ### admin already knows, but this will let other notification targets ### know that the change has happened. my $message_key = $type eq "temperature" ? "scan_hpacucli_note_0019" : "scan_hpacucli_note_0020"; my $variables = { serial_number => $scan_hpacucli_controller_serial_number, name => $scan_hpacucli_variable_name, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => $message_key, variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => $message_key, variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-ipmitool'}{alert_sort}++, set_by => $THIS_FILE, }); my $query = " UPDATE scan_hpacucli_variables SET scan_hpacucli_variable_value = 'VANISHED', modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." WHERE scan_hpacucli_variable_uuid = ".$anvil->Database->quote($old_scan_hpacucli_variable_uuid)." ;"; # Now record the query in the array $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); push @{$anvil->data->{'scan-hpacucli'}{queries}}, $query; } } } # Now commit the changes. $anvil->Database->write({query => $anvil->data->{'scan-hpacucli'}{queries}, source => $THIS_FILE, line => __LINE__}); $anvil->data->{'scan-hpacucli'}{queries} = []; return(0); } # This reads in the last scan's data. sub read_last_scan { my ($anvil) = @_; # Read in the controller(s) my $query = " SELECT scan_hpacucli_controller_uuid, scan_hpacucli_controller_serial_number, scan_hpacucli_controller_model, scan_hpacucli_controller_status, scan_hpacucli_controller_last_diagnostics, scan_hpacucli_controller_cache_present, scan_hpacucli_controller_drive_write_cache, scan_hpacucli_controller_firmware_version, scan_hpacucli_controller_unsafe_writeback_cache FROM scan_hpacucli_controllers WHERE scan_hpacucli_controller_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 $scan_hpacucli_controller_uuid = $row->[0]; my $scan_hpacucli_controller_serial_number = $row->[1]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_uuid => $scan_hpacucli_controller_uuid, scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number, }}); $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_serial_number} = $scan_hpacucli_controller_serial_number; $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_model} = $row->[2]; $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_status} = $row->[3]; $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_last_diagnostics} = $row->[4]; $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_cache_present} = $row->[5]; $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_drive_write_cache} = $row->[6]; $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_firmware_version} = $row->[7]; $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_unsafe_writeback_cache} = $row->[8]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_serial_number" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_serial_number}, "sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_model" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_model}, "sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_status" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_status}, "sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_last_diagnostics" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_last_diagnostics}, "sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_cache_present" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_cache_present}, "sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_drive_write_cache" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_drive_write_cache}, "sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_firmware_version" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_firmware_version}, "sql::scan_hpacucli_controllers::scan_hpacucli_controller_uuid::${scan_hpacucli_controller_uuid}::scan_hpacucli_controller_unsafe_writeback_cache" => $anvil->data->{sql}{scan_hpacucli_controllers}{scan_hpacucli_controller_uuid}{$scan_hpacucli_controller_uuid}{scan_hpacucli_controller_unsafe_writeback_cache}, }}); # Store the information about this controllers $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number} = $scan_hpacucli_controller_uuid; $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid} = $scan_hpacucli_controller_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::controllers::by_serial::${scan_hpacucli_controller_serial_number}" => $anvil->data->{'scan-hpacucli'}{controllers}{by_serial}{$scan_hpacucli_controller_serial_number}, "scan-hpacucli::controllers::by_uuid::${scan_hpacucli_controller_uuid}" => $anvil->data->{'scan-hpacucli'}{controllers}{by_uuid}{$scan_hpacucli_controller_uuid}, }}); } undef $results; undef $count; # Now load the cache data $query = " SELECT scan_hpacucli_cache_module_uuid, scan_hpacucli_cache_module_serial_number, scan_hpacucli_cache_module_controller_uuid, scan_hpacucli_cache_module_status, scan_hpacucli_cache_module_type, scan_hpacucli_cache_module_size FROM scan_hpacucli_cache_modules WHERE scan_hpacucli_cache_module_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 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 $scan_hpacucli_cache_module_uuid = $row->[0]; my $scan_hpacucli_cache_module_serial_number = $row->[1]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_cache_module_uuid => $scan_hpacucli_cache_module_uuid, scan_hpacucli_cache_module_serial_number => $scan_hpacucli_cache_module_serial_number, }}); # Store the information about this cache_module $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_controller_uuid} = $row->[2]; $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_serial_number} = $scan_hpacucli_cache_module_serial_number; $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_status} = $row->[3]; $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_type} = $row->[4]; $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_size} = $row->[5]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_controller_uuid" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_controller_uuid}, "sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_serial_number" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_serial_number}, "sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_status" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_status}, "sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_type" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_type}, "sql::scan_hpacucli_cache_modules::scan_hpacucli_cache_module_uuid::${scan_hpacucli_cache_module_uuid}::scan_hpacucli_cache_module_size" => $anvil->data->{sql}{scan_hpacucli_cache_modules}{scan_hpacucli_cache_module_uuid}{$scan_hpacucli_cache_module_uuid}{scan_hpacucli_cache_module_size}, }}); $anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$scan_hpacucli_cache_module_serial_number} = $scan_hpacucli_cache_module_uuid; $anvil->data->{'scan-hpacucli'}{cache_modules}{by_uuid}{$scan_hpacucli_cache_module_uuid} = $scan_hpacucli_cache_module_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::cache_modules::by_serial::${scan_hpacucli_cache_module_serial_number}" => $anvil->data->{'scan-hpacucli'}{cache_modules}{by_serial}{$scan_hpacucli_cache_module_serial_number}, "scan-hpacucli::cache_modules::by_uuid::${scan_hpacucli_cache_module_uuid}" => $anvil->data->{'scan-hpacucli'}{cache_modules}{by_uuid}{$scan_hpacucli_cache_module_uuid}, }}); } undef $results; undef $count; # The array data... $query = " SELECT scan_hpacucli_array_uuid, scan_hpacucli_array_name, scan_hpacucli_array_controller_uuid, scan_hpacucli_array_type, scan_hpacucli_array_status, scan_hpacucli_array_error_message FROM scan_hpacucli_arrays WHERE scan_hpacucli_array_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 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 $scan_hpacucli_array_uuid = $row->[0]; my $scan_hpacucli_array_name = $row->[1]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_array_uuid => $scan_hpacucli_array_uuid, scan_hpacucli_array_name => $scan_hpacucli_array_name, }}); # Store the drive group data. (Drive groups have no SN) $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_controller_uuid} = $row->[2]; $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_name} = $scan_hpacucli_array_name; $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_type} = $row->[3]; $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_status} = $row->[4]; $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_error_message} = $row->[5]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_controller_uuid" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_controller_uuid}, "sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_name" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_name}, "sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_type" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_type}, "sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_status" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_status}, "sql::scan_hpacucli_arrays::scan_hpacucli_array_uuid::${scan_hpacucli_array_uuid}::scan_hpacucli_array_error_message" => $anvil->data->{sql}{scan_hpacucli_arrays}{scan_hpacucli_array_uuid}{$scan_hpacucli_array_uuid}{scan_hpacucli_array_error_message}, }}); # Store the information about this virtual drive. $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_name}{$scan_hpacucli_array_name} = $scan_hpacucli_array_uuid; $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_uuid}{$scan_hpacucli_array_uuid} = $scan_hpacucli_array_name; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::virtual_drives::by_name::${scan_hpacucli_array_name}" => $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_name}{$scan_hpacucli_array_name}, "scan-hpacucli::virtual_drives::by_uuid::${scan_hpacucli_array_uuid}" => $anvil->data->{'scan-hpacucli'}{virtual_drives}{by_uuid}{$scan_hpacucli_array_uuid}, }}); } undef $results; undef $count; # The drive group data... $query = " SELECT scan_hpacucli_logical_drive_uuid, scan_hpacucli_logical_drive_name, scan_hpacucli_logical_drive_array_uuid, scan_hpacucli_logical_drive_caching, scan_hpacucli_logical_drive_os_device_name, scan_hpacucli_logical_drive_type, scan_hpacucli_logical_drive_raid_level, scan_hpacucli_logical_drive_size, scan_hpacucli_logical_drive_strip_size, scan_hpacucli_logical_drive_stripe_size, scan_hpacucli_logical_drive_status FROM scan_hpacucli_logical_drives WHERE scan_hpacucli_logical_drive_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 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 $scan_hpacucli_logical_drive_uuid = $row->[0]; my $scan_hpacucli_logical_drive_name = $row->[1]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_logical_drive_uuid => $scan_hpacucli_logical_drive_uuid, scan_hpacucli_logical_drive_name => $scan_hpacucli_logical_drive_name, }}); # Store the logical drive data. (LDs have no SN) $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_name} = $scan_hpacucli_logical_drive_name; $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_array_uuid} = $row->[2]; $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_caching} = $row->[3]; $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_os_device_name} = $row->[4]; $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_type} = $row->[5]; $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_raid_level} = $row->[6]; $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_size} = $row->[7]; $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_strip_size} = $row->[8]; $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_stripe_size} = $row->[9]; $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_status} = $row->[10]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_array_uuid" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_array_uuid}, "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_name" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_name}, "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_caching" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_caching}, "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_os_device_name" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_os_device_name}, "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_type" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_type}, "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_raid_level" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_raid_level}, "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_size" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_size}, "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_strip_size" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_strip_size}, "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_stripe_size" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_stripe_size}, "sql::scan_hpacucli_logical_drives::scan_hpacucli_logical_drive_uuid::${scan_hpacucli_logical_drive_uuid}::scan_hpacucli_logical_drive_status" => $anvil->data->{sql}{scan_hpacucli_logical_drives}{scan_hpacucli_logical_drive_uuid}{$scan_hpacucli_logical_drive_uuid}{scan_hpacucli_logical_drive_status}, }}); # Store the information about this virtual drive. $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name} = $scan_hpacucli_logical_drive_uuid; $anvil->data->{'scan-hpacucli'}{logical_drives}{by_uuid}{$scan_hpacucli_logical_drive_uuid} = $scan_hpacucli_logical_drive_name; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::logical_drives::by_name::${scan_hpacucli_logical_drive_name}" => $anvil->data->{'scan-hpacucli'}{logical_drives}{by_name}{$scan_hpacucli_logical_drive_name}, "scan-hpacucli::logical_drives::by_uuid::${scan_hpacucli_logical_drive_uuid}" => $anvil->data->{'scan-hpacucli'}{logical_drives}{by_uuid}{$scan_hpacucli_logical_drive_uuid}, }}); } undef $results; undef $count; # And now, the physical drives. $query = " SELECT scan_hpacucli_physical_drive_uuid, scan_hpacucli_physical_drive_serial_number, scan_hpacucli_physical_drive_logical_drive_uuid, scan_hpacucli_physical_drive_model, scan_hpacucli_physical_drive_interface, scan_hpacucli_physical_drive_status, scan_hpacucli_physical_drive_size, scan_hpacucli_physical_drive_type, scan_hpacucli_physical_drive_rpm, scan_hpacucli_physical_drive_temperature, scan_hpacucli_physical_drive_last_failure_reason, scan_hpacucli_physical_drive_port, scan_hpacucli_physical_drive_box, scan_hpacucli_physical_drive_bay FROM scan_hpacucli_physical_drives WHERE scan_hpacucli_physical_drive_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 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 $scan_hpacucli_physical_drive_uuid = $row->[0]; my $scan_hpacucli_physical_drive_serial_number = $row->[1]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_physical_drive_uuid => $scan_hpacucli_physical_drive_uuid, scan_hpacucli_physical_drive_serial_number => $scan_hpacucli_physical_drive_serial_number, }}); # Store the information about this physical drive $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_logical_drive_uuid} = $row->[2]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_serial_number} = $scan_hpacucli_physical_drive_serial_number; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_model} = $row->[3]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_interface} = $row->[4]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_status} = $row->[5]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_size} = $row->[6]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_type} = $row->[7]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_rpm} = $row->[8]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_temperature} = $row->[9]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_last_failure_reason} = $row->[10]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_port} = $row->[11]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_box} = $row->[12]; $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_bay} = $row->[13]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_logical_drive_uuid" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_logical_drive_uuid}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_serial_number" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_serial_number}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_model" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_model}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_interface" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_interface}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_status" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_status}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_size" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_size}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_type" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_type}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_rpm" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_rpm}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_temperature" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_temperature}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_last_failure_reason" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_last_failure_reason}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_port" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_port}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_box" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_box}, "sql::scan_hpacucli_physical_drives::scan_hpacucli_physical_drive_uuid::${scan_hpacucli_physical_drive_uuid}::scan_hpacucli_physical_drive_bay" => $anvil->data->{sql}{scan_hpacucli_physical_drives}{scan_hpacucli_physical_drive_uuid}{$scan_hpacucli_physical_drive_uuid}{scan_hpacucli_physical_drive_bay}, }}); # Make it so that we can look up the serial number from the drive's UUID and vice versa $anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number} = $scan_hpacucli_physical_drive_uuid; $anvil->data->{'scan-hpacucli'}{physical_drives}{by_uuid}{$scan_hpacucli_physical_drive_uuid} = $scan_hpacucli_physical_drive_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::physical_drives::by_serial::${scan_hpacucli_physical_drive_serial_number}" => $anvil->data->{'scan-hpacucli'}{physical_drives}{by_serial}{$scan_hpacucli_physical_drive_serial_number}, "scan-hpacucli::physical_drives::by_uuid::${scan_hpacucli_physical_drive_uuid}" => $anvil->data->{'scan-hpacucli'}{physical_drives}{by_uuid}{$scan_hpacucli_physical_drive_uuid}, }}); } undef $results; undef $count; # Lastly, the variables. $query = " SELECT scan_hpacucli_variable_uuid, scan_hpacucli_variable_source_table, scan_hpacucli_variable_source_uuid, scan_hpacucli_variable_is_temperature, scan_hpacucli_variable_name, scan_hpacucli_variable_value FROM scan_hpacucli_variables WHERE scan_hpacucli_variable_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 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 $scan_hpacucli_variable_uuid = $row->[0]; my $scan_hpacucli_variable_source_table = $row->[1]; my $scan_hpacucli_variable_source_uuid = $row->[2]; my $scan_hpacucli_variable_is_temperature = $row->[3]; my $scan_hpacucli_variable_name = $row->[4]; my $scan_hpacucli_variable_value = $row->[5]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid, scan_hpacucli_variable_source_table => $scan_hpacucli_variable_source_table, scan_hpacucli_variable_source_uuid => $scan_hpacucli_variable_source_uuid, scan_hpacucli_variable_is_temperature => $scan_hpacucli_variable_is_temperature, scan_hpacucli_variable_name => $scan_hpacucli_variable_name, scan_hpacucli_variable_value => $scan_hpacucli_variable_value, }}); # We store these differently for easier reference. Diagnostic data is stored in the special # 'scan_hpacucli_physical_drive_diagnostics' source. my $type = "detail"; if ($scan_hpacucli_variable_source_table eq "scan_hpacucli_physical_drive_diagnostics") { $type = "diagnostics"; } if ($scan_hpacucli_variable_is_temperature eq "1") { $type = "temperature"; } $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{$scan_hpacucli_variable_source_table}{source_uuid}{$scan_hpacucli_variable_source_uuid}{$type}{$scan_hpacucli_variable_name} = { scan_hpacucli_variable_uuid => $scan_hpacucli_variable_uuid, scan_hpacucli_variable_is_temperature => $scan_hpacucli_variable_is_temperature, scan_hpacucli_variable_value => $scan_hpacucli_variable_value, }; # Entries are so long that we log the one per variable. $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::${scan_hpacucli_variable_source_table}::source_uuid::${scan_hpacucli_variable_source_uuid}::${type}::${scan_hpacucli_variable_name}::scan_hpacucli_variable_uuid" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{$scan_hpacucli_variable_source_table}{source_uuid}{$scan_hpacucli_variable_source_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_uuid}, }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::${scan_hpacucli_variable_source_table}::source_uuid::${scan_hpacucli_variable_source_uuid}::${type}::${scan_hpacucli_variable_name}::scan_hpacucli_variable_is_temperature" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{$scan_hpacucli_variable_source_table}{source_uuid}{$scan_hpacucli_variable_source_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_is_temperature}, }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sql::scan_hpacucli_variables::scan_hpacucli_variable_uuid::source_table::${scan_hpacucli_variable_source_table}::source_uuid::${scan_hpacucli_variable_source_uuid}::${type}::${scan_hpacucli_variable_name}::scan_hpacucli_variable_value" => $anvil->data->{sql}{scan_hpacucli_variables}{scan_hpacucli_variable_uuid}{source_table}{$scan_hpacucli_variable_source_table}{source_uuid}{$scan_hpacucli_variable_source_uuid}{$type}{$scan_hpacucli_variable_name}{scan_hpacucli_variable_value}, }}); } undef $results; undef $count; # Return the number return(0); } # This looks for anything other than temperature sensors that will feed into the health of the node. sub pre_process_health { my ($anvil) = @_; # This is to collected data from every sweep. foreach my $scan_hpacucli_controller_serial_number (sort {$a cmp $b} keys %{$anvil->data->{controller}}) { # We don't care about metadata next if $scan_hpacucli_controller_serial_number eq "metadata"; # Controller data foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}}) { if (($variable eq "battery_or_capacitor_status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{$variable}) ne "ok")) { # BBU/FBU problem, score of 2 my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":data:".$variable; $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); } elsif (($variable eq "cache_status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{$variable}) ne "ok")) { # Cache isn't OK, score of 2 my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":data:".$variable; $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); } elsif (($variable eq "controller_status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{$variable}) ne "ok")) { # The controller isn't OK, this is major, score of 10 my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":data:".$variable; $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 10; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); } } # Array foreach my $scan_hpacucli_array_name (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}}) { # Data foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}}) { if (($variable eq "status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{$variable}) ne "ok")) { # Something is wrong with this array my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":array:".$scan_hpacucli_array_name.":".$variable; $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 5; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); } } # Logical Drive foreach my $logical_drive (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}}) { # Data foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{detail}}) { if (($variable eq "caching") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{detail}{$variable}) ne "enabled")) { # Not enabled is going to hurt performance. my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":array:".$scan_hpacucli_array_name.":logical_drive:".$logical_drive.":".$variable; $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); } elsif (($variable eq "status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{detail}{$variable}) ne "ok")) { # If the status isn't OK, it's degraded (or rebuilding, but # still degraded). my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":array:".$scan_hpacucli_array_name.":logical_drive:".$logical_drive.":".$variable; $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); } } # Physical Disks. foreach my $port (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}}) { foreach my $box (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}}) { foreach my $bay (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}}) { my $scan_hpacucli_physical_drive_serial_number = $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{serial_number}; # Data foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}}) { next if $variable eq "serial_number"; next if $variable eq "port"; next if $variable eq "box"; next if $variable eq "bay"; if (($variable eq "status") && (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{$variable}) ne "ok")) { # The drive is failed or is rebuilding. This adds 2. my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":physical_drive:".$scan_hpacucli_physical_drive_serial_number.":data:".$variable; $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = 2; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); } } # If this was a diagnostics run, check for error # counters if ($anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics}) { # If the diagnostics don't exist for the # drive and the drive is OK, it's likely a # 3rd party drive. If the status is not OK, # there may not be diagnostic data. if (exists $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_hard}) { # We got the data foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}}) { # Store this in the main hash. if ((($variable eq "hardware_errors") or ($variable eq "predictive_failure_errors") or ($variable eq "read_errors_hard") or ($variable eq "write_errors_hard")) && ($anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable} =~ /^\d+$/) && ($anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable} > 0)) { # How high is the error count? my $score = 1; if ($anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable} > 10) { # Eek $score = 3; } elsif ($anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable} > 5) { # Getting a little high $score = 2; } my $health_source_name = "controller:".$scan_hpacucli_controller_serial_number.":physical_drive:".$scan_hpacucli_physical_drive_serial_number.":diagnostics:".$variable; $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name} = $score; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "health::new::controller:$health_source_name" => $anvil->data->{'scan-hpacucli'}{health}{new}{$health_source_name}, }}); } # Record the diagnostic data # under the drive's hash. $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{'diagnostics'}{$variable} = $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{$variable}; } } elsif (lc($anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{detail}{status}) eq "ok") { # No data for this drive. It might be # a 3rd party drive. We'll warn the # user that we can't predict failure. my $changed = $anvil->Alert->check_alert_sent({clear => 0, record_locator => $scan_hpacucli_physical_drive_serial_number.":no_diagnostics", set_by => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { changed => $changed }}); if ($changed) { # Warn the user that we can't # predict this drive's death. my $variables = { serial_number => $scan_hpacucli_physical_drive_serial_number, port => $port, box => $box, bay => $bay, }; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_hpacucli_warning_0001", variables => $variables}); $anvil->Alert->register({ clear_alert => 0, alert_level => "warning", message => "scan_hpacucli_warning_0001", variables => $variables, show_header => 1, sort_position => $anvil->data->{'scan-hpacucli'}{alert_sort}++, set_by => $THIS_FILE, }); } } } } } } } } } return(0); } # This gets the basic information about the controller. sub get_controller_info { my ($anvil, $controller) = @_; my $model_name = ""; my $scan_hpacucli_controller_serial_number = ""; my $cache_serial_number = ""; my $scan_hpacucli_physical_drive_serial_number = ""; my $scan_hpacucli_array_name = ""; my $logical_drive = ""; my $port = ""; my $box = ""; my $bay = ""; my $in_array = 0; my $shell_call = $anvil->data->{path}{exe}{hpacucli}." controller slot=".$controller." show config detail"; 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, }}); foreach my $line (split/\n/, $output) { $line = $anvil->Words->clean_spaces({string => $line}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); if ((not $scan_hpacucli_controller_serial_number) && ($line =~ /^(.*?) in Slot $controller /)) { $model_name = $1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { model_name => $model_name }}); } if (($line =~ /^Serial Number: (.*?)$/) && (not $port) && (not $box) && (not $bay)) { $scan_hpacucli_controller_serial_number = $1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number }}); # Record the model number if ($model_name) { $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{model_name} = $model_name; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::data::detail::model_name" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{model_name}, }}); } # Make a reference between the slot and SN $anvil->data->{controller}{metadata}{sn_to_slot}{$scan_hpacucli_controller_serial_number} = $controller; $anvil->data->{controller}{metadata}{slot_to_sn}{$controller} = $scan_hpacucli_controller_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::metadata::sn_to_slot::${scan_hpacucli_controller_serial_number}" => $anvil->data->{controller}{metadata}{sn_to_slot}{$scan_hpacucli_controller_serial_number}, "controller::metadata::slot_to_sn::${controller}" => $anvil->data->{controller}{metadata}{slot_to_sn}{$controller}, }}); next; } next if not $scan_hpacucli_controller_serial_number; if ($line =~ /Cache Serial Number: (.*?)$/i) { $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{cache_serial_number} = $1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::data::detail::cache_serial_number" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{detail}{cache_serial_number}, }}); next; } if ($line =~ /Array: (.*?)$/i) { $scan_hpacucli_array_name = $1; $in_array = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_array_name => $scan_hpacucli_array_name, in_array => $in_array, }}); next; } if ($line =~ /Logical Drive: (.*?)$/i) { $logical_drive = $1; $in_array = 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { logical_drive => $logical_drive, in_array => $in_array, }}); next; } if ($line =~ /physicaldrive (.*?):(.*?):(.*)$/) { $port = $1; $box = $2; $bay = $3; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { port => $port, box => $box, bay => $bay, }}); next; } elsif (($port) && (($line eq "Drive Type: Data") or ($line =~ /^Mirror Group \d+:$/))) { $port = ""; $box = ""; $bay = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { port => $port, box => $box, bay => $bay, }}); } if (lc($line) eq "unassigned") { $scan_hpacucli_array_name = "ZZZZ"; $logical_drive = "9999"; $port = ""; $box = ""; $bay = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_array_name => $scan_hpacucli_array_name, logical_drive => $logical_drive, port => $port, box => $box, bay => $bay, }}); next; } # Lines I don't care about next if $line =~ /^Slot: $controller$/i; my $type = "detail"; if ($line =~ /^(.*?): (.*)$/) { my $variable = $1; my $value = $2; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable => $variable, value => $value, }}); # If the variable has units, pull them out. if ($variable =~ / \(C\)$/i) { $variable =~ s/ \(C\)$//i; $variable = $anvil->Words->clean_spaces({string => $variable}); $type = "temperature"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable => $variable, value => $value, type => $type, }}); } elsif ($variable =~ / \(F\)/i) { # Covert to °C $variable =~ s/ \(F\)$//i; $variable = $anvil->Words->clean_spaces({string => $variable}); $value = $anvil->Convert->fahrenheit_to_celsius({temperature => $value}); $type = "temperature"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable => $variable, value => $value, type => $type, }}); } elsif (($value =~ /^\d+ \wB$/) or ($value =~ /^\d+\.\d+ \wB$/)) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable => $variable, ">> value" => $value, }}); if (($variable eq "Total Cache Size") or ($variable eq "Total Cache Memory Available") or ($variable eq "Strip Size") or ($variable eq "Size") or ($variable eq "Full Stripe Size")) { # HP reports in MB, etc, but means MiB. $value = $anvil->Convert->human_readable_to_bytes({size => $value, base2 => 1}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable => $variable, "<< value" => $value, }}); } } # Save it. if (exists $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{$type}{$variable}) { # Conflict! This is a dirty way to keep them separate $variable .= " 2"; } $variable = process_variable_name($anvil, $variable); # What am I saving? if (($port) && ($box) && ($bay)) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "line" => $line, }}); # Physical drive info $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{$type}{$variable} = $value; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::array::${scan_hpacucli_array_name}::logical_drive::${logical_drive}::physical_drive::port::${port}::box::${box}::bay::${bay}::${type}::$variable" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{physical_drive}{port}{$port}{box}{$box}{bay}{$bay}{$type}{$variable}, }}); # Map the SN to it's current location. if ($line =~ /Serial Number: (.*?)$/) { $scan_hpacucli_physical_drive_serial_number = $1; my $location = $port.":".$box.":".$bay; $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number} = { array => $scan_hpacucli_array_name, logical_drive => $logical_drive, port => $port, box => $box, bay => $bay, }; $anvil->data->{physical_drive}{by_location}{$location} = $scan_hpacucli_physical_drive_serial_number; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::array" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{array}, "physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::logical_drive" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{logical_drive}, "physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::port" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{port}, "physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::box" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{box}, "physical_drive::by_serial_number::${scan_hpacucli_physical_drive_serial_number}::bay" => $anvil->data->{physical_drive}{by_serial_number}{$scan_hpacucli_physical_drive_serial_number}{bay}, "physical_drive::by_location::$location" => $anvil->data->{physical_drive}{by_location}{$location}, }}); } } elsif ($logical_drive) { # Logical drive $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{$type}{$variable} = $value; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::array::${scan_hpacucli_array_name}::logical_drive::${logical_drive}::data::${type}::$variable" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{logical_drive}{$logical_drive}{data}{$type}{$variable}, }}); } elsif ($scan_hpacucli_array_name) { # Array $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{$type}{$variable} = $value; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::array::${scan_hpacucli_array_name}::data::${type}::$variable" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{$type}{$variable}, }}); } else { # Controller data $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable} = $value; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::data::${type}::$variable" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{data}{$type}{$variable}, }}); } } elsif ($in_array) { # Messages about a degraded array can be here. # ie: "One of the drives on this array have failed or has been removed." if ($line =~ /this array have failed/) { # We'll concatonate in case there are multiple errors. if (not exists $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message}) { $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message} = ""; } $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message} .= $line."\n"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::array::${scan_hpacucli_array_name}::data::detail::error_message" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{array}{$scan_hpacucli_array_name}{data}{detail}{error_message}, }}); } } } # If I didn't find a serial number, something went wrong. if (not $scan_hpacucli_controller_serial_number) { # Error out. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0004", variables => { controller => $controller }}); $anvil->nice_exit({exit_code => 6}); } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number }}); return($scan_hpacucli_controller_serial_number); } # This will do a details diagnostics check, if enough time has passed. sub get_diagnostics { my ($anvil, $controller) = @_; # Every 'scan-hpacucli::diagnostics_interval' seconds, run a full diagnostics to check for drives in # pre-failure. $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::process_diagnostics" => $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics} }}); if (not $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics}) { # Is it time? my $query = "SELECT scan_hpacucli_controller_last_diagnostics FROM scan_hpacucli_controllers WHERE scan_hpacucli_controller_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).";"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); # The actual query -----------------. .------- Row 0 # Query this DB --. | | .-- Columns 0 my $last_diagnostics = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0]; $last_diagnostics = 0 if not defined $last_diagnostics; my $current_time = time; my $last_scan_was = $current_time - $last_diagnostics; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { last_diagnostics => $last_diagnostics, current_time => $current_time, last_scan_was => $last_scan_was, "scan-hpacucli::diagnostics_interval" => $anvil->data->{'scan-hpacucli'}{diagnostics_interval}, }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::diagnostics_interval" => $last_diagnostics, }}); if ($anvil->data->{'scan-hpacucli'}{diagnostics_interval} !~ /^\d+$/) { # Invalid value, override. $anvil->data->{'scan-hpacucli'}{diagnostics_interval} = 1800; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "scan-hpacucli::diagnostics_interval" => $anvil->data->{'scan-hpacucli'}{diagnostics_interval}, }}); } if ($last_scan_was > $anvil->data->{'scan-hpacucli'}{diagnostics_interval}) { $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics} = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::process_diagnostics" => $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics}, }}); } } # Well, is it? $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::process_diagnostics" => $anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics}, }}); if ($anvil->data->{'scan-hpacucli'}{sys}{process_diagnostics}) { # Yup! We use hpacucli's diagnostics to gather all data. my $shell_call = " cd /tmp/ ".$anvil->data->{path}{exe}{hpacucli}." controller slot=".$controller." diag file=/tmp/ADUReport.zip ".$anvil->data->{path}{exe}{'unzip'}." -o /tmp/ADUReport.zip -d /tmp/ if [ -e '/tmp/ADUReport.xml' ]; then ".$anvil->data->{path}{exe}{rm}." -f /tmp/ADUReport.zip ".$anvil->data->{path}{exe}{rm}." -f /tmp/ADUReport.htm ".$anvil->data->{path}{exe}{rm}." -f /tmp/ADUReport.xml ".$anvil->data->{path}{exe}{rm}." -f /tmp/report.checksum fi "; # Write a log message to warn the user that we're starting a long process. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_hpacucli_log_0003", variables => { 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, }}); foreach my $line (split/\n/, $output) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); } undef $output; undef $return_code; # Did it work? if (not -r "/tmp/ADUReport.txt") { # Something went wrong. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0005", variables => { path => "/tmp/ADUReport.txt" }}); $anvil->nice_exit({exit_code => 4}); } # Get this controller's serial number my $scan_hpacucli_controller_serial_number = $anvil->data->{controller}{metadata}{slot_to_sn}{$controller}; # Parse! my $in_cache_config_status = 0; my $in_physical_drive = 0; my $scan_hpacucli_physical_drive_serial_number = ""; my $port = ""; my $box = ""; my $bay = ""; my $skip_blank_line = 0; $shell_call = "/tmp/ADUReport.txt"; ($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, }}); foreach my $line (split/\n/, $output) { $line = $anvil->Words->clean_spaces({string => $line}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); if (not $line) { if ($skip_blank_line) { next; } $in_cache_config_status = 0; $in_physical_drive = 0; $scan_hpacucli_physical_drive_serial_number = ""; $port = ""; $box = ""; $bay = ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_cache_config_status => $in_cache_config_status, in_physical_drive => $in_physical_drive, scan_hpacucli_physical_drive_serial_number => $scan_hpacucli_physical_drive_serial_number, port => $port, box => $box, bay => $bay, }}); next; } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); $skip_blank_line = 0; if ($line =~ /: Cache Config Status$/i) { $in_cache_config_status = 1; $skip_blank_line = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_cache_config_status => $in_cache_config_status }}); next; } if ($line =~ /: Physical Drive \(.*?\) (.*?):(.*?):(.*?) : Monitor and Performance Statistics \(Since Factory\)/) { $port = $1; $box = $2; $bay = $3; $skip_blank_line = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { port => $port, box => $box, bay => $bay, }}); } if ($in_cache_config_status) { if ($line =~ /Parity Read Errors (\d+) \(/) { $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{'diagnostics'}{cache}{parity_read_errors} = $1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::diagnostics::cache::parity_read_errors" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{'diagnostics'}{cache}{parity_read_errors}, }}); } if ($line =~ /Parity Write Errors (\d+) \(/) { $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{'diagnostics'}{cache}{parity_write_errors} = $1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "controller::${scan_hpacucli_controller_serial_number}::diagnostics::cache::parity_write_errors" => $anvil->data->{controller}{$scan_hpacucli_controller_serial_number}{'diagnostics'}{cache}{parity_write_errors}, }}); } } if (($port) && ($box) && ($bay)) { my $location = $port.":".$box.":".$bay; $scan_hpacucli_physical_drive_serial_number = $anvil->data->{physical_drive}{by_location}{$location}; if ($line =~ /Read Errors Hard (0x.*?)$/) { my $hex = $1; $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_hard} = hex($hex); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hex" => $hex, "physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::read_errors_hard" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_hard}, }}); } if ($line =~ /Read Errors Retry Recovered (0x.*?)$/) { my $hex = $1; $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_retry_recovered} = hex($hex); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hex" => $hex, "physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::read_errors_retry_recovered" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_retry_recovered}, }}); } if ($line =~ /Read Errors ECC Corrected (0x.*?)$/) { my $hex = $1; $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_ecc_corrected} = hex($hex); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hex" => $hex, "physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::read_errors_ecc_corrected" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{read_errors_ecc_corrected}, }}); } if ($line =~ /Write Errors Hard (0x.*?)$/) { my $hex = $1; $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_hard} = hex($hex); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hex" => $hex, "physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::write_errors_hard" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_hard}, }}); } if ($line =~ /Write Errors Retry Recovered (0x.*?)$/) { my $hex = $1; $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_retry_recovered} = hex($hex); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hex" => $hex, "physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::write_errors_retry_recovered" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_retry_recovered}, }}); } if ($line =~ /Format Errors (0x.*?)$/) { my $hex = $1; $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{format_errors} = hex($hex); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hex" => $hex, "physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::format_errors" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{format_errors}, }}); } if ($line =~ /Write Errors After Remap (0x.*?)$/) { my $hex = $1; $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_after_remap} = hex($hex); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hex" => $hex, "physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::write_errors_after_remap" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{write_errors_after_remap}, }}); } if ($line =~ /Hardware Errors (0x.*?)$/) { my $hex = $1; $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{hardware_errors} = hex($hex); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hex" => $hex, "physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::hardware_errors" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{hardware_errors}, }}); } if ($line =~ /Predictive Failure Errors (0x.*?)$/) { my $hex = $1; $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{predictive_failure_errors} = hex($hex); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "hex" => $hex, "physical_drive::${scan_hpacucli_physical_drive_serial_number}::diagnostics::predictive_failure_errors" => $anvil->data->{physical_drive}{$scan_hpacucli_physical_drive_serial_number}{'diagnostics'}{predictive_failure_errors}, }}); } } } } return(0); } # This gathers the various data from the controller(s). sub gather_data { my ($anvil) = @_; ### TODO: This assumes the controllers go 0, 1, ... n. If this is wrong, we'll need to call ### 'hpacucli controller all show' and parse the output as our outer loop. # Loops through reach found controller. foreach my $count (1..$anvil->data->{'scan-hpacucli'}{sys}{controller_count}) { my $controller = $count - 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { controller => $controller }}); # Read in controller data. my $scan_hpacucli_controller_serial_number = get_controller_info($anvil, $controller); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { scan_hpacucli_controller_serial_number => $scan_hpacucli_controller_serial_number }}); get_diagnostics($anvil, $controller); } return(0); } # This processes variable names to flatten them and remove spaces and special characters. sub process_variable_name { my ($anvil, $variable) = @_; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "<< variable" => $variable }}); $variable = lc($variable); $variable =~ s/ /_/g; $variable =~ s/-/_/g; $variable =~ s/&/and/g; $variable =~ s/\//_or_/g; $variable =~ s/_%/_percent/g; $variable =~ s/{_}+/_/g; $variable =~ s/^_+//g; $variable =~ s/_+$//g; $variable =~ s/(\w)\(/$1_\(/; $variable =~ s/\((.*?)\)/-_$1/g; $variable =~ s/_+/_/g; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ">> variable" => $variable }}); return($variable); } # This does two things; It checks to see if hpacucli is installed (exits '1' if not, exits '2' if not # executable) and then checks to see if any controllers are found in the system (exits '3' if not). sub find_hp_controllers { my ($anvil) = @_; # This will keep track of how many controllers we find. my $controller_count = 0; # First, do we have hpacucli installed? if (not -e $anvil->data->{path}{exe}{hpacucli}) { # Nope, exit. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "scan_hpacucli_error_0001", variables => { path => $anvil->data->{path}{exe}{hpacucli} }}); $anvil->nice_exit({exit_code => 1}); } # Make sure it is executable if (not -x $anvil->data->{path}{exe}{hpacucli}) { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0002", variables => { path => $anvil->data->{path}{exe}{hpacucli} }}); $anvil->nice_exit({exit_code => 2}); } # Still alive? Good! Look for controllers now. my $shell_call = $anvil->data->{path}{exe}{hpacucli}." controller all show"; 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, }}); foreach my $line (split/\n/, $output) { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); if ($line =~ /.*? Slot (\d+) .*?\(sn: (.*?)\)/i) { my $controller_number = $1; my $controller_serial_number = $2; $controller_count++; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { controller_number => $controller_number, controller_serial_number => $controller_serial_number, controller_count => $controller_count, }}); } } # Have we any controllers? if ($controller_count > 0) { $anvil->data->{'scan-hpacucli'}{sys}{controller_count} = $controller_count; $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, key => "scan_hpacucli_log_0001", variables => { count => $anvil->data->{'scan-hpacucli'}{sys}{controller_count} }}); } else { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "scan_hpacucli_error_0003", variables => { path => $anvil->data->{path}{exe}{hpacucli} }}); $anvil->nice_exit({exit_code => 3}); } return(0); }