* Connecting to a database now adds/updates the host in the database via the new Database->insert_or_update_hosts and Database->get_hosts().

* Created the new System->determine_host_type() method that tries to determine the host type based on the host name (or via sys::host_type).

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 8 years ago
parent 4aff8a1722
commit 6080ae0bb3
  1. 3
      AN/Tools.pm
  2. 211
      AN/Tools/Database.pm
  3. 51
      AN/Tools/System.pm
  4. 8
      striker.conf

@ -126,6 +126,9 @@ sub new
# This is the host's UUID. It should never be manually set.
UUID => "",
},
sys => {
host_type => "",
},
};
# Bless you!

@ -15,8 +15,10 @@ my $THIS_FILE = "Database.pm";
# configure_pgsql
# connect
# disconnect
# get_hosts
# get_local_id
# initialize
# insert_or_update_hosts
# insert_or_update_states
# insert_or_update_variables
# locking
@ -894,6 +896,9 @@ sub connect
# Mark that we're not active.
$an->Database->mark_active({set => 1});
# Add ourselves to the database, if needed.
$an->Database->insert_or_update_hosts();
return($connections);
}
@ -934,6 +939,72 @@ sub disconnect
return(0);
}
=head2 get_hosts
Get a list of hosts from the c<< hosts >> table, returned as an array of hash references.
Each anonymous hash is structured as:
host_uuid => $host_uuid,
host_name => $host_name,
host_type => $host_type,
modified_date => $modified_date,
It also sets the variables C<< sys::hosts::by_uuid::<host_uuid> = <host_name> >> and C<< sys::hosts::by_name::<host_name> = <host_uuid> >> per host read, for quick reference.
=cut
sub get_hosts
{
my $self = shift;
my $parameter = shift;
my $an = $self->parent;
my $query = "
SELECT
host_uuid,
host_name,
host_type,
modified_date
FROM
hosts
;";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $return = [];
my $results = $an->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$an->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 $host_type = $row->[2];
my $modified_date = $row->[3];
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid,
host_name => $host_name,
host_type => $host_type,
modified_date => $modified_date,
}});
push @{$return}, {
host_uuid => $host_uuid,
host_name => $host_name,
host_type => $host_type,
modified_date => $modified_date,
};
# Record the host_uuid in a hash so that the name can be easily retrieved.
$an->data->{sys}{hosts}{by_uuid}{$host_uuid} = $host_name;
$an->data->{sys}{hosts}{by_name}{$host_name} = $host_uuid;
}
return($return);
}
=head2 get_local_id
This returns the database ID from 'C<< striker.conf >>' based on matching the 'C<< database::<id>::host >>' to the local machine's host name or one of the active IP addresses on the host.
@ -1070,6 +1141,136 @@ sub initialize
return($success);
};
=head2 insert_or_update_hosts
This updates (or inserts) a record in the 'hosts' table.
If there is an error, an empty string is returned.
Parameters;
=head3 host_name (required)
This default value is the local hostname.
=head3 host_type (required)
This default value is the value returned by C<< System->determine_host_type >>.
=head3 host_uuid (required)
The default value is the host's UUID (as returned by C<< Get->host_uuid >>.
=head3 id (optional)
If set, only the corresponding database will be written to.
=cut
sub insert_or_update_hosts
{
my $self = shift;
my $parameter = shift;
my $an = $self->parent;
my $host_name = $parameter->{host_name} ? $parameter->{host_name} : $an->_hostname;
my $host_type = $parameter->{host_type} ? $parameter->{host_type} : $an->System->determine_host_type;
my $host_uuid = $parameter->{host_uuid} ? $parameter->{host_uuid} : $an->Get->host_uuid;
my $id = $parameter->{id} ? $parameter->{id} : "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_name => $host_name,
host_type => $host_type,
host_uuid => $host_uuid,
id => $id,
}});
if (not $host_name)
{
# Throw an error and exit.
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_hosts()", parameter => "host_name" }});
return("");
}
if (not $host_uuid)
{
# Throw an error and exit.
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_hosts()", parameter => "host_uuid" }});
return("");
}
# Read the old values, if they exist.
my $old_host_name = "";
my $old_host_type = "";
my $query = "
SELECT
host_name,
host_type
FROM
hosts
WHERE
host_uuid = ".$an->data->{sys}{use_db_fh}->quote($host_uuid)."
;";
$an->Log->entry({log_level => 2, message_key => "an_variables_0001", message_variables => {
name1 => "query", value1 => $query
}, file => $THIS_FILE, line => __LINE__});
my $results = $an->Database->query({query => $query, id => $id, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
$old_host_name = $row->[0];
$old_host_type = $row->[1];
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
old_host_name => $old_host_name,
old_host_type => $old_host_type,
}});
}
if (not $count)
{
# Add this host to the database
my $query = "
INSERT INTO
hosts
(
host_uuid,
host_name,
host_type,
modified_date
) VALUES (
".$an->data->{sys}{use_db_fh}->quote($host_uuid).",
".$an->data->{sys}{use_db_fh}->quote($host_name).",
".$an->data->{sys}{use_db_fh}->quote($host_type).",
".$an->data->{sys}{use_db_fh}->quote($an->data->{sys}{db_timestamp})."
);
";
$query =~ s/'NULL'/NULL/g;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$an->Database->write({query => $query, id => $id, source => $THIS_FILE, line => __LINE__});
}
else
{
# Clear the stop data.
my $query = "
UPDATE
hosts
SET
host_name = ".$an->data->{sys}{use_db_fh}->quote($host_name).",
host_type = ".$an->data->{sys}{use_db_fh}->quote($host_type).",
modified_date = ".$an->data->{sys}{use_db_fh}->quote($an->data->{sys}{db_timestamp})."
WHERE
host_uuid = ".$an->data->{sys}{use_db_fh}->quote($host_uuid)."
;";
$query =~ s/'NULL'/NULL/g;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$an->Database->write({query => $query, id => $id, source => $THIS_FILE, line => __LINE__});
}
return(0);
}
=head2 insert_or_update_states
This updates (or inserts) a record in the 'states' table. The C<< state_uuid >> referencing the database row will be returned.
@ -1159,7 +1360,7 @@ AND
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $an->ScanCore->get_hosts();
my $hosts = $an->Database->get_hosts();
my $found = 0;
foreach my $hash_ref (@{$hosts})
{
@ -1974,6 +2175,7 @@ sub query
}
# Test access to the DB before we do the actual query
$an->Log->entry({source => $source, line => $line, secure => $secure, level => 2, key => "log_0074", variables => { id => $id }});
$an->Database->_test_access({ id => $id });
# Do the query.
@ -2000,7 +2202,7 @@ This reads a variable from the C<< variables >> table. Be sure to only use the r
The method returns an array reference containing, in order, the variable's value, database UUID and last modified date stamp.
If anything goes wrong, C<< undef >> is returned.
If anything goes wrong, C<< undef >> is returned. If the variable didn't exist in the database, an empty string will be returned for the UUID, value and modified date.
Parameters;
@ -2068,8 +2270,8 @@ AND
$query .= ";";
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0074", variables => { query => $query }});
my $variable_value = undef;
my $modified_date = undef;
my $variable_value = "";
my $modified_date = "";
my $results = $an->Database->query({id => $id, query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
@ -2234,6 +2436,7 @@ sub write
foreach my $id (@db_ids)
{
# Test access to the DB before we do the actual query
$an->Log->entry({source => $source, line => $line, secure => $secure, level => 2, key => "log_0074", variables => { id => $id }});
$an->Database->_test_access({id => $id});
# Do the actual query(ies)

@ -15,6 +15,7 @@ my $THIS_FILE = "System.pm";
# call
# check_daemon
# check_memory
# determine_host_type
# enable_daemon
# ping
# read_ssh_config
@ -192,6 +193,9 @@ sub check_daemon
}
=head2 check_memory
# Not yet written...
=cut
sub check_memory
{
@ -199,7 +203,6 @@ sub check_memory
my $parameter = shift;
my $an = $self->parent;
my $program_name = defined $parameter->{program_name} ? $parameter->{program_name} : "";
my $program_pid = defined $parameter->{program_pid} ? $parameter->{program_pid} : 0;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
@ -220,6 +223,52 @@ sub check_memory
return($used_ram);
}
=head2 determine_host_type
This method tries to determine the host type and returns a value suitable for use is the C<< hosts >> table.
First, it looks to see if C<< sys::host_type >> is set and, if so, uses that string as it is.
If that isn't set, it then looks at the short host name. The following rules are used, in order;
1. If the host name ends in C<< n<digits> >> or C<< node<digits> >>, C<< node >> is returned.
2. If the host name ends in C<< striker<digits> >> or C<< dashboard<digits> >>, C<< dashboard >> is returned.
3. If the host name ends in C<< dr<digits> >>, C<< dr >> is returned.
=cut
sub determine_host_type
{
my $self = shift;
my $parameter = shift;
my $an = $self->parent;
my $host_type = "";
my $host_name = $an->_hostname;
$host_type = "unknown";
if ($an->data->{sys}{host_type})
{
$host_type = $an->data->{sys}{host_type};
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
}
elsif (($host_name =~ /n\d+$/) or ($host_name =~ /node\d+$/))
{
$host_type = "node";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
}
elsif (($host_name =~ /striker\d+$/) or ($host_name =~ /dashboard\d+$/))
{
$host_type = "dashboard";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
}
elsif ($host_name =~ /dr\d+$/)
{
$host_type = "dr";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
}
return($host_type);
}
=head2 enable_daemon
This method enables a daemon (so that it starts when the OS boots). The return code from the start request will be returned.

@ -19,3 +19,11 @@ database::2::ping_before_connect = 1
# useful when doing very large transacions, like resync'ing a large table, by limiting how long a given
# transaction can take and how much memory is used.
sys::database::maximum_batch_size = 25000
# By default, we try to determine the host type using the host name. The rules used for this can be seen in
# 'perldoc AN::Tools::System -> determine_host_type'. If you are using non-standard host names, or for some
# other reason want to statically assign the host type, you can do so with this variable. Note that this sets
# the host type of this host only. You will need to set this appropriately on other hosts.
#
# Normally, you should not need to set this.
#sys::host_type = node

Loading…
Cancel
Save