* Created Database->get_tables_from_schema() that returns an ordered list of tables in a database schema file, removing the need for scan agents to manually provide a list for agent start-up / DB purge.

* Updated ScanCore->agent_startup() to use Database->get_tables_from_schema() when the 'tables' parameter isn't passed.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 4 years ago
parent 7e6e345513
commit 9c92b6bbb8
  1. 59
      Anvil/Tools/Database.pm
  2. 17
      Anvil/Tools/ScanCore.pm
  3. 2
      scancore-agents/scan-hardware/scan-hardware
  4. 233
      tools/test.pl

@ -38,6 +38,7 @@ my $THIS_FILE = "Database.pm";
# get_recipients
# get_servers
# get_ssh_keys
# get_tables_from_schema
# get_upses
# initialize
# insert_or_update_anvils
@ -3756,6 +3757,64 @@ FROM
}
=head2 get_tables_from_schema
This reads in a schema file and generates an array of tables. The array contains the tables in the order they are found in the schema. If there is a problem, C<< !!error!! >> is returned. On success, an array reference is returned.
Parameters;
=head3 schema_file (required)
This is the full path to a SQL schema file to look for tables in.
=cut
sub get_tables_from_schema
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->get_tables_from_schema()" }});
my $tables = [];
my $schema_file = defined $parameter->{schema_file} ? $parameter->{schema_file} : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
schema_file => $schema_file,
}});
if (not $schema_file)
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->get_tables_from_schema()", parameter => "schema_file" }});
return("!!error!!");
}
my $schema = $anvil->Storage->read_file({file => $schema_file});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { schema_file => $schema_file }});
if ($schema eq "!!error!!")
{
return("!!error!!");
}
foreach my $line (split/\n/, $schema)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
$line =~ s/--.*?//;
next if $line =~ /CREATE TABLE history\./;
if ($line =~ /CREATE TABLE (.*?) \(/i)
{
my $table = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { table => $table }});
push @{$tables}, $table;
}
}
return($tables);
}
=head2 get_upses
This loads the known UPSes (uninterruptible power supplies) into the C<< anvil::data >> hash at:

@ -128,8 +128,21 @@ sub agent_startup
}
if ((not $tables) or (ref($tables) ne "ARRAY"))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "ScanCore->agent_startup()", parameter => "tables" }});
return("!!error!!");
my $schema_file = $anvil->data->{path}{directories}{scan_agents}."/".$agent."/".$agent.".sql";
if (-e $schema_file)
{
$tables = $anvil->Database->get_tables_from_schema({debug => $debug, schema_file => $schema_file});
if (($tables eq "!!error!!") or (ref($tables) ne "ARRAY"))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "ScanCore->agent_startup()", parameter => "tables" }});
return("!!error!!");
}
}
else
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "ScanCore->agent_startup()", parameter => "tables" }});
return("!!error!!");
}
}
# Connect to DBs.

@ -54,7 +54,7 @@ $anvil->data->{scancore}{'scan-hardware'}{swap}{high_threshold} = 75;
$anvil->data->{switches}{force} = 0;
$anvil->Storage->read_config();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0115", variables => { program => $THIS_FILE }});
# Read switches
$anvil->Get->switches;

@ -33,232 +33,11 @@ print "Connecting to the database(s);\n";
$anvil->Database->connect({debug => 3});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0132"});
# These packages can't be downloaded on RHEL Striker dashboads as they usually are not entitled to
$anvil->data->{ha_packages} = {
c => [
"corosync.x86_64",
"corosynclib.x86_64",
],
l => [
"libknet1.x86_64",
"libknet1-compress-bzip2-plugin.x86_64",
"libknet1-compress-lz4-plugin.x86_64",
"libknet1-compress-lzma-plugin.x86_64",
"libknet1-compress-lzo2-plugin.x86_64",
"libknet1-compress-plugins-all.x86_64",
"libknet1-compress-zlib-plugin.x86_64",
"libknet1-crypto-nss-plugin.x86_64",
"libknet1-crypto-openssl-plugin.x86_64",
"libknet1-crypto-plugins-all.x86_64",
"libknet1-plugins-all.x86_64",
"libnozzle1.x86_64",
],
p => [
"pacemaker.x86_64",
"pacemaker-cli.x86_64",
"pacemaker-cluster-libs.x86_64",
"pacemaker-libs.x86_64",
"pacemaker-schemas.noarch",
],
r => [
"resource-agents.x86_64",
],
};
my $use_node_name = "";
my $use_node_ip = "";
my $use_password = "";
my ($os_type, $os_arch) = $anvil->Get->os_type();
$anvil->data->{host_os}{os_type} = $os_type;
$anvil->data->{host_os}{os_arch} = $os_arch;
if ($anvil->data->{host_os}{os_type} eq "rhel8")
my $agent = "scan-apc-ups";
my $schema_file = $anvil->data->{path}{directories}{scan_agents}."/".$agent."/".$agent.".sql";
my $tables = $anvil->Database->get_tables_from_schema({debug => 2, schema_file => $schema_file});
print "Schema file: [".$schema_file."]\n";
foreach my $table (@{$tables})
{
my $local_short_host_name = $anvil->Get->short_host_name;
$anvil->Network->load_ips({
debug => 3,
host => $local_short_host_name,
});
print "My OS is: [".$anvil->data->{host_os}{os_type}."], [".$anvil->data->{host_os}{os_arch}."]\n";
my $query = "
SELECT
a.host_uuid,
a.host_name,
b.anvil_password
FROM
hosts a,
anvils b
WHERE
a.host_type = 'node'
AND
(
a.host_uuid = b.anvil_node1_host_uuid
OR
a.host_uuid = b.anvil_node2_host_uuid
)
ORDER BY
a.host_name ASC
;";
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 $host_uuid = $row->[0];
my $host_name = $row->[1];
my $anvil_password = $row->[2];
my $short_host_name = $host_name;
$short_host_name =~ s/\..*$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid,
host_name => $host_name,
anvil_password => $anvil->Log->is_secure($anvil_password),
short_host_name => $short_host_name,
}});
$anvil->Network->load_ips({
debug => 3,
host_uuid => $host_uuid,
host => $short_host_name,
});
my $access = 0;
my ($match) = $anvil->Network->find_matches({
debug => 3,
first => $local_short_host_name,
second => $short_host_name,
});
my $keys = keys %{$match};
print "Node: [".$host_name."]\n";
print "- match: [".$match."], keys: [".$keys."]\n";
if ($keys)
{
foreach my $interface (sort {$a cmp $b} keys %{$match->{$short_host_name}})
{
my $remote_ip = $match->{$short_host_name}{$interface}{ip};
print "- Should be able to reach: [".$short_host_name."] at the IP: [".$remote_ip."]\n";
my $pinged = $anvil->Network->ping({
ping => $remote_ip,
count => 1,
});
if ($pinged)
{
print "- The node is pingable, checking access.\n";
my $access = $anvil->Remote->test_access({
target => $remote_ip,
password => $anvil_password,
});
if ($access)
{
print "- Accessed! Testing Internet...\n";
my $internet = $anvil->Network->check_internet({
debug => 3,
target => $remote_ip,
password => $anvil_password,
});
if ($internet)
{
print "- Has Internet access! Checking OS...\n";
my ($os_type, $os_arch) = $anvil->Get->os_type({
debug => 3,
target => $remote_ip,
password => $anvil_password,
});
print "- The host OS is: [".$os_type."], [".$os_arch."]\n";
if (($anvil->data->{host_os}{os_type} eq $os_type) && ($os_arch eq $anvil->data->{host_os}{os_arch}))
{
print "- Found a match!\n";
$use_node_name = $host_name;
$use_node_ip = $remote_ip;
$use_password = $anvil_password;
last;
}
}
}
else
{
print "- Unable to connect.\n";
}
}
else
{
print "- Unable to ping, skipping.\n";
}
}
}
}
if ($use_node_ip)
{
print "Will download RPMs via: [".$use_node_name."] via IP: [".$use_node_ip."]\n";
foreach my $letter (sort {$a cmp $b} keys %{$anvil->data->{ha_packages}})
{
my $download_path = "/tmp/Packages/".$letter;
my $local_path = "/var/www/html/".$anvil->data->{host_os}{os_type}."/".$anvil->data->{host_os}{os_arch}."/os/Packages/".$letter;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
letter => $letter,
download_path => $download_path,
local_path => $local_path,
}});
# This is the directory we'll download the packages to on the node.
$anvil->Storage->make_directory({
debug => 3,
directory => $download_path,
target => $use_node_ip,
password => $use_password,
mode => "0775",
});
my $packages = "";
my $shell_call = $anvil->data->{path}{exe}{dnf}." download --destdir ".$download_path." ";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
foreach my $package (sort {$a cmp $b} @{$anvil->data->{ha_packages}{$letter}})
{
# Append the package to the active shell call.
$packages .= $package." ";
}
$packages =~ s/ $//;
$shell_call .= " ".$packages;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
# None of the HA packages are large os it's not worth trying to monitor the downlaods
# in real time. As such, we'll make a standard remote call.
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
target => $use_node_ip,
password => $use_password,
shell_call => $shell_call,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
if (not $return_code)
{
# Success! Copy the files.
my $failed = $anvil->Storage->rsync({
debug => 2,
source => "root\@".$use_node_ip.":".$download_path."/*",
destination => $local_path."/",
password => $use_password,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }});
}
}
}
else
{
print "No nodes are available to try to download HA packages from.\n"
}
print "- ".$table."\n";
}

Loading…
Cancel
Save