From 726a4374d1ec0a737021c9034868775ec067f52b Mon Sep 17 00:00:00 2001 From: Digimer Date: Wed, 10 Jun 2020 18:26:50 -0400 Subject: [PATCH] * Renamed the database table 'host_keys' to 'ssh_keys' to better represent what it stores. * Updated 'variables' -> 'variable_source_uuid' to type 'uuid' and removed the 'not null' constraint. * Updated Database->insert_or_update_variables() to check/update 'variables_source_table' and 'variables_source_uuid'. * Created the 'trusts' database table which will, when done, tell anvil-daemon which users@machines to trust (setup passwordkess SSH). * Created (but not finished) System->manage_authorized_keys() and moved the logic over to it from anvil-daemon. * Changed the host types "dashboard" to "striker". * Moved the following methods from 'System' to 'Get'; ** System->get_host_type to Get->host_type ** System->get_bridges to Get->bridges ** System->get_free_memory to Get->free_memory ** System->get_os_type to Get->os_type ** System->get_uptime to Get->uptime * Updated striker to include the host_uuid for the 'node1', 'node2' and (if chosen) 'dr1' when running a job manifest. Signed-off-by: Digimer --- Anvil/Tools.pm | 5 +- Anvil/Tools/Database.pm | 232 +++++---- Anvil/Tools/Get.pm | 327 ++++++++++++ Anvil/Tools/Server.pm | 2 +- Anvil/Tools/Striker.pm | 10 +- Anvil/Tools/System.pm | 742 ++++++++++++++++------------ cgi-bin/striker | 77 ++- notes | 269 +--------- ocf/alteeve/server | 4 +- rpm/SPECS/anvil.spec | 14 +- share/anvil.sql | 70 +-- tools/anvil-configure-host | 6 +- tools/anvil-daemon | 429 ++-------------- tools/anvil-join-anvil | 102 ++-- tools/anvil-manage-firewall | 2 +- tools/anvil-manage-power | 2 +- tools/anvil-update-states | 8 +- tools/striker-manage-install-target | 6 +- tools/test.pl | 8 +- 19 files changed, 1131 insertions(+), 1184 deletions(-) diff --git a/Anvil/Tools.pm b/Anvil/Tools.pm index dde73a50..862388b5 100644 --- a/Anvil/Tools.pm +++ b/Anvil/Tools.pm @@ -882,7 +882,7 @@ sub _set_defaults # grep 'CREATE TABLE' share/anvil.sql | grep -v history. | awk '{print $3}' core_tables => [ "hosts", # Always has to be first. - "host_keys", + "ssh_keys", "users", "host_variable", "sessions", # Has to come after users and hosts @@ -908,6 +908,7 @@ sub _set_defaults "states", "manifests", "fences", + "upses", ], failed_connection_log_level => 1, local_lock_active => 0, @@ -1065,7 +1066,7 @@ sub _set_paths pxe_default => "/var/lib/tftpboot/pxelinux.cfg/default", pxe_uefi => "/var/lib/tftpboot/pxelinux.cfg/uefi", ssh_config => "/etc/ssh/ssh_config", - 'type.dashboard' => "/etc/anvil/type.dashboard", + 'type.striker' => "/etc/anvil/type.striker", 'type.dr' => "/etc/anvil/type.dr", 'type.node' => "/etc/anvil/type.node", }, diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index 723d3ce4..f4837a43 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -40,7 +40,7 @@ my $THIS_FILE = "Database.pm"; # insert_or_update_fences # insert_or_update_file_locations # insert_or_update_files -# insert_or_update_host_keys +# insert_or_update_ssh_keys # insert_or_update_hosts # insert_or_update_ip_addresses # insert_or_update_jobs @@ -164,9 +164,9 @@ sub archive_database } # If this isn't a dashboard, exit. - my $host_type = $anvil->System->get_host_type(); + my $host_type = $anvil->Get->host_type(); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); - if ($host_type ne "dashboard") + if ($host_type ne "striker") { # Not a dashboard, don't archive $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0452"}); @@ -4584,9 +4584,9 @@ WHERE } -=head2 insert_or_update_host_keys +=head2 insert_or_update_ssh_keys -This updates (or inserts) a record in the 'host_keys' table. The C<< host_key_uuid >> UUID will be returned. +This updates (or inserts) a record in the 'ssh_keys' table. The C<< ssh_key_uuid >> UUID will be returned. If there is an error, an empty string is returned. @@ -4604,73 +4604,73 @@ If set, this is the file name logged as the source of any INSERTs or UPDATEs. If set, this is the file line number logged as the source of any INSERTs or UPDATEs. -=head3 host_key_host_uuid (optional, default is Get->host_uuid) +=head3 ssh_key_host_uuid (optional, default is Get->host_uuid) This is the host that the corresponding user and key belong to. -=head3 host_key_public_key (required) +=head3 ssh_key_public_key (required) This is the B<> key for the user, the full line stored in the user's C<< ~/.ssh/id_rsa.pub >> file. -=head3 host_key_user_name (required) +=head3 ssh_key_user_name (required) This is the name of the user that the public key belongs to. -=head3 host_key_uuid (optional) +=head3 ssh_key_uuid (optional) This is the specific record to update. If not provides, a search will be made to find a matching entry. If found, the record will be updated if one of the values has changed. If not, a new record will be inserted. =cut -sub insert_or_update_host_keys +sub insert_or_update_ssh_keys { my $self = shift; my $parameter = shift; my $anvil = $self->parent; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->insert_or_update_host_keys()" }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->insert_or_update_ssh_keys()" }}); my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : ""; my $file = defined $parameter->{file} ? $parameter->{file} : ""; my $line = defined $parameter->{line} ? $parameter->{line} : ""; - my $host_key_host_uuid = defined $parameter->{host_key_host_uuid} ? $parameter->{host_key_host_uuid} : $anvil->Get->host_uuid; - my $host_key_public_key = defined $parameter->{host_key_public_key} ? $parameter->{host_key_public_key} : ""; - my $host_key_user_name = defined $parameter->{host_key_user_name} ? $parameter->{host_key_user_name} : ""; - my $host_key_uuid = defined $parameter->{host_key_uuid} ? $parameter->{host_key_uuid} : ""; + my $ssh_key_host_uuid = defined $parameter->{ssh_key_host_uuid} ? $parameter->{ssh_key_host_uuid} : $anvil->Get->host_uuid; + my $ssh_key_public_key = defined $parameter->{ssh_key_public_key} ? $parameter->{ssh_key_public_key} : ""; + my $ssh_key_user_name = defined $parameter->{ssh_key_user_name} ? $parameter->{ssh_key_user_name} : ""; + my $ssh_key_uuid = defined $parameter->{ssh_key_uuid} ? $parameter->{ssh_key_uuid} : ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid, file => $file, line => $line, - host_key_host_uuid => $host_key_host_uuid, - host_key_public_key => $host_key_public_key, - host_key_user_name => $host_key_user_name, - host_key_uuid => $host_key_uuid, + ssh_key_host_uuid => $ssh_key_host_uuid, + ssh_key_public_key => $ssh_key_public_key, + ssh_key_user_name => $ssh_key_user_name, + ssh_key_uuid => $ssh_key_uuid, }}); - if (not $host_key_public_key) + if (not $ssh_key_public_key) { # Throw an error and exit. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_host_keys()", parameter => "host_key_public_key" }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_ssh_keys()", parameter => "ssh_key_public_key" }}); return(""); } - if (not $host_key_user_name) + if (not $ssh_key_user_name) { # Throw an error and exit. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_host_keys()", parameter => "host_key_user_name" }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_ssh_keys()", parameter => "ssh_key_user_name" }}); return(""); } # If we don't have a UUID, see if we can find one for the given user and host. - if (not $host_key_uuid) + if (not $ssh_key_uuid) { my $query = " SELECT - host_key_uuid + ssh_key_uuid FROM - host_keys + ssh_keys WHERE - host_key_user_name = ".$anvil->Database->quote($host_key_user_name)." + ssh_key_user_name = ".$anvil->Database->quote($ssh_key_user_name)." AND - host_key_host_uuid = ".$anvil->Database->quote($host_key_host_uuid)." + ssh_key_host_uuid = ".$anvil->Database->quote($ssh_key_host_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); @@ -4682,33 +4682,33 @@ AND }}); if ($count) { - $host_key_uuid = $results->[0]->[0]; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_key_uuid => $host_key_uuid }}); + $ssh_key_uuid = $results->[0]->[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ssh_key_uuid => $ssh_key_uuid }}); } } - # If I still don't have an host_key_uuid, we're INSERT'ing . - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_key_uuid => $host_key_uuid }}); - if (not $host_key_uuid) + # If I still don't have an ssh_key_uuid, we're INSERT'ing . + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ssh_key_uuid => $ssh_key_uuid }}); + if (not $ssh_key_uuid) { # INSERT - $host_key_uuid = $anvil->Get->uuid(); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_key_uuid => $host_key_uuid }}); + $ssh_key_uuid = $anvil->Get->uuid(); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ssh_key_uuid => $ssh_key_uuid }}); my $query = " INSERT INTO - host_keys + ssh_keys ( - host_key_uuid, - host_key_host_uuid, - host_key_public_key, - host_key_user_name, + ssh_key_uuid, + ssh_key_host_uuid, + ssh_key_public_key, + ssh_key_user_name, modified_date ) VALUES ( - ".$anvil->Database->quote($host_key_uuid).", - ".$anvil->Database->quote($host_key_host_uuid).", - ".$anvil->Database->quote($host_key_public_key).", - ".$anvil->Database->quote($host_key_user_name).", + ".$anvil->Database->quote($ssh_key_uuid).", + ".$anvil->Database->quote($ssh_key_host_uuid).", + ".$anvil->Database->quote($ssh_key_public_key).", + ".$anvil->Database->quote($ssh_key_user_name).", ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." ); "; @@ -4720,13 +4720,13 @@ INSERT INTO # Query the rest of the values and see if anything changed. my $query = " SELECT - host_key_host_uuid, - host_key_public_key, - host_key_user_name + ssh_key_host_uuid, + ssh_key_public_key, + ssh_key_user_name FROM - host_keys + ssh_keys WHERE - host_key_uuid = ".$anvil->Database->quote($host_key_uuid)." + ssh_key_uuid = ".$anvil->Database->quote($ssh_key_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); @@ -4738,37 +4738,37 @@ WHERE }}); if (not $count) { - # I have a host_key_uuid but no matching record. Probably an error. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0216", variables => { uuid_name => "host_key_uuid", uuid => $host_key_uuid }}); + # I have a ssh_key_uuid but no matching record. Probably an error. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0216", variables => { uuid_name => "ssh_key_uuid", uuid => $ssh_key_uuid }}); return(""); } foreach my $row (@{$results}) { - my $old_host_key_host_uuid = $row->[0]; - my $old_host_key_public_key = $row->[1]; - my $old_host_key_user_name = $row->[2]; + my $old_ssh_key_host_uuid = $row->[0]; + my $old_ssh_key_public_key = $row->[1]; + my $old_ssh_key_user_name = $row->[2]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - old_host_key_host_uuid => $old_host_key_host_uuid, - old_host_key_public_key => $old_host_key_public_key, - old_host_key_user_name => $old_host_key_user_name, + old_ssh_key_host_uuid => $old_ssh_key_host_uuid, + old_ssh_key_public_key => $old_ssh_key_public_key, + old_ssh_key_user_name => $old_ssh_key_user_name, }}); # Anything change? - if (($old_host_key_host_uuid ne $host_key_host_uuid) or - ($old_host_key_public_key ne $host_key_public_key) or - ($old_host_key_user_name ne $host_key_user_name)) + if (($old_ssh_key_host_uuid ne $ssh_key_host_uuid) or + ($old_ssh_key_public_key ne $ssh_key_public_key) or + ($old_ssh_key_user_name ne $ssh_key_user_name)) { # Something changed, save. my $query = " UPDATE - host_keys + ssh_keys SET - host_key_host_uuid = ".$anvil->Database->quote($host_key_host_uuid).", - host_key_public_key = ".$anvil->Database->quote($host_key_public_key).", - host_key_user_name = ".$anvil->Database->quote($host_key_user_name).", + ssh_key_host_uuid = ".$anvil->Database->quote($ssh_key_host_uuid).", + ssh_key_public_key = ".$anvil->Database->quote($ssh_key_public_key).", + ssh_key_user_name = ".$anvil->Database->quote($ssh_key_user_name).", modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." WHERE - host_key_uuid = ".$anvil->Database->quote($host_key_uuid)." + ssh_key_uuid = ".$anvil->Database->quote($ssh_key_uuid)." "; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); @@ -4776,8 +4776,8 @@ WHERE } } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_key_uuid => $host_key_uuid }}); - return($host_key_uuid); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ssh_key_uuid => $ssh_key_uuid }}); + return($ssh_key_uuid); } @@ -4832,7 +4832,7 @@ This default value is the local host name. =head3 host_type (required) -This default value is the value returned by C<< System->get_host_type >>. +This default value is the value returned by C<< Get->host_type >>. =head3 host_uuid (required) @@ -4853,7 +4853,7 @@ sub insert_or_update_hosts my $host_ipmi = defined $parameter->{host_ipmi} ? $parameter->{host_ipmi} : ""; my $host_key = defined $parameter->{host_key} ? $parameter->{host_key} : ""; my $host_name = defined $parameter->{host_name} ? $parameter->{host_name} : $anvil->_host_name; - my $host_type = defined $parameter->{host_type} ? $parameter->{host_type} : $anvil->System->get_host_type; + my $host_type = defined $parameter->{host_type} ? $parameter->{host_type} : $anvil->Get->host_type; my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : $anvil->Get->host_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid, @@ -6269,11 +6269,9 @@ sub insert_or_update_manifests return(""); } - # If we don't have a network interface UUID, try to look one up using the MAC address + # If we don't have an install manifest UUID, try to look one up using the manifest name. if (not $manifest_uuid) { - # See if I know this NIC by referencing it's MAC and name. The name is needed because virtual - # devices can share the MAC with the real interface. my $query = " SELECT manifest_uuid, @@ -6398,6 +6396,13 @@ WHERE old_manifest_note => $old_manifest_note, }}); + # If we're here and 'manifest_last_ran' is am empty string, use the old value. + if ($manifest_last_ran eq "") + { + $manifest_last_ran = $old_manifest_last_ran; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { manifest_last_ran => $manifest_last_ran }}); + } + # Anything to update? This is a little extra complicated because if a variable was # not passed in, we want to not compare it. if (($manifest_name ne $old_manifest_name) or @@ -8817,7 +8822,7 @@ sub insert_or_update_variables my $variable_default = defined $parameter->{variable_default} ? $parameter->{variable_default} : ""; my $variable_description = defined $parameter->{variable_description} ? $parameter->{variable_description} : ""; my $variable_section = defined $parameter->{variable_section} ? $parameter->{variable_section} : ""; - my $variable_source_uuid = defined $parameter->{variable_source_uuid} ? $parameter->{variable_source_uuid} : ""; + my $variable_source_uuid = defined $parameter->{variable_source_uuid} ? $parameter->{variable_source_uuid} : "NULL"; my $variable_source_table = defined $parameter->{variable_source_table} ? $parameter->{variable_source_table} : ""; my $update_value_only = defined $parameter->{update_value_only} ? $parameter->{update_value_only} : 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { @@ -8870,7 +8875,7 @@ FROM variables WHERE variable_name = ".$anvil->Database->quote($variable_name); - if (($variable_source_uuid ne "") && ($variable_source_table ne "")) + if (($variable_source_uuid ne "NULL") && ($variable_source_table ne "")) { $query .= " AND @@ -8880,6 +8885,7 @@ AND "; } $query .= ";"; + $query =~ s/'NULL'/NULL/g; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); @@ -8949,6 +8955,7 @@ INSERT INTO ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." ); "; + $query =~ s/'NULL'/NULL/g; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); @@ -8965,7 +8972,7 @@ FROM variables WHERE variable_uuid = ".$anvil->Database->quote($variable_uuid); - if (($variable_source_uuid ne "") && ($variable_source_table ne "")) + if (($variable_source_uuid ne "NULL") && ($variable_source_table ne "")) { $query .= " AND @@ -8975,6 +8982,7 @@ AND "; } $query .= ";"; + $query =~ s/'NULL'/NULL/g; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); @@ -9010,7 +9018,7 @@ SET modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." WHERE variable_uuid = ".$anvil->Database->quote($variable_uuid); - if (($variable_source_uuid ne "") && ($variable_source_table ne "")) + if (($variable_source_uuid ne "NULL") && ($variable_source_table ne "")) { $query .= " AND @@ -9020,6 +9028,7 @@ AND "; } $query .= ";"; + $query =~ s/'NULL'/NULL/g; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); @@ -9035,12 +9044,15 @@ SELECT variable_value, variable_default, variable_description, - variable_section + variable_section, + variable_source_table, + variable_source_uuid FROM variables WHERE variable_uuid = ".$anvil->Database->quote($variable_uuid)." ;"; + $query =~ s/'NULL'/NULL/g; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); @@ -9057,40 +9069,49 @@ WHERE } foreach my $row (@{$results}) { - my $old_variable_name = $row->[0]; - my $old_variable_value = $row->[1]; - my $old_variable_default = $row->[2]; - my $old_variable_description = $row->[3]; - my $old_variable_section = $row->[4]; + my $old_variable_name = $row->[0]; + my $old_variable_value = $row->[1]; + my $old_variable_default = $row->[2]; + my $old_variable_description = $row->[3]; + my $old_variable_section = $row->[4]; + my $old_variable_source_table = $row->[5]; + my $old_variable_source_uuid = defined $row->[6] ? $row->[6] : ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - old_variable_name => $old_variable_name, - old_variable_value => $old_variable_value, - old_variable_default => $old_variable_default, - old_variable_description => $old_variable_description, - old_variable_section => $old_variable_section, + old_variable_name => $old_variable_name, + old_variable_value => $old_variable_value, + old_variable_default => $old_variable_default, + old_variable_description => $old_variable_description, + old_variable_section => $old_variable_section, + old_variable_source_table => $old_variable_source_table, + old_variable_source_uuid => $old_variable_source_uuid, }}); # Anything change? - if (($old_variable_name ne $variable_name) or - ($old_variable_value ne $variable_value) or - ($old_variable_default ne $variable_default) or - ($old_variable_description ne $variable_description) or - ($old_variable_section ne $variable_section)) + if (($old_variable_name ne $variable_name) or + ($old_variable_value ne $variable_value) or + ($old_variable_default ne $variable_default) or + ($old_variable_description ne $variable_description) or + ($old_variable_section ne $variable_section) or + ($old_variable_source_table ne $variable_source_table) or + ($old_variable_source_uuid ne $variable_source_uuid)) { # Something changed, save. my $query = " UPDATE variables SET - variable_name = ".$anvil->Database->quote($variable_name).", - variable_value = ".$anvil->Database->quote($variable_value).", - variable_default = ".$anvil->Database->quote($variable_default).", - variable_description = ".$anvil->Database->quote($variable_description).", - variable_section = ".$anvil->Database->quote($variable_section).", - modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." + variable_name = ".$anvil->Database->quote($variable_name).", + variable_value = ".$anvil->Database->quote($variable_value).", + variable_default = ".$anvil->Database->quote($variable_default).", + variable_description = ".$anvil->Database->quote($variable_description).", + variable_section = ".$anvil->Database->quote($variable_section).", + variable_source_table = ".$anvil->Database->quote($variable_source_table).", + variable_source_uuid = ".$anvil->Database->quote($variable_source_uuid).", + modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." WHERE - variable_uuid = ".$anvil->Database->quote($variable_uuid)." + variable_uuid = ".$anvil->Database->quote($variable_uuid)." "; + $query =~ s/'NULL'/NULL/g; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); @@ -10111,7 +10132,7 @@ sub read This reads a variable from the C<< variables >> table. Be sure to only use the reply from here to override what might have been set in a config file. This method always returns the data from the database itself. -The method returns an array reference containing, in order, the variable's value, database UUID and last modified date stamp. +The method returns an array reference containing, in order, the variable's value, database UUID and last modified date stamp in unix time (since epoch) and last as a normal time stamp. If anything goes wrong, C<< !!error!! >> is returned. If the variable didn't exist in the database, an empty string will be returned for the UUID, value and modified date. @@ -10167,7 +10188,8 @@ sub read_variable SELECT variable_value, variable_uuid, - round(extract(epoch from modified_date)) AS mtime + round(extract(epoch from modified_date)) AS mtime, + modified_date FROM variables WHERE "; @@ -10194,6 +10216,7 @@ AND $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0124", variables => { query => $query }}); my $variable_value = ""; + my $mtime = ""; my $modified_date = ""; my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__}); my $count = @{$results}; @@ -10205,10 +10228,12 @@ AND { $variable_value = $row->[0]; $variable_uuid = $row->[1]; - $modified_date = $row->[2]; + $mtime = $row->[2]; + $modified_date = $row->[3]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable_value => $variable_value, variable_uuid => $variable_uuid, + mtime => $mtime, modified_date => $modified_date, }}); } @@ -10216,9 +10241,10 @@ AND $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable_value => $variable_value, variable_uuid => $variable_uuid, + mtime => $mtime, modified_date => $modified_date, }}); - return($variable_value, $variable_uuid, $modified_date); + return($variable_value, $variable_uuid, $mtime, $modified_date); } diff --git a/Anvil/Tools/Get.pm b/Anvil/Tools/Get.pm index e86f82a5..69dca3e8 100644 --- a/Anvil/Tools/Get.pm +++ b/Anvil/Tools/Get.pm @@ -16,11 +16,16 @@ my $THIS_FILE = "Get.pm"; ### Methods; # anvil_version +# bridges # cgi # date_and_time +# free_memory +# host_type # host_uuid # md5sum +# os_type # switches +# uptime # users_home # uuid # _salt @@ -239,6 +244,98 @@ fi; return($version); } +=head2 bridges + +This finds a list of bridges on the host. Bridges that are found are stored is ' + +=cut +sub bridges +{ + 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 => "Get->bridges()" }}); + + my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{bridge}." -json -details link show"}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + output => $output, + return_code => $return_code, + }}); + + # Delete any previously known data + if (exists $anvil->data->{'local'}{network}{bridges}) + { + delete $anvil->data->{'local'}{network}{bridges}; + }; + + my $json = JSON->new->allow_nonref; + my $bridge_data = $json->decode($output); + #print Dumper $bridge_data; + foreach my $hash_ref (@{$bridge_data}) + { + # If the ifname and master are the same, it's a bridge. + my $type = "interface"; + my $interface = $hash_ref->{ifname}; + my $master_bridge = $hash_ref->{master}; + if ($interface eq $master_bridge) + { + $type = "bridge"; + $anvil->data->{'local'}{network}{bridges}{bridge}{$interface}{found} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "local::network::bridges::bridge::${interface}::found" => $anvil->data->{'local'}{network}{bridges}{bridge}{$interface}{found}, + }}); + } + else + { + # Store this interface under the bridge. + $anvil->data->{'local'}{network}{bridges}{bridge}{$master_bridge}{connected_interface}{$interface} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "local::network::bridges::bridge::${master_bridge}::connected_interface::${interface}" => $anvil->data->{'local'}{network}{bridges}{bridge}{$master_bridge}{connected_interface}{$interface}, + }}); + } + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + interface => $interface, + master_bridge => $master_bridge, + type => $type, + }}); + foreach my $key (sort {$a cmp $b} keys %{$hash_ref}) + { + if (ref($hash_ref->{$key}) eq "ARRAY") + { + $anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key} = []; + foreach my $value (sort {$a cmp $b} @{$hash_ref->{$key}}) + { + push @{$anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key}}, $value; + } + for (my $i = 0; $i < @{$anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key}}; $i++) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "local::network::bridges::${type}::${interface}::${key}->[$i]" => $anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key}->[$i], + }}); + } + } + else + { + $anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key} = $hash_ref->{$key}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "local::network::bridges::${type}::${interface}::${key}" => $anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key}, + }}); + } + } + } + + # Summary of found bridges. + foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{'local'}{network}{bridges}{bridge}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "local::network::bridges::bridge::${interface}::found" => $anvil->data->{'local'}{network}{bridges}{bridge}{$interface}{found}, + }}); + } + + return(0); +} + =head2 cgi This reads in the CGI variables passed in by a form or URL. @@ -561,6 +658,142 @@ WHERE return($host_name); } +=head2 free_memory + +This returns, in bytes, host much free memory is available on the local system. + +=cut +### TODO: Make this work on remote systems. +sub free_memory +{ + 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 => "Get->free_memory()" }}); + + my $available = 0; + my ($free_output, $free_rc) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{free}." --bytes"}); + foreach my $line (split/\n/, $free_output) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); + if ($line =~ /Mem:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/) + { + my $total = $1; + my $used = $2; + my $free = $3; + my $shared = $4; + my $cache = $5; + $available = $6; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + total => $total." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $total})."})", + used => $used." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $used})."})", + free => $free." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $free})."})", + shared => $shared." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $shared})."})", + cache => $cache." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $cache})."})", + available => $available." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $available})."})", + }}); + } + } + + return($available); +} + +=head2 host_type + +This method tries to determine the host type and returns a value suitable for use is the C<< hosts >> table. + + my $type = $anvil->System->host_type(); + +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 to see if the file C<< /etc/anvil/type.X >> exists, where C<< X >> is C<< node >>, C<< striker >> or C<< dr >>. If found, the appropriate type is returned. + +If that file doesn't exist, then it then checks to see which C<< anvil- >> rpm is installed. In order, it looks for C<< anvil-striker >>, then C<< anvil-node >> and finally C<< anvil-dr >>. If one of them is found, the appropriate C<< /etc/anvil/type.X >> is created. + +=cut +sub host_type +{ + 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 => "Get->host_type()" }}); + + my $host_type = ""; + my $host_name = $anvil->_short_host_name; + $host_type = "unknown"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + host_type => $host_type, + host_name => $host_name, + "sys::host_type" => $anvil->data->{sys}{host_type}, + }}); + + if ($anvil->data->{sys}{host_type}) + { + $host_type = $anvil->data->{sys}{host_type}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); + } + else + { + # Can I determine it by seeing a file? + if (-e $anvil->data->{path}{configs}{'type.node'}) + { + $host_type = "node"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); + } + elsif (-e $anvil->data->{path}{configs}{'type.striker'}) + { + $host_type = "striker"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); + } + elsif (-e $anvil->data->{path}{configs}{'type.dr'}) + { + $host_type = "dr"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); + } + else + { + # Last gasp here is to use 'rpm' to see which RPMs are installed. If we find one, + # we'll touch 'type.X' file + foreach my $rpm ("anvil-striker", "anvil-node", "anvil-dr") + { + my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{rpm}." -q ".$rpm}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { output => $output, return_code => $return_code }}); + if ($return_code eq "0") + { + # Found out what we are. + if ($rpm eq "anvil-striker") + { + $host_type = "striker"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); + } + + my $key = "type.".$host_type; + my $file = $anvil->data->{path}{configs}{$key}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + key => $key, + file => $file, + }}); + # If we have a file and we're root, touch to the file. + if (($file) && (($< == 0) or ($> == 0))) + { + my $error = $anvil->Storage->write_file({ + debug => $debug, + body => "", + file => $file, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => { error => $error }}); + } + last; + } + } + } + } + + return($host_type); +} + =head2 host_uuid This returns the local host's system UUID (as reported by 'dmidecode'). If the host UUID isn't available, and the program is not running with root priviledges, C<< #!error!# >> is returned. @@ -704,6 +937,68 @@ sub md5sum return($sum); } +=head2 os_type + +This returns the operating system type and the system architecture as two separate string variables. + + # Run on RHEL 8, on a 64-bit system + my ($os_type, $os_arch) = $anvil->Get->os_type(); + + # '$os_type' holds 'rhel8' ('rhel' or 'centos' + release version) + # '$os_arch' holds 'x86_64' (specifically, 'uname --hardware-platform') + +If either can not be determined, C<< unknown >> will be returned. + +This method takes no parameters. + +=cut +sub get_os_type +{ + 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 => "Get->os_type()" }}); + + my $os_type = "unknown"; + my $os_arch = "unknown"; + + ### NOTE: Examples; + # Red Hat Enterprise Linux release 8.0 Beta (Ootpa) + # Red Hat Enterprise Linux Server release 7.5 (Maipo) + # CentOS Linux release 7.5.1804 (Core) + + # Read in the /etc/redhat-release file + my $release = $anvil->Storage->read_file({file => $anvil->data->{path}{data}{'redhat-release'}}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { release => $release }}); + if ($release =~ /Red Hat Enterprise Linux .* (\d+)\./) + { + # RHEL, with the major version number appended + $os_type = "rhel".$1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { os_type => $os_type }}); + } + elsif ($release =~ /CentOS .*? (\d+)\./) + { + # CentOS, with the major version number appended + $os_type = "centos".$1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { os_type => $os_type }}); + } + + my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{uname}." --hardware-platform"}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { output => $output, return_code => $return_code }}); + if ($output) + { + $os_arch = $output; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { os_arch => $os_arch }}); + } + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + os_type => $os_type, + os_arch => $os_arch, + }}); + return($os_type, $os_arch); +} + =head2 switches This reads in the command line switches used to invoke the parent program. @@ -784,6 +1079,38 @@ sub switches return(0); } +=head2 uptime + +This returns, in seconds, how long the host has been up and running for. + +This method takes no parameters. + +=cut +### TODO: Make this work on remote hosts +sub uptime +{ + 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 => "Get->uptime()" }}); + + my $uptime = $anvil->Storage->read_file({ + force_read => 1, + cache => 0, + file => $anvil->data->{path}{proc}{uptime}, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uptime => $uptime }}); + + # Clean it up. We'll have gotten two numbers, the uptime in seconds (to two decimal places) and the + # total idle time. We only care about the int number. + $uptime =~ s/^(\d+)\..*$/$1/; + $uptime =~ s/\n//gs; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uptime => $uptime }}); + + return($uptime); +} + =head2 users_home This method takes a user's name and returns the user's home directory. If the home directory isn't found, C<< 0 >> is returned. diff --git a/Anvil/Tools/Server.pm b/Anvil/Tools/Server.pm index 703dadd4..a318a6b0 100755 --- a/Anvil/Tools/Server.pm +++ b/Anvil/Tools/Server.pm @@ -226,7 +226,7 @@ sub find delete $anvil->data->{server}{location}; } - my $host_type = $anvil->System->get_host_type({debug => $debug}); + my $host_type = $anvil->Get->host_type({debug => $debug}); my $host = $anvil->_host_name; my $virsh_output = ""; my $return_code = ""; diff --git a/Anvil/Tools/Striker.pm b/Anvil/Tools/Striker.pm index 308cd36a..cb51c820 100644 --- a/Anvil/Tools/Striker.pm +++ b/Anvil/Tools/Striker.pm @@ -186,7 +186,7 @@ sub generate_manifest { my $host_name = $node1_name; if ($machine eq "node2") { $host_name = $node2_name; } - elsif ($machine eq "dr1") { $host_name = $dr1_name; } + elsif ($machine eq "dr1") { $host_name = $dr1_name; } $manifest_xml .= ' <'.$machine.' name="'.$host_name.'" ipmi_ip="'.$machines->{$machine}{ipmi_ip}.'"> '; @@ -967,7 +967,7 @@ WHERE foreach my $machine (sort {$a cmp $b} keys %{$parsed_xml->{machines}}) { $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{name} = $parsed_xml->{machines}{$machine}{name}; - $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ipmi_ip} = $parsed_xml->{machines}{$machine}{ipmi_ip}; + $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ipmi_ip} = defined $parsed_xml->{machines}{$machine}{ipmi_ip} ? $parsed_xml->{machines}{$machine}{ipmi_ip} : ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "manifests::manifest_uuid::${manifest_uuid}::parsed::machine::${machine}::type" => $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{type}, "manifests::manifest_uuid::${manifest_uuid}::parsed::machine::${machine}::ipmi_ip" => $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ipmi_ip}, @@ -975,7 +975,7 @@ WHERE foreach my $hash_ref (@{$parsed_xml->{machines}{$machine}{fences}{fence}}) { - my $fence_name = $hash_ref->{name}; + my $fence_name = $hash_ref->{name}; $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{fence}{$fence_name}{port} = $hash_ref->{port}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "manifests::manifest_uuid::${manifest_uuid}::parsed::machine::${machine}::fence::${fence_name}::port" => $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{fence}{$fence_name}{port}, @@ -984,7 +984,7 @@ WHERE foreach my $hash_ref (@{$parsed_xml->{machines}{$machine}{upses}{ups}}) { - my $ups_name = $hash_ref->{name}; + my $ups_name = $hash_ref->{name}; $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ups}{$ups_name}{used} = $hash_ref->{used}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "manifests::manifest_uuid::${manifest_uuid}::parsed::machine::${machine}::ups::${ups_name}::used" => $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ups}{$ups_name}{used}, @@ -993,7 +993,7 @@ WHERE foreach my $hash_ref (@{$parsed_xml->{machines}{$machine}{networks}{network}}) { - my $network_name = $hash_ref->{name}; + my $network_name = $hash_ref->{name}; $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{network}{$network_name}{ip} = $hash_ref->{ip}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "manifests::manifest_uuid::${manifest_uuid}::parsed::machine::${machine}::network::${network_name}::ip" => $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{network}{$network_name}{ip}, diff --git a/Anvil/Tools/System.pm b/Anvil/Tools/System.pm index e1bba77f..dc54f755 100644 --- a/Anvil/Tools/System.pm +++ b/Anvil/Tools/System.pm @@ -11,6 +11,7 @@ use Time::HiRes qw(gettimeofday tv_interval); use Proc::Simple; use NetAddr::IP; use JSON; +use Text::Diff; our $VERSION = "3.0.0"; my $THIS_FILE = "System.pm"; @@ -26,13 +27,9 @@ my $THIS_FILE = "System.pm"; # disable_daemon # enable_daemon # find_matching_ip -# get_bridges -# get_free_memory -# get_host_type -# get_uptime -# get_os_type # host_name # maintenance_mode +# manage_authorized_keys # manage_firewall # read_ssh_config # reload_daemon @@ -615,6 +612,373 @@ sub check_memory return($used_ram); } + +=head2 check_ssh_keys + +This method does several things; + +1. This makes sure the users on this system have SSH keys, and creates the keys if needed. +2. It records the user's keys in the C<< ssh_keys >> table. +3. For the dashboard machines it uses, it adds their host machine public key (SSH fingerprint) to C<< ~/.ssh/known_hosts >>. +4. If this machine is a node or DR host, it sets up passwordless SSH between the other machines in the same Anvil! system. + +This works on the C<< admin >> and C<< root >> users. If the host is a node, it will also work on the c<< hacluster >> user. + +B<< Note >>: If a machine's fingerprint changes, this method will NOT update C<< ~/.ssh/known_hosts >>! You will see an alert on the Striker dashboard prompting you to clear the bad keys (or, if that wasn't expected, find the "man in the middle" attacker). + +This method takes no parameters. + +=cut +sub check_ssh_keys +{ + 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 => "System->check_memory()" }}); + + # We do a couple things here. First we make sure our user's keys are up to date and stored in the + # 'ssh_keys' table. Then we look through the 'trusts' table for any other users@hosts we're supposed + # to trust. For each, we make sure that they're in the appropriate local user's authorized_keys file. + my $users = $anvil->Get->host_type eq "node" ? ["root", "admin", "hacluster"] : ["root", "admin"]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { users => \@{$users} }}); + + # Get a list of machine host keys and user public keys from other machines. + #get_other_keys($anvil); + + # Users to check: + foreach my $user (@{$users}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { user => $user }}); + + my $user_home = $anvil->Get->users_home({user => $user}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { user_home => $user_home }}); + + # If the user doesn't exist, their home directory won't either, so skip. + next if not $user_home; + next if not -d $user_home; + + # If the user's ~/.ssh directory doesn't exist, we need to create it. + my $ssh_directory = $user_home."/.ssh"; + $ssh_directory =~ s/\/\//\//g; + if (not -e $ssh_directory) + { + # Create it. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0272", variables => { user => $user, directory => $ssh_directory }}); + $anvil->Storage->make_directory({ + debug => $debug, + directory => $ssh_directory, + user => $user, + group => $user, + mode => "0700", + }); + if (not -e $ssh_directory) + { + # Failed ? + next; + } + } + + my $ssh_private_key_file = $user_home."/.ssh/id_rsa"; + my $ssh_public_key_file = $user_home."/.ssh/id_rsa.pub"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + ssh_public_key_file => $ssh_public_key_file, + ssh_private_key_file => $ssh_private_key_file, + }}); + if (not -e $ssh_public_key_file) + { + # Generate the SSH keys. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0270", variables => { user => $user }}); + + my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{'ssh-keygen'}." -t rsa -N \"\" -b 8191 -f ".$ssh_private_key_file}); + if (-e $ssh_public_key_file) + { + # Success! + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0271", variables => { user => $user, output => $output }}); + } + else + { + # Failed? + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "error_0057", variables => { user => $user, output => $output }}); + next; + } + } + + # Now read in the key. + my $users_public_key = $anvil->Storage->read_file({ + debug => $debug, + file => $ssh_public_key_file, + }); + $users_public_key =~ s/\n$//; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { users_public_key => $users_public_key }}); + + # Now store the key in the 'ssh_key' table, if needed. + my $ssh_key_uuid = $anvil->Database->insert_or_update_ssh_keys({ + debug => $debug, + ssh_key_host_uuid => $anvil->Get->host_uuid, + ssh_key_public_key => $users_public_key, + ssh_key_user_name => $user, + }); + + # Read in the existing 'known_hosts' file, if it exists. The 'old' and 'new' variables will + # be used when looking for needed changes. + my $known_hosts_file_body = ""; + my $known_hosts_old_body = ""; + my $known_hosts_new_body = ""; + my $known_hosts_file = $ssh_directory."/known_hosts"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { known_hosts_file => $known_hosts_file }}); + if (-e $known_hosts_file) + { + $known_hosts_file_body = $anvil->Storage->read_file({ + debug => $debug, + file => $known_hosts_file, + }); + $known_hosts_old_body = $known_hosts_file_body; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { known_hosts_file_body => $known_hosts_file_body }}); + } + + # Read in the existing 'authorized_keys' file, if it exists. + my $authorized_keys_file_body = ""; + my $authorized_keys_old_body = ""; + my $authorized_keys_new_body = ""; + my $authorized_keys_file = $ssh_directory."/authorized_keys"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { authorized_keys_file => $authorized_keys_file }}); + if (-e $authorized_keys_file) + { + $authorized_keys_file_body = $anvil->Storage->read_file({ + debug => $debug, + file => $authorized_keys_file, + }); + $authorized_keys_old_body = $authorized_keys_file_body; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { authorized_keys_file_body => $authorized_keys_file_body }}); + } + + ### Walk through each host we now know of. As we we do, loop through the old file body to see + ### if it exists. If it does, and the key has changed, update the line with the new key. If + ### it isn't found, add it. Once we check the old body for this entry, change the "old" body + ### to the new one, then repeat the process. + + # Look at all the hosts I know about (other than myself) and see if any of the machine or + # user keys either don't exist or have changed. + my $update_known_hosts = 0; + my $update_authorized_keys = 0; + my $known_hosts_new_lines = ""; + my $authorized_keys_new_lines = ""; + + # Check for changes to known_hosts + foreach my $host_uuid (keys %{$anvil->data->{peers}{ssh_keys}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid }}); + foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{peers}{ssh_keys}{$host_uuid}{host}}) + { + my $key = $anvil->data->{peers}{ssh_keys}{$host_uuid}{host}{$host_name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + 's1:host_name' => $host_name, + 's2:key' => $key, + }}); + + # Is this in the file and, if so, has it changed? + my $found = 0; + my $test_line = $host_name." ".$key; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { test_line => $test_line }}); + foreach my $line (split/\n/, $known_hosts_old_body) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }}); + if ($line eq $test_line) + { + # No change needed, key is the same. + $found = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { found => $found }}); + } + elsif ($line =~ /^$host_name /) + { + # Key has changed, update. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0274", variables => { + machine => $host_name, + old_key => $line, + new_key => $test_line, + + }}); + $found = 1; + $line = $test_line; + $update_known_hosts = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + found => $found, + line => $line, + update_known_hosts => $update_known_hosts, + }}); + } + $known_hosts_new_body .= $line."\n"; + } + # If we didn't find the key, add it. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { found => $found }}); + if (not $found) + { + $update_known_hosts = 1; + $known_hosts_new_lines .= $test_line."\n"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + 's1:update_known_hosts' => $update_known_hosts, + 's2:known_hosts_new_lines' => $known_hosts_new_lines, + }}); + } + + # Move the new body over to the old body (even though it may not have + # changed) and then clear the new body to prepare for the next pass. + $known_hosts_old_body = $known_hosts_new_body; + $known_hosts_new_body = ""; + } + } + + # Lastly, copy the last version of the old body to the new body, + $known_hosts_new_body = $known_hosts_old_body.$known_hosts_new_lines; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + 's1:update_known_hosts' => $update_known_hosts, + 's2:known_hosts_file_body' => $known_hosts_file_body, + 's3:known_hosts_new_body' => $known_hosts_new_body, + 's4:difference' => diff \$known_hosts_file_body, \$known_hosts_new_body, { STYLE => 'Unified' }, + }}); + + + ### TODO: Change this to not use all hosts, but on dashboards we use, plus if we're in an Anvil!, those machines. + +=cut + # Check for changes to authorized_keys + foreach my $host_uuid (keys %{$anvil->data->{peers}{ssh_keys}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid }}); + foreach my $ssh_key_user_name (sort {$a cmp $b} keys %{$anvil->data->{peers}{ssh_keys}{$host_uuid}{user}}) + { + my $ssh_key_public_key = $anvil->data->{peers}{ssh_keys}{$host_uuid}{user}{$ssh_key_user_name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + 's1:ssh_key_user_name' => $ssh_key_user_name, + 's2:ssh_key_public_key' => $ssh_key_public_key, + }}); + + # The key in the file might have a different trailing suffix (user@host_name) + # and doesn't really matter. So we search by the key type and public key to + # see if it exists already. + my $found = 0; + my $test_line = ($ssh_key_public_key =~ /^(ssh-.*? .*?) /)[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { test_line => $test_line }}); + foreach my $line (split/\n/, $authorized_keys_old_body) + { + # NOTE: Use '\Q...\E' so that the '+' characters in the key aren't + # evaluated as part of the regex. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }}); + if ($line =~ /^\Q$test_line\E/) + { + # No change needed, key is the same. + $found = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { found => $found }}); + } + # We don't look for changes (yet). Might be worth looking for stale + # keys by ckecking of the host at the end matches an entry in the + # database and then verifying the keys haven't changed, but that's + # for another day. + $authorized_keys_new_body .= $line."\n"; + } + # If we didn't find the key, add it. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { found => $found }}); + if (not $found) + { + $update_authorized_keys = 1; + $authorized_keys_new_lines .= $ssh_key_public_key."\n"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + 's1:update_authorized_keys' => $update_authorized_keys, + 's2:authorized_keys_new_lines' => $authorized_keys_new_lines, + }}); + } + + # Move the new body over to the old body (even though it may not have + # changed) and then clear the new body to prepare for the next pass. + $authorized_keys_old_body = $authorized_keys_new_body; + $authorized_keys_new_body = ""; + } + } + + # Lastly, copy the last version of the old body to the new body, + $authorized_keys_new_body = $authorized_keys_old_body.$authorized_keys_new_lines; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + 's1:update_authorized_keys' => $update_authorized_keys, + 's2:authorized_keys_file_body' => $authorized_keys_file_body, + 's3:authorized_keys_new_body' => $authorized_keys_new_body, + 's4:difference' => diff \$authorized_keys_file_body, \$authorized_keys_new_body, { STYLE => 'Unified' }, + }}); +=cut + + # Update the known_hosts files, if needed. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { update_known_hosts => $update_known_hosts }}); + if ($update_known_hosts) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0273", variables => { user => $user, file => $known_hosts_file }}); + if (-e $known_hosts_file) + { + my $backup_file = $anvil->Storage->backup({ + debug => $debug, + fatal => 1, + file => $known_hosts_file, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { backup_file => $backup_file }}); + if (-e $backup_file) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0154", variables => { source_file => $known_hosts_file, target_file => $backup_file }}); + } + else + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "error_0058", variables => { file => $known_hosts_file }}); + } + } + my $failed = $anvil->Storage->write_file({ + debug => $debug, + overwrite => 1, + file => $known_hosts_file, + body => $known_hosts_new_body, + user => $user, + group => $user, + mode => "0644", + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { failed => $failed }}); + } + + # Update the authorized_keys files, if needed. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { update_authorized_keys => $update_authorized_keys }}); + if ($update_authorized_keys) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0273", variables => { user => $user, file => $authorized_keys_file }}); + if (-e $authorized_keys_file) + { + my $backup_file = $anvil->Storage->backup({ + debug => $debug, + fatal => 1, + file => $authorized_keys_file, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { backup_file => $backup_file }}); + if (-e $backup_file) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0154", variables => { source_file => $authorized_keys_file, target_file => $backup_file }}); + } + else + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "error_0058", variables => { file => $authorized_keys_file }}); + } + } + my $failed = $anvil->Storage->write_file({ + debug => $debug, + overwrite => 1, + file => $authorized_keys_file, + body => $authorized_keys_new_body, + user => $user, + group => $user, + mode => "0644", + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { failed => $failed }}); + } + } + + return(0); +} + + =head2 check_storage Thic gathers LVM data from the local system. @@ -1240,139 +1604,6 @@ sub generate_state_json return(0); } -=head2 get_bridges - -This finds a list of bridges on the host. Bridges that are found are stored is ' - -=cut -sub get_bridges -{ - 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 => "System->get_bridges()" }}); - - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{bridge}." -json -details link show"}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - output => $output, - return_code => $return_code, - }}); - - # Delete any previously known data - if (exists $anvil->data->{'local'}{network}{bridges}) - { - delete $anvil->data->{'local'}{network}{bridges}; - }; - - my $json = JSON->new->allow_nonref; - my $bridge_data = $json->decode($output); - #print Dumper $bridge_data; - foreach my $hash_ref (@{$bridge_data}) - { - # If the ifname and master are the same, it's a bridge. - my $type = "interface"; - my $interface = $hash_ref->{ifname}; - my $master_bridge = $hash_ref->{master}; - if ($interface eq $master_bridge) - { - $type = "bridge"; - $anvil->data->{'local'}{network}{bridges}{bridge}{$interface}{found} = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "local::network::bridges::bridge::${interface}::found" => $anvil->data->{'local'}{network}{bridges}{bridge}{$interface}{found}, - }}); - } - else - { - # Store this interface under the bridge. - $anvil->data->{'local'}{network}{bridges}{bridge}{$master_bridge}{connected_interface}{$interface} = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "local::network::bridges::bridge::${master_bridge}::connected_interface::${interface}" => $anvil->data->{'local'}{network}{bridges}{bridge}{$master_bridge}{connected_interface}{$interface}, - }}); - } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - interface => $interface, - master_bridge => $master_bridge, - type => $type, - }}); - foreach my $key (sort {$a cmp $b} keys %{$hash_ref}) - { - if (ref($hash_ref->{$key}) eq "ARRAY") - { - $anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key} = []; - foreach my $value (sort {$a cmp $b} @{$hash_ref->{$key}}) - { - push @{$anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key}}, $value; - } - for (my $i = 0; $i < @{$anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key}}; $i++) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "local::network::bridges::${type}::${interface}::${key}->[$i]" => $anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key}->[$i], - }}); - } - } - else - { - $anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key} = $hash_ref->{$key}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "local::network::bridges::${type}::${interface}::${key}" => $anvil->data->{'local'}{network}{bridges}{$type}{$interface}{$key}, - }}); - } - } - } - - # Summary of found bridges. - foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{'local'}{network}{bridges}{bridge}}) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - "local::network::bridges::bridge::${interface}::found" => $anvil->data->{'local'}{network}{bridges}{bridge}{$interface}{found}, - }}); - } - - return(0); -} - -=head2 get_free_memory - -This returns, in bytes, host much free memory is available on the local system. - -=cut -### TODO: Make this work on remote systems. -sub get_free_memory -{ - 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 => "System->get_free_memory()" }}); - - my $available = 0; - my ($free_output, $free_rc) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{free}." --bytes"}); - foreach my $line (split/\n/, $free_output) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); - if ($line =~ /Mem:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/) - { - my $total = $1; - my $used = $2; - my $free = $3; - my $shared = $4; - my $cache = $5; - $available = $6; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - total => $total." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $total})."})", - used => $used." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $used})."})", - free => $free." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $free})."})", - shared => $shared." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $shared})."})", - cache => $cache." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $cache})."})", - available => $available." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $available})."})", - }}); - } - } - - return($available); -} - =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. @@ -1492,175 +1723,6 @@ sub find_matching_ip return($local_ip); } -=head2 get_host_type - -This method tries to determine the host type and returns a value suitable for use is the C<< hosts >> table. - - my $type = $anvil->System->get_host_type(); - -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 to see if the file C<< /etc/anvil/type.X >> exists, where C<< X >> is C<< node >>, C<< dashboard >> or C<< dr >>. If found, the appropriate type is returned. - -If that file doesn't exist, then it looks at the short host name. The following rules are used, in order; - -1. If the host name ends in C<< n >> or C<< node >>, C<< node >> is returned. -2. If the host name ends in C<< striker >> or C<< dashboard >>, C<< dashboard >> is returned. -3. If the host name ends in C<< dr >>, C<< dr >> is returned. - -=cut -sub get_host_type -{ - 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 => "System->get_host_type()" }}); - - my $host_type = ""; - my $host_name = $anvil->_short_host_name; - $host_type = "unknown"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - host_type => $host_type, - host_name => $host_name, - "sys::host_type" => $anvil->data->{sys}{host_type}, - }}); - if ($anvil->data->{sys}{host_type}) - { - $host_type = $anvil->data->{sys}{host_type}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); - } - else - { - # Can I determine it by seeing a file? - if (-e $anvil->data->{path}{configs}{'type.node'}) - { - $host_type = "node"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); - } - elsif (-e $anvil->data->{path}{configs}{'type.dashboard'}) - { - $host_type = "dashboard"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); - } - elsif (-e $anvil->data->{path}{configs}{'type.dr'}) - { - $host_type = "dr"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); - } - elsif (($host_name =~ /n\d+$/) or ($host_name =~ /node\d+$/) or ($host_name =~ /new-node+$/)) - { - $host_type = "node"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); - } - elsif (($host_name =~ /striker\d+$/) or ($host_name =~ /dashboard\d+$/)) - { - $host_type = "dashboard"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); - } - elsif (($host_name =~ /dr\d+$/) or ($host_name =~ /new-dr$/)) - { - $host_type = "dr"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }}); - } - } - - return($host_type); -} - -=head2 get_uptime - -This returns, in seconds, how long the host has been up and running for. - -This method takes no parameters. - -=cut -sub get_uptime -{ - 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 => "System->get_uptime()" }}); - - my $uptime = $anvil->Storage->read_file({ - force_read => 1, - cache => 0, - file => $anvil->data->{path}{proc}{uptime}, - }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uptime => $uptime }}); - - # Clean it up. We'll have gotten two numbers, the uptime in seconds (to two decimal places) and the - # total idle time. We only care about the int number. - $uptime =~ s/^(\d+)\..*$/$1/; - $uptime =~ s/\n//gs; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uptime => $uptime }}); - - return($uptime); -} - -=head2 get_os_type - -This returns the operating system type and the system architecture as two separate string variables. - - # Run on RHEL 8, on a 64-bit system - my ($os_type, $os_arch) = $anvil->System->get_os_type(); - - # '$os_type' holds 'rhel8' ('rhel' or 'centos' + release version) - # '$os_arch' holds 'x86_64' (specifically, 'uname --hardware-platform') - -If either can not be determined, C<< unknown >> will be returned. - -This method takes no parameters. - -=cut -sub get_os_type -{ - 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 => "System->get_os_type()" }}); - - my $os_type = "unknown"; - my $os_arch = "unknown"; - - ### NOTE: Examples; - # Red Hat Enterprise Linux release 8.0 Beta (Ootpa) - # Red Hat Enterprise Linux Server release 7.5 (Maipo) - # CentOS Linux release 7.5.1804 (Core) - - # Read in the /etc/redhat-release file - my $release = $anvil->Storage->read_file({file => $anvil->data->{path}{data}{'redhat-release'}}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { release => $release }}); - if ($release =~ /Red Hat Enterprise Linux .* (\d+)\./) - { - # RHEL, with the major version number appended - $os_type = "rhel".$1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { os_type => $os_type }}); - } - elsif ($release =~ /CentOS .*? (\d+)\./) - { - # CentOS, with the major version number appended - $os_type = "centos".$1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { os_type => $os_type }}); - } - - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{uname}." --hardware-platform"}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { output => $output, return_code => $return_code }}); - if ($output) - { - $os_arch = $output; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { os_arch => $os_arch }}); - } - - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - os_type => $os_type, - os_arch => $os_arch, - }}); - return($os_type, $os_arch); -} - =head2 host_name Get or set the local host name. The current (or new) "static" (traditional) host name and the "pretty" (descriptive) host names are returned. @@ -1967,7 +2029,7 @@ sub check_firewall 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 => "System->manage_firewall()" }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "System->check_firewall()" }}); # Show live or permanent rules? Permanent is default my $permanent = defined $parameter->{permanent} ? $parameter->{permanent} : 1; @@ -2086,6 +2148,70 @@ sub check_firewall return(0); } +=head2 manage_authorized_keys + +This takes a host's UUID and will adds or removes their ssh public key to the target host user (or users). On success, C<< 0 >> is returned. Otherwise, C<< 1 >> is returned. + +Parameters; + +=head3 host_uuid (required) + +This is the C<< hosts >> -> C<< host_uuid >> whose key we're adding or removing. When adding, the C<< + +=head3 password (optional) + +This is the password to use when connecting to a remote machine. If not set, but C<< target >> is, an attempt to connect without a password will be made. + +=head3 port (optional) + +This is the TCP port to use when connecting to a remote machine. If not set, but C<< target >> is, C<< 22 >> will be used. + +=head3 remote_user (optional, default root) + +If C<< target >> is set, this will be the user we connect to the remote machine as. + +=head3 target (optional, default 'local') + +This is the IP or host name of the machine to manage keys on. If not passed, the keys on the local machine will be managed. + +=head3 users (optional) + +This is a comma separated list of users whose keys are being managed. If not set, the default on Striker and DR Hosts is C<< root,admin >> and on nodes it is C<< root,admin,hacluster >>. + +=cut +sub manage_authorized_keys +{ + 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 => "System->manage_authorized_keys()" }}); + + my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : ""; + my $password = defined $parameter->{password} ? $parameter->{password} : ""; + my $port = defined $parameter->{port} ? $parameter->{port} : ""; + my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : "root"; + my $target = defined $parameter->{target} ? $parameter->{target} : ""; + my $users = defined $parameter->{users} ? $parameter->{users} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + target => $target, + port => $port, + remote_user => $remote_user, + password => $anvil->Log->is_secure($password), + users => $users, + }}); + + if (not $users) + { + $users = $anvil->Striker->get_host_type eq "node" ? "root,admin,hacluster" : "root,admin"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { users => $users }}); + } + + + + return(0); +} + =head2 manage_firewall This method manages a firewalld firewall. diff --git a/cgi-bin/striker b/cgi-bin/striker index dea1c9b0..1d162d6e 100755 --- a/cgi-bin/striker +++ b/cgi-bin/striker @@ -1572,7 +1572,7 @@ sub run_manifest $anvil->data->{cgi}{password}{value} = "" if not defined $anvil->data->{cgi}{password}{value}; $anvil->data->{cgi}{password}{alert} = 0 if not defined $anvil->data->{cgi}{password}{alert}; - $anvil->Database->get_hosts(); + $anvil->Database->get_hosts({debug => 2}); my $manifest_uuid = $anvil->data->{cgi}{manifest_uuid}{value}; my $problem = $anvil->Striker->load_manifest({ debug => 2, @@ -1671,15 +1671,15 @@ sub run_manifest } # Check that the machines selected didn't get added to another anvil while looking. - my $node1_host_name = $anvil->data->{cgi}{node1_host}{value}; - my $node1_host_uuid = $anvil->data->{sys}{hosts}{by_name}{$node1_host_name}; + my $node1_host_uuid = $anvil->data->{cgi}{node1_host}{value}; + my $node1_host_name = $anvil->data->{sys}{hosts}{by_uuid}{$node1_host_uuid}; my $node1_anvil = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{anvil_name}; - my $node2_host_name = $anvil->data->{cgi}{node2_host}{value}; - my $node2_host_uuid = $anvil->data->{sys}{hosts}{by_name}{$node2_host_name}; + my $node2_host_uuid = $anvil->data->{cgi}{node2_host}{value}; + my $node2_host_name = $anvil->data->{sys}{hosts}{by_uuid}{$node2_host_uuid}; my $node2_anvil = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{anvil_name}; - my $dr1_host_name = $anvil->data->{cgi}{dr1_host}{value}; - my $dr1_host_uuid = $dr1_host_name ? $anvil->data->{sys}{hosts}{by_name}{$dr1_host_name} : ""; - my $dr1_anvil = $dr1_host_name ? $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}{anvil_name} : ""; + my $dr1_host_uuid = $anvil->data->{cgi}{dr1_host}{value}; + my $dr1_host_name = $dr1_host_uuid ? $anvil->data->{sys}{hosts}{by_uuid}{$dr1_host_uuid} : ""; + my $dr1_anvil = $dr1_host_uuid ? $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}{anvil_name} : ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node1_host_name => $node1_host_name, node1_host_uuid => $node1_host_uuid, @@ -1753,7 +1753,7 @@ sub run_manifest line => __LINE__, job_host_uuid => $node1_host_uuid, job_command => $anvil->data->{path}{exe}{'anvil-join-anvil'}, - job_data => "as_machine=node1,manifest_uuid=".$manifest_uuid, + job_data => "as_machine=node1,manifest_uuid=".$manifest_uuid.",node1_host_uuid=".$node1_host_uuid.",node2_host_uuid=".$node2_host_uuid.",dr1_host_uuid=".$dr1_host_uuid, job_name => "join_anvil::node1", job_title => "job_0072", job_description => "job_0073", @@ -1767,7 +1767,7 @@ sub run_manifest line => __LINE__, job_host_uuid => $node2_host_uuid, job_command => $anvil->data->{path}{exe}{'anvil-join-anvil'}, - job_data => "as_machine=node2,manifest_uuid=".$manifest_uuid, + job_data => "as_machine=node2,manifest_uuid=".$manifest_uuid.",node1_host_uuid=".$node1_host_uuid.",node2_host_uuid=".$node2_host_uuid.",dr1_host_uuid=".$dr1_host_uuid, job_name => "join_anvil::node2", job_title => "job_0072", job_description => "job_0073", @@ -1783,7 +1783,7 @@ sub run_manifest line => __LINE__, job_host_uuid => $dr1_host_uuid, job_command => $anvil->data->{path}{exe}{'anvil-join-anvil'}, - job_data => "as_machine=dr1,manifest_uuid=".$manifest_uuid, + job_data => "as_machine=dr1,manifest_uuid=".$manifest_uuid.",node1_host_uuid=".$node1_host_uuid.",node2_host_uuid=".$node2_host_uuid.",dr1_host_uuid=".$dr1_host_uuid, job_name => "join_anvil::dr1", job_title => "job_0072", job_description => "job_0073", @@ -1800,7 +1800,7 @@ sub run_manifest return(0); } } - + # Ask the user to choose the targets and confirm the manifest settings. my $nodes = []; my $dr_hosts = []; @@ -1829,27 +1829,27 @@ sub run_manifest if ($host_type eq "node") { - push @{$nodes}, $host_name; + push @{$nodes}, $host_uuid."#!#".$host_name; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }}); if ((not defined $anvil->data->{cgi}{node1_host}{value}) && ($host_name eq $node1_name)) { - $anvil->data->{cgi}{node1_host}{value} = $host_name; + $anvil->data->{cgi}{node1_host}{value} = $host_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node1_host::value" => $anvil->data->{cgi}{node1_host}{value} }}); } elsif ((not defined $anvil->data->{cgi}{node2_host}{value}) && ($host_name eq $node2_name)) { - $anvil->data->{cgi}{node2_host}{value} = $host_name; + $anvil->data->{cgi}{node2_host}{value} = $host_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node2_host::value" => $anvil->data->{cgi}{node2_host}{value} }}); } } elsif ($host_type eq "dr") { - push @{$dr_hosts}, $host_name; + push @{$dr_hosts}, $host_uuid."#!#".$host_name; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }}); if ((not defined $anvil->data->{cgi}{dr1_host}{value}) && ($host_name eq $dr1_name)) { - $anvil->data->{cgi}{dr1_host}{value} = $host_name; + $anvil->data->{cgi}{dr1_host}{value} = $host_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::dr1_host::value" => $anvil->data->{cgi}{dr1_host}{value} }}); } } @@ -1857,7 +1857,9 @@ sub run_manifest # We're going to need three selects; one for each node and one for DR. The DR is allowed to # be unselected so it has an empty entry. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node1_host::value" => $anvil->data->{cgi}{node1_host}{value} }}); my $select_node1 = $anvil->Template->select_form({ + debug => 2, name => "node1_host", options => $nodes, blank => 0, @@ -1866,8 +1868,11 @@ sub run_manifest class => $anvil->data->{cgi}{node1_host}{alert} ? "input_alert" : "input_clear", style => "", }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { select_node1 => $select_node1 }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node2_host::value" => $anvil->data->{cgi}{node2_host}{value} }}); my $select_node2 = $anvil->Template->select_form({ + debug => 2, name => "node2_host", options => $nodes, blank => 0, @@ -1876,8 +1881,11 @@ sub run_manifest class => $anvil->data->{cgi}{node2_host}{alert} ? "input_alert" : "input_clear", style => "", }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { select_node2 => $select_node2 }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::dr1_host::value" => $anvil->data->{cgi}{dr1_host}{value} }}); my $select_dr1 = $anvil->Template->select_form({ + debug => 2, name => "dr1_host", options => $dr_hosts, blank => 1, @@ -1886,6 +1894,7 @@ sub run_manifest class => $anvil->data->{cgi}{dr1_host}{alert} ? "input_alert" : "input_clear", style => "", }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { select_dr1 => $select_dr1 }}); # Show the networks. my $networks = ""; @@ -2274,17 +2283,17 @@ sub handle_manifest if (not $anvil->data->{cgi}{ifn_count}{value}) { - $anvil->data->{cgi}{ifn_count}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{ifn_count}; + $anvil->data->{cgi}{ifn_count}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{ifn}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::ifn_count::value" => $anvil->data->{cgi}{ifn_count}{value} }}); } if (not $anvil->data->{cgi}{sn_count}{value}) { - $anvil->data->{cgi}{sn_count}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{sn_count}; + $anvil->data->{cgi}{sn_count}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{sn}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::sn_count::value" => $anvil->data->{cgi}{sn_count}{value} }}); } if (not $anvil->data->{cgi}{bcn_count}{value}) { - $anvil->data->{cgi}{bcn_count}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{bcn_count}; + $anvil->data->{cgi}{bcn_count}{value} = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{bcn}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::bcn_count::value" => $anvil->data->{cgi}{bcn_count}{value} }}); } } @@ -6570,9 +6579,21 @@ sub configure_striker { # Sanity check step1. my $sane = sanity_check_step1($anvil); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { sane => $sane }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }}); if ($sane) { + # We're mapping, so tell anvil-daemon to + $anvil->Database->insert_or_update_variables({ + debug => 2, + variable_name => "config::map_network", + variable_value => 1, + variable_default => 0, + variable_description => "striker_0202", + variable_section => "config", + variable_source_uuid => $anvil->Get->host_uuid, + variable_source_table => "hosts", + }); + # Step 1 was sane, show step 2. $anvil->data->{form}{body} = config_step2($anvil); } @@ -6586,9 +6607,21 @@ sub configure_striker { # Sanity check step1. my $sane = sanity_check_step2($anvil); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { sane => $sane }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }}); if ($sane) { + # Also, we're done mapping + $anvil->Database->insert_or_update_variables({ + debug => 2, + variable_name => "config::map_network", + variable_value => 0, + variable_default => 0, + variable_description => "striker_0202", + variable_section => "config", + variable_source_uuid => $anvil->Get->host_uuid, + variable_source_table => "hosts", + }); + # Step 2 was sane, show step 3. $anvil->data->{form}{body} = config_step3($anvil); } diff --git a/notes b/notes index 85a86abf..f1918884 100644 --- a/notes +++ b/notes @@ -42,37 +42,6 @@ DOCS; - ==== -dnf download --source awscli booth booth-arbitrator booth-core booth-site booth-test corosync corosync-qdevice corosync-qnetd corosynclib-devel fence-agents-aliyun fence-agents-aws fence-agents-azure-arm fence-agents-gce libknet1 \ - libknet1-compress-bzip2-plugin libknet1-compress-lz4-plugin libknet1-compress-lzma-plugin libknet1-compress-lzo2-plugin libknet1-compress-plugins-all libknet1-compress-zlib-plugin libknet1-crypto-nss-plugin \ - libknet1-crypto-openssl-plugin libknet1-crypto-plugins-all libknet1-plugins-all pacemaker pacemaker-cli pacemaker-cts pacemaker-doc pacemaker-libs-devel pacemaker-nagios-plugins-metadata pacemaker-remote \ - pcs pcs-snmp python3-azure-sdk python3-boto3 python3-botocore python3-fasteners python3-gflags python3-google-api-client python3-httplib2 python3-oauth2client python3-s3transfer python3-uritemplate \ - resource-agents resource-agents-aliyun resource-agents-gcp - -rpm -Uvh python-s3transfer-0.1.13-1.el8.src.rpm python-oauth2client-4.1.2-6.el8.src.rpm booth-1.0-5.f2d38ce.git.el8.src.rpm google-api-python-client-1.6.5-3.el8.src.rpm python-boto3-1.6.1-2.el8.src.rpm python-httplib2-0.10.3-4.el8.src.rpm python-botocore-1.9.1-2.el8.src.rpm corosync-qdevice-3.0.0-2.el8.src.rpm python-uritemplate-3.0.0-3.el8.src.rpm python3-azure-sdk-4.0.0-9.el8.src.rpm awscli-1.14.50-5.el8.src.rpm python-gflags-2.0-15.el8ost.src.rpm resource-agents-4.1.1-33.el8.src.rpm pcs-0.10.2-4.el8.src.rpm fence-agents-4.2.1-30.el8_1.1.src.rpm -rpm -Uvh python-fasteners-0.14.1-15.el8ost.src.rpm - -rpm -Uvh awscli-1.14.50-5.el8.src.rpm booth-1.0-5.f2d38ce.git.el8.src.rpm corosync-qdevice-3.0.0-2.el8.src.rpm fence-agents-4.2.1-30.el8.1.src.rpm google-api-python-client-1.6.5-3.el8.src.rpm pacemaker-2.0.2-3.el8.2.src.rpm \ - pcs-0.10.2-4.el8.src.rpm python-boto3-1.6.1-2.el8.src.rpm python-botocore-1.9.1-2.el8.src.rpm python-gflags-2.0-15.el8.src.rpm python-httplib2-0.10.3-4.el8.src.rpm python-oauth2client-4.1.2-6.el8.src.rpm \ - python-s3transfer-0.1.13-1.el8.src.rpm python-uritemplate-3.0.0-3.el8.src.rpm python3-azure-sdk-4.0.0-9.el8.src.rpm resource-agents-4.1.1-33.el8.src.rpm - - - -rpmbuild -ba --sign pcs.spec -rpmbuild -ba --sign python3-azure-sdk.spec -rpmbuild -ba --sign python-s3transfer.spec python-oauth2client.spec booth.spec google-api-python-client.spec python-boto3.spec python-httplib2.spec python-botocore.spec corosync-qdevice.spec python-uritemplate.spec awscli.spec python-gflags.spec resource-agents.spec fence-agents.spec - -# rpmbuild -ba python-fasteners.spec - - -### Need to find/build -python2-futures -python2-monotonic - - -dnf install booth-site corosync corosynclib-devel pacemaker pacemaker-cli pacemaker-libs-devel pcs - - - Network planning; 10.x.y.z / 255.255.0.0 @@ -252,219 +221,6 @@ hosts: 10.255.22.1 m3-a02dr01.ifn ==== -### Interface files -# -# Note: Insert the HWADDR's and update the IPs! -# -### BCN ####################################################################### -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-BCN_1_-_Link_1 << EOF -# Back-Channel Network 1 - Link 1 -HWADDR="" -UUID="${UUID}" -NAME="BCN 1 - Link 1" -DEVICE="bcn1_link1" -TYPE="Ethernet" -BOOTPROTO="none" -IPV6INIT="no" -ONBOOT="yes" -USERCTL="no" -MTU="1500" -NM_CONTROLLED="yes" -SLAVE="yes" -MASTER="bcn1_bond1" -ZONE="BCN1" -EOF - -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-BCN_1_-_Link_2 << EOF -# Back-Channel Network 1 - Link 2 -HWADDR="" -UUID="${UUID}" -NAME="BCN 1 - Link 2" -DEVICE="bcn1_link2" -TYPE="Ethernet" -BOOTPROTO="none" -IPV6INIT="no" -ONBOOT="yes" -USERCTL="no" -MTU="1500" -NM_CONTROLLED="yes" -SLAVE="yes" -MASTER="bcn1_bond1" -ZONE="BCN1" -EOF - -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-BCN_1_-_Bond_1 << EOF -# Back-Channel Network 1 - Bond 1 -UUID="${UUID}" -NAME="BCN 1 - Bond 1" -DEVICE="bcn1_bond1" -BRIDGE="bcn1_bridge1" -BONDING_OPTS="mode=active-backup primary=bcn1_link1 updelay=120000 downdelay=0 miimon=100 primary_reselect=better" -TYPE="Bond" -BONDING_MASTER="yes" -BOOTPROTO="none" -IPV6INIT="no" -ONBOOT="yes" -ZONE="BCN1" -EOF - -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-BCN_1_-_Bridge_1 << EOF -# Back-Channel Network 1 - Bridge 1 -UUID="${UUID}" -STP="yes" -BRIDGING_OPTS="priority=32768" -TYPE="Bridge" -BROWSER_ONLY="no" -NAME="BCN 1 - Bridge 1" -DEVICE="bcn1_bridge1" -ONBOOT="yes" -BOOTPROTO="none" -IPADDR="10.20.10.1" -PREFIX="16" -DEFROUTE="no" -ZONE="BCN1" -EOF - -### SN ######################################################################## -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-SN_1_-_Link_1 << EOF -# Storage Network 1 - Link 1 -HWADDR="" -UUID="${UUID}" -NAME="SN 1 - Link 1" -DEVICE="sn1_link1" -TYPE="Ethernet" -BOOTPROTO="none" -IPV6INIT="no" -ONBOOT="yes" -USERCTL="no" -MTU="1500" -NM_CONTROLLED="yes" -SLAVE="yes" -MASTER="sn1_bond1" -ZONE="SN1" -EOF - -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-SN_1_-_Link_2 << EOF -# Storage Network 1 - Link 2 -HWADDR="" -UUID="${UUID}" -NAME="SN 1 - Link 2" -DEVICE="sn1_link2" -TYPE="Ethernet" -BOOTPROTO="none" -IPV6INIT="no" -ONBOOT="yes" -USERCTL="no" -MTU="1500" -NM_CONTROLLED="yes" -SLAVE="yes" -MASTER="sn1_bond1" -ZONE="SN1" -EOF - -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-SN_1_-_Bond_1 << EOF -# Storage Network 1 - Bond 1 -UUID="${UUID}" -NAME="SN 1 - Bond 1" -DEVICE="sn1_bond1" -BONDING_OPTS="mode=active-backup primary=sn1_link1 updelay=120000 downdelay=0 miimon=100 primary_reselect=better" -TYPE="Bond" -BONDING_MASTER="yes" -BOOTPROTO="none" -IPV6INIT="no" -ONBOOT="yes" -IPADDR="10.41.10.1" -PREFIX="16" -DEFROUTE="no" -ZONE="SN1" -EOF - -### IFN ####################################################################### -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-IFN_1_-_Link_1 << EOF -# Internet-Facing Network 1 - Link 1 -HWADDR="" -UUID="${UUID}" -NAME="IFN 1 - Link 1" -DEVICE="ifn1_link1" -TYPE="Ethernet" -BOOTPROTO="none" -IPV6INIT="no" -ONBOOT="yes" -USERCTL="no" -MTU="1500" -NM_CONTROLLED="yes" -SLAVE="yes" -MASTER="ifn1_bond1" -ZONE="IFN1" -EOF - -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-IFN_1_-_Link_2 << EOF -# Internet-Facing Network 1 - Link 2 -HWADDR="" -UUID="${UUID}" -NAME="IFN 1 - Link 2" -DEVICE="ifn1_link2" -TYPE="Ethernet" -BOOTPROTO="none" -IPV6INIT="no" -ONBOOT="yes" -USERCTL="no" -MTU="1500" -NM_CONTROLLED="yes" -SLAVE="yes" -MASTER="ifn1_bond1" -ZONE="IFN1" -EOF - -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-IFN_1_-_Bond_1 << EOF -# Internet-Facing Network 1 - Bond 1 -UUID="${UUID}" -NAME="IFN 1 - Bond 1" -DEVICE="ifn1_bond1" -BRIDGE="ifn1_bridge1" -BONDING_OPTS="mode=active-backup primary=ifn1_link1 updelay=120000 downdelay=0 miimon=100 primary_reselect=better" -TYPE="Bond" -BONDING_MASTER="yes" -BOOTPROTO="none" -IPV6INIT="no" -ONBOOT="yes" -MTU="1500" -ZONE="IFN1" -EOF - -UUID=$(uuidgen) -cat > /etc/sysconfig/network-scripts/ifcfg-IFN_1_-_Bridge_1 << EOF -# Internet-Facing Network 1 - Bridge 1 -UUID="${UUID}" -STP="yes" -BRIDGING_OPTS="priority=32768" -TYPE="Bridge" -BROWSER_ONLY="no" -NAME="IFN 1 - Bridge 1" -DEVICE="ifn1_bridge1" -ONBOOT="yes" -BOOTPROTO="none" -IPADDR="10.255.10.1" -PREFIX="16" -GATEWAY="10.255.255.254" -DNS1="8.8.8.8" -DNS2="8.8.4.4" -DEFROUTE="yes" -ZONE="IFN1" -EOF - -==== - ======= virt-manager stores information in dconf-editor -> /org/virt-manager/virt-manager/connections ($HOME/.config/dconf/user) @@ -481,30 +237,6 @@ restorecon -rv /var/www ============================================================= -How to rebuild all of the packages in the Alteeve RHEL 8 repo; - -# Register if RHEL proper; -subscription-manager register --username --password --auto-attach --force - -subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-source-rpms -subscription-manager repos --enable rhel-8-for-x86_64-supplementary-source-rpms -subscription-manager repos --enable rhel-8-for-x86_64-baseos-rpms -subscription-manager repos --enable rhel-8-for-x86_64-appstream-source-rpms -subscription-manager repos --enable rhel-8-for-x86_64-supplementary-rpms -subscription-manager repos --enable rhel-8-for-x86_64-baseos-source-rpms -subscription-manager repos --enable rhel-8-for-x86_64-highavailability-source-rpms -subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-rpms -subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms -subscription-manager repos --enable rhel-8-for-x86_64-appstream-rpms - -repos => { - 'rhel-8-for-x86_64-highavailability-rpms' => 0, - 'codeready-builder-for-rhel-8-x86_64-rpms' => 0, -} - - -* Packages to install; - * Network; ** {bc,if,s}nX_{link,bond,bridge}Y naming ** firewall; - https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/high_availability_add-on_reference/s1-firewalls-haar @@ -512,6 +244,7 @@ firewall-cmd --permanent --add-service=high-availability firewall-cmd --add-service=high-availability firewall-cmd --reload + * Cluster Config; ==== Both nodes echo Initial1 | passwd hacluster --stdin diff --git a/ocf/alteeve/server b/ocf/alteeve/server index ea9569ec..5601bf6b 100755 --- a/ocf/alteeve/server +++ b/ocf/alteeve/server @@ -947,7 +947,7 @@ sub validate_bridges my ($anvil) = @_; # Get my bridge list - $anvil->System->get_bridges({debug => 3}); + $anvil->Get->bridges({debug => 3}); # Find the Optical drives and DRBD devices. my $server = $anvil->data->{environment}{OCF_RESKEY_name}; @@ -1190,7 +1190,7 @@ sub validate_ram # How mcuh RAM does the server need and how much do we have free? my $server = $anvil->data->{environment}{OCF_RESKEY_name}; my $server_ram_bytes = $anvil->data->{server}{'local'}{$server}{from_disk}{memory}; - my $available = $anvil->System->get_free_memory({debug => 3}); + my $available = $anvil->Get->free_memory({debug => 3}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { server_ram_bytes => $anvil->Convert->add_commas({number => $server_ram_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram_bytes}).")", available => $anvil->Convert->add_commas({number => $available})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $available}).")", diff --git a/rpm/SPECS/anvil.spec b/rpm/SPECS/anvil.spec index 0c7c3200..814c6dad 100644 --- a/rpm/SPECS/anvil.spec +++ b/rpm/SPECS/anvil.spec @@ -247,7 +247,7 @@ elif [ -e '/etc/anvil/type.dr' ] then rm -f /etc/anvil/type.dr fi -touch /etc/anvil/type.dashboard +touch /etc/anvil/type.striker ### TODO: I don't think we need this anymore @@ -266,9 +266,9 @@ firewall-cmd --add-service=postgresql --permanent %post node # Touch the system type file. echo "Touching the system type file" -if [ -e '/etc/anvil/type.dashboard' ] +if [ -e '/etc/anvil/type.striker' ] then - rm -f /etc/anvil/type.dashboard + rm -f /etc/anvil/type.striker elif [ -e '/etc/anvil/type.dr' ] then rm -f /etc/anvil/type.dr @@ -282,9 +282,9 @@ touch /etc/anvil/type.node %post dr # Touch the system type file. echo "Touching the system type file" -if [ -e '/etc/anvil/type.dashboard' ] +if [ -e '/etc/anvil/type.striker' ] then - rm -f /etc/anvil/type.dashboard + rm -f /etc/anvil/type.striker elif [ -e '/etc/anvil/type.node' ] then rm -f /etc/anvil/type.node @@ -318,9 +318,9 @@ touch /etc/anvil/type.dr # systemctl stop postgresql.service # Remove the system type file. -if [ -e '/etc/anvil/type.dashboard' ] +if [ -e '/etc/anvil/type.striker' ] then - rm -f /etc/anvil/type.dashboard + rm -f /etc/anvil/type.striker fi %postun node diff --git a/share/anvil.sql b/share/anvil.sql index 8f8fa3ec..a07fa7fe 100644 --- a/share/anvil.sql +++ b/share/anvil.sql @@ -97,60 +97,60 @@ CREATE TRIGGER trigger_hosts -- This stores the SSH _public_keys for a given user on a host. -CREATE TABLE host_keys ( - host_key_uuid uuid not null primary key, -- This is the single most important record in Anvil!. Everything links back to here. - host_key_host_uuid uuid not null, - host_key_user_name text not null, -- This is the user name on the system, not a web interface user. - host_key_public_key text not null, -- Either 'node', 'dashboard' or 'dr' +CREATE TABLE ssh_keys ( + ssh_key_uuid uuid not null primary key, + ssh_key_host_uuid uuid not null, + ssh_key_user_name text not null, -- This is the user name on the system, not a web interface user. + ssh_key_public_key text not null, -- Either 'node', 'dashboard' or 'dr' modified_date timestamp with time zone not null, - FOREIGN KEY(host_key_host_uuid) REFERENCES hosts(host_uuid) + FOREIGN KEY(ssh_key_host_uuid) REFERENCES hosts(host_uuid) ); -ALTER TABLE host_keys OWNER TO admin; +ALTER TABLE ssh_keys OWNER TO admin; -CREATE TABLE history.host_keys ( +CREATE TABLE history.ssh_keys ( history_id bigserial, - host_key_uuid uuid, - host_key_host_uuid uuid, - host_key_user_name text, - host_key_public_key text, + ssh_key_uuid uuid, + ssh_key_host_uuid uuid, + ssh_key_user_name text, + ssh_key_public_key text, modified_date timestamp with time zone not null ); -ALTER TABLE history.host_keys OWNER TO admin; +ALTER TABLE history.ssh_keys OWNER TO admin; -CREATE FUNCTION history_host_keys() RETURNS trigger +CREATE FUNCTION history_ssh_keys() RETURNS trigger AS $$ DECLARE - history_host_keys RECORD; + history_ssh_keys RECORD; BEGIN - SELECT INTO history_host_keys * FROM host_keys WHERE host_key_uuid = new.host_key_uuid; - INSERT INTO history.host_keys - (host_key_uuid, - host_key_host_uuid, - host_key_user_name, - host_key_public_key, + SELECT INTO history_ssh_keys * FROM ssh_keys WHERE ssh_key_uuid = new.ssh_key_uuid; + INSERT INTO history.ssh_keys + (ssh_key_uuid, + ssh_key_host_uuid, + ssh_key_user_name, + ssh_key_public_key, modified_date) VALUES - (history_host_keys.host_key_uuid, - history_host_keys.host_key_host_uuid, - history_host_keys.host_key_user_name, - history_host_keys.host_key_public_key, - history_host_keys.modified_date); + (history_ssh_keys.ssh_key_uuid, + history_ssh_keys.ssh_key_host_uuid, + history_ssh_keys.ssh_key_user_name, + history_ssh_keys.ssh_key_public_key, + history_ssh_keys.modified_date); RETURN NULL; END; $$ LANGUAGE plpgsql; -ALTER FUNCTION history_host_keys() OWNER TO admin; +ALTER FUNCTION history_ssh_keys() OWNER TO admin; -CREATE TRIGGER trigger_host_keys - AFTER INSERT OR UPDATE ON host_keys - FOR EACH ROW EXECUTE PROCEDURE history_host_keys(); +CREATE TRIGGER trigger_ssh_keys + AFTER INSERT OR UPDATE ON ssh_keys + FOR EACH ROW EXECUTE PROCEDURE history_ssh_keys(); -- This stores information about users. -- Note that is all permissions are left false, the user can still interact with the Anvil! doing safe things, like changing optical media, perform migrations, start servers (but not stop them), etc. CREATE TABLE users ( - user_uuid uuid not null primary key, -- This is the single most important record in Anvil!. Everything links back to here. + user_uuid uuid not null primary key, user_name text not null, user_password_hash text not null, -- A user without a password is disabled. user_salt text not null, -- This is used to enhance the security of the user's password. @@ -223,7 +223,7 @@ CREATE TRIGGER trigger_users -- This stores special variables for a given host that programs may want to record. CREATE TABLE host_variable ( - host_variable_uuid uuid not null primary key, -- This is the single most important record in ScanCore. Everything links back to here. + host_variable_uuid uuid not null primary key, host_variable_host_uuid uuid not null, host_variable_name text not null, host_variable_value text not null, @@ -274,7 +274,7 @@ CREATE TRIGGER trigger_host_variable -- This stores user session information on a per-dashboard basis. CREATE TABLE sessions ( - session_uuid uuid not null primary key, -- This is the single most important record in Anvil!. Everything links back to here. + session_uuid uuid not null primary key, session_host_uuid uuid not null, -- This is the host uuid for this session. session_user_uuid uuid not null, -- This is the user uuid for the user logging in. session_salt text not null, -- This is used when generating a session hash for a session when they log in. @@ -642,7 +642,7 @@ CREATE TABLE variables ( variable_default text not null, -- This acts as a reference for the user should they want to roll-back changes. variable_description text not null, -- This is a string key that describes this variable's use. variable_section text not null, -- This is a free-form field that is used when displaying the various entries to a user. This allows for the various variables to be grouped into sections. - variable_source_uuid text not null, -- Optional; Marks the variable as belonging to a specific X_uuid, where 'X' is a table name set in 'variable_source_table' + variable_source_uuid uuid, -- Optional; Marks the variable as belonging to a specific X_uuid, where 'X' is a table name set in 'variable_source_table' variable_source_table text not null, -- Optional; Marks the database table corresponding to the 'variable_source_uuid' value. modified_date timestamp with time zone not null ); @@ -656,7 +656,7 @@ CREATE TABLE history.variables ( variable_default text, variable_description text, variable_section text, - variable_source_uuid text, + variable_source_uuid uuid, variable_source_table text, modified_date timestamp with time zone not null ); diff --git a/tools/anvil-configure-host b/tools/anvil-configure-host index c2bc4222..e677a9bd 100755 --- a/tools/anvil-configure-host +++ b/tools/anvil-configure-host @@ -168,7 +168,7 @@ sub reconfigure_network my $sn_count = exists $anvil->data->{variables}{form}{config_step1}{sn_count}{value} ? $anvil->data->{variables}{form}{config_step1}{sn_count}{value} : 0; my $ifn_count = exists $anvil->data->{variables}{form}{config_step1}{ifn_count}{value} ? $anvil->data->{variables}{form}{config_step1}{ifn_count}{value} : 1; my $new_host_name = exists $anvil->data->{variables}{form}{config_step2}{host_name}{value} ? $anvil->data->{variables}{form}{config_step2}{host_name}{value} : ""; - my $type = $anvil->System->get_host_type(); + my $type = $anvil->Get->host_type(); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, list => { prefix => $prefix, sequence => $sequence, @@ -182,7 +182,7 @@ sub reconfigure_network }}); # If we're configuring a dashboard and no host name was given, generate it. - if (($type eq "dashboard") && (not $new_host_name)) + if (($type eq "striker") && (not $new_host_name)) { $new_host_name = $prefix."-striker".sprintf("%02d", $sequence).".".$domain; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, list => { new_host_name => $new_host_name }}); @@ -191,7 +191,7 @@ sub reconfigure_network if ($new_host_name) { my $type_name = ""; - if ($type eq "dashboard") + if ($type eq "striker") { $type_name = $anvil->Words->string({key => "brand_0003"}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, list => { type_name => $type_name }}); diff --git a/tools/anvil-daemon b/tools/anvil-daemon index 0a0866c9..a7484856 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -81,7 +81,7 @@ if (not $anvil->data->{sys}{database}{connections}) { # If this is a dashboard, try to configure and then connect to the local database. If this isn't a # dashboard, then just go into a loop waiting for a database to be configured. - if ($anvil->System->get_host_type eq "dashboard") + if ($anvil->Get->host_type eq "striker") { $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0201"}); prep_database($anvil); @@ -232,21 +232,25 @@ sub check_if_mapping $anvil->data->{sys}{mapping_network} = 0; if ($anvil->data->{sys}{database}{connections}) { - my ($map_network_value, $map_network_uuid, $map_network_modified_date) = $anvil->Database->read_variable({ + my ($map_network_value, $map_network_uuid, $map_network_mtime, $map_network_modified_date) = $anvil->Database->read_variable({ + debug => 3, variable_name => "config::map_network", variable_source_table => "hosts", variable_source_uuid => $anvil->data->{sys}{host_uuid}, }); - my $expire_age = 1200; + # We'll run for a day (should be cancelled by the program when the user's done, so this + # shouldn't fire in practice). + my $expire_age = 86400; my $map_network_age = 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 's1:map_network_value' => $map_network_value, - 's2:map_network_modified_date' => $map_network_modified_date, - 's3:map_network_uuid' => $map_network_uuid, + 's2:map_network_mtime' => $map_network_mtime, + 's3:map_network_modified_date' => $map_network_modified_date, + 's4:map_network_uuid' => $map_network_uuid, }}); if ($map_network_uuid) { - $map_network_age = time - $map_network_modified_date; + $map_network_age = time - $map_network_mtime; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { map_network_age => $map_network_age }}); } if ($map_network_value) @@ -255,7 +259,7 @@ sub check_if_mapping if ($map_network_age >= $expire_age) { # Clear it. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0470"}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0470"}); $anvil->Database->insert_or_update_variables({ debug => 3, variable_value => 0, @@ -268,7 +272,7 @@ sub check_if_mapping # Mark it so we only track the network. my $say_age = $anvil->Convert->add_commas({number => $expire_age}); my $timeout = $anvil->Convert->add_commas({number => ($expire_age - $map_network_age)}); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0471", variables => { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0471", variables => { age => $say_age, timeout => $timeout, }}); @@ -280,7 +284,7 @@ sub check_if_mapping foreach my $ssh_fh_key (keys %{$anvil->data->{cache}{ssh_fh}}) { my $ssh_fh = $anvil->data->{cache}{ssh_fh}{$ssh_fh_key}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { ssh_fh_key => $ssh_fh_key, ssh_fh => $ssh_fh, }}); @@ -304,9 +308,9 @@ sub set_delay my ($anvil) = @_; my $delay = 7200; - my $type = $anvil->System->get_host_type(); + my $type = $anvil->Get->host_type(); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { type => $type }}); - if ($type eq "dashboard") + if ($type eq "striker") { foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{database}}) { @@ -338,7 +342,7 @@ sub handle_periodic_tasks my ($anvil) = @_; my $now_time = time; - my $type = $anvil->System->get_host_type(); + my $type = $anvil->Get->host_type(); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "s1:now_time" => $now_time, "s2:timing::next_minute_check" => $anvil->data->{timing}{next_minute_check}, @@ -356,7 +360,7 @@ sub handle_periodic_tasks check_install_target($anvil); # Check that the users we care about have ssh public keys and they're recorded in ssh_keys. - check_ssh_keys($anvil); + $anvil->System->check_ssh_keys({debug => 3}); # Check if the files on disk have changed. Even if it is time to check, don't if a job is # running. @@ -378,7 +382,7 @@ sub handle_periodic_tasks }}); # If we're a dashboard, see if the fence information needs to be gathered. - if ($type eq "dashboard") + if ($type eq "striker") { # Even when this runs, it should finish in under ten seconds so we don't need to background it. my ($parse_output, $return_code) = $anvil->System->call({debug => 3, shell_call => $anvil->data->{path}{exe}{'striker-parse-fence-agents'}, source => $THIS_FILE, line => __LINE__}); @@ -429,7 +433,7 @@ sub handle_periodic_tasks ### NOTE: We call it once/day, but this will also trigger on restart of anvil-daemon. As such, we ### don't use '--force' and let striker-manage-install-target skip the repo update if it happened ### recently enough. - if ($type eq "dashboard") + if ($type eq "striker") { # Record a job, don't call it directly. It takes too long to run. my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ @@ -482,346 +486,6 @@ sub handle_periodic_tasks return(0); } -# Check that the host's fingerprint and users we care about have ssh public keys and they're recorded in ssh_keys. -sub check_ssh_keys -{ - my ($anvil) = @_; - - ### TODO: When a node is rebuilt, this causes the old keys to be reloaded between when we delete the entries. We need to delete the keys for the target IP from the 'ip_addresses' table. - return(0); - - - # Get a list of machine host keys and user public keys from other machines. - get_other_keys($anvil); - - # Users to check: - # root, admin, hacluster - foreach my $user ("root", "admin") - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { user => $user }}); - - my $user_home = $anvil->Get->users_home({user => $user}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { user_home => $user_home }}); - - # If the user doesn't exist, their home directory won't either, so skip. - next if not $user_home; - next if not -d $user_home; - - # If the user's ~/.ssh directory doesn't exist, we need to create it. - my $ssh_directory = $user_home."/.ssh"; - $ssh_directory =~ s/\/\//\//g; - if (not -e $ssh_directory) - { - # Create it. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0272", variables => { user => $user, directory => $ssh_directory }}); - $anvil->Storage->make_directory({ - debug => 3, - directory => $ssh_directory, - user => $user, - group => $user, - mode => "0700", - }); - if (not -e $ssh_directory) - { - # Failed ? - next; - } - } - - my $ssh_private_key_file = $user_home."/.ssh/id_rsa"; - my $ssh_public_key_file = $user_home."/.ssh/id_rsa.pub"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - ssh_public_key_file => $ssh_public_key_file, - ssh_private_key_file => $ssh_private_key_file, - }}); - if (not -e $ssh_public_key_file) - { - # Generate the SSH keys. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0270", variables => { user => $user }}); - - my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{'ssh-keygen'}." -t rsa -N \"\" -b 8191 -f ".$ssh_private_key_file}); - if (-e $ssh_public_key_file) - { - # Success! - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0271", variables => { user => $user, output => $output }}); - } - else - { - # Failed? - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "error_0057", variables => { user => $user, output => $output }}); - next; - } - } - - # Now read in the key. - my $users_public_key = $anvil->Storage->read_file({ - debug => 3, - file => $ssh_public_key_file, - }); - $users_public_key =~ s/\n$//; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { users_public_key => $users_public_key }}); - - # Now store the key in the 'host_key' table, if needed. - my $host_key_uuid = $anvil->Database->insert_or_update_host_keys({ - debug => 3, - host_key_host_uuid => $anvil->Get->host_uuid, - host_key_public_key => $users_public_key, - host_key_user_name => $user, - }); - - # Read in the existing 'known_hosts' file, if it exists. The 'old' and 'new' variables will - # be used when looking for needed changes. - my $known_hosts_file_body = ""; - my $known_hosts_old_body = ""; - my $known_hosts_new_body = ""; - my $known_hosts_file = $ssh_directory."/known_hosts"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { known_hosts_file => $known_hosts_file }}); - if (-e $known_hosts_file) - { - $known_hosts_file_body = $anvil->Storage->read_file({ - debug => 3, - file => $known_hosts_file, - }); - $known_hosts_old_body = $known_hosts_file_body; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { known_hosts_file_body => $known_hosts_file_body }}); - } - - # Read in the existing 'authorized_keys' file, if it exists. - my $authorized_keys_file_body = ""; - my $authorized_keys_old_body = ""; - my $authorized_keys_new_body = ""; - my $authorized_keys_file = $ssh_directory."/authorized_keys"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { authorized_keys_file => $authorized_keys_file }}); - if (-e $authorized_keys_file) - { - $authorized_keys_file_body = $anvil->Storage->read_file({ - debug => 3, - file => $authorized_keys_file, - }); - $authorized_keys_old_body = $authorized_keys_file_body; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { authorized_keys_file_body => $authorized_keys_file_body }}); - } - - ### Walk through each host we now know of. As we we do, loop through the old file body to see - ### if it exists. If it does, and the key has changed, update the line with the new key. If - ### it isn't found, add it. Once we check the old body for this entry, change the "old" body - ### to the new one, then repeat the process. - - # Look at all the hosts I know about (other than myself) and see if any of the machine or - # user keys either don't exist or have changed. - my $update_known_hosts = 0; - my $update_authorized_keys = 0; - my $known_hosts_new_lines = ""; - my $authorized_keys_new_lines = ""; - - # Check for changes to known_hosts - foreach my $host_uuid (keys %{$anvil->data->{peers}{ssh_keys}}) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { host_uuid => $host_uuid }}); - foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{peers}{ssh_keys}{$host_uuid}{host}}) - { - my $key = $anvil->data->{peers}{ssh_keys}{$host_uuid}{host}{$host_name}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - 's1:host_name' => $host_name, - 's2:key' => $key, - }}); - - # Is this in the file and, if so, has it changed? - my $found = 0; - my $test_line = $host_name." ".$key; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { test_line => $test_line }}); - foreach my $line (split/\n/, $known_hosts_old_body) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); - if ($line eq $test_line) - { - # No change needed, key is the same. - $found = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { found => $found }}); - } - elsif ($line =~ /^$host_name /) - { - # Key has changed, update. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0274", variables => { - machine => $host_name, - old_key => $line, - new_key => $test_line, - - }}); - $found = 1; - $line = $test_line; - $update_known_hosts = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - found => $found, - line => $line, - update_known_hosts => $update_known_hosts, - }}); - } - $known_hosts_new_body .= $line."\n"; - } - # If we didn't find the key, add it. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { found => $found }}); - if (not $found) - { - $update_known_hosts = 1; - $known_hosts_new_lines .= $test_line."\n"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - 's1:update_known_hosts' => $update_known_hosts, - 's2:known_hosts_new_lines' => $known_hosts_new_lines, - }}); - } - - # Move the new body over to the old body (even though it may not have - # changed) and then clear the new body to prepare for the next pass. - $known_hosts_old_body = $known_hosts_new_body; - $known_hosts_new_body = ""; - } - } - - # Lastly, copy the last version of the old body to the new body, - $known_hosts_new_body = $known_hosts_old_body.$known_hosts_new_lines; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - 's1:update_known_hosts' => $update_known_hosts, - 's2:known_hosts_file_body' => $known_hosts_file_body, - 's3:known_hosts_new_body' => $known_hosts_new_body, - 's4:difference' => diff \$known_hosts_file_body, \$known_hosts_new_body, { STYLE => 'Unified' }, - }}); - - # Check for changes to authorized_keys - foreach my $host_uuid (keys %{$anvil->data->{peers}{ssh_keys}}) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { host_uuid => $host_uuid }}); - foreach my $host_key_user_name (sort {$a cmp $b} keys %{$anvil->data->{peers}{ssh_keys}{$host_uuid}{user}}) - { - my $host_key_public_key = $anvil->data->{peers}{ssh_keys}{$host_uuid}{user}{$host_key_user_name}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - 's1:host_key_user_name' => $host_key_user_name, - 's2:host_key_public_key' => $host_key_public_key, - }}); - - # The key in the file might have a different trailing suffix (user@host_name) - # and doesn't really matter. So we search by the key type and public key to - # see if it exists already. - my $found = 0; - my $test_line = ($host_key_public_key =~ /^(ssh-.*? .*?) /)[0]; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { test_line => $test_line }}); - foreach my $line (split/\n/, $authorized_keys_old_body) - { - # NOTE: Use '\Q...\E' so that the '+' characters in the key aren't - # evaluated as part of the regex. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); - if ($line =~ /^\Q$test_line\E/) - { - # No change needed, key is the same. - $found = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { found => $found }}); - } - # We don't look for changes (yet). Might be worth looking for stale - # keys by ckecking of the host at the end matches an entry in the - # database and then verifying the keys haven't changed, but that's - # for another day. - $authorized_keys_new_body .= $line."\n"; - } - # If we didn't find the key, add it. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { found => $found }}); - if (not $found) - { - $update_authorized_keys = 1; - $authorized_keys_new_lines .= $host_key_public_key."\n"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - 's1:update_authorized_keys' => $update_authorized_keys, - 's2:authorized_keys_new_lines' => $authorized_keys_new_lines, - }}); - } - - # Move the new body over to the old body (even though it may not have - # changed) and then clear the new body to prepare for the next pass. - $authorized_keys_old_body = $authorized_keys_new_body; - $authorized_keys_new_body = ""; - } - } - - # Lastly, copy the last version of the old body to the new body, - $authorized_keys_new_body = $authorized_keys_old_body.$authorized_keys_new_lines; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - 's1:update_authorized_keys' => $update_authorized_keys, - 's2:authorized_keys_file_body' => $authorized_keys_file_body, - 's3:authorized_keys_new_body' => $authorized_keys_new_body, - 's4:difference' => diff \$authorized_keys_file_body, \$authorized_keys_new_body, { STYLE => 'Unified' }, - }}); - - # Update the known_hosts files, if needed. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { update_known_hosts => $update_known_hosts }}); - if ($update_known_hosts) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0273", variables => { user => $user, file => $known_hosts_file }}); - if (-e $known_hosts_file) - { - my $backup_file = $anvil->Storage->backup({ - debug => 3, - fatal => 1, - file => $known_hosts_file, - }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { backup_file => $backup_file }}); - if (-e $backup_file) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0154", variables => { source_file => $known_hosts_file, target_file => $backup_file }}); - } - else - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "error_0058", variables => { file => $known_hosts_file }}); - } - } - my $failed = $anvil->Storage->write_file({ - debug => 3, - overwrite => 1, - file => $known_hosts_file, - body => $known_hosts_new_body, - user => $user, - group => $user, - mode => "0644", - }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { failed => $failed }}); - } - - # Update the authorized_keys files, if needed. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { update_authorized_keys => $update_authorized_keys }}); - if ($update_authorized_keys) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0273", variables => { user => $user, file => $authorized_keys_file }}); - if (-e $authorized_keys_file) - { - my $backup_file = $anvil->Storage->backup({ - debug => 3, - fatal => 1, - file => $authorized_keys_file, - }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { backup_file => $backup_file }}); - if (-e $backup_file) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0154", variables => { source_file => $authorized_keys_file, target_file => $backup_file }}); - } - else - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "error_0058", variables => { file => $authorized_keys_file }}); - } - } - my $failed = $anvil->Storage->write_file({ - debug => 3, - overwrite => 1, - file => $authorized_keys_file, - body => $authorized_keys_new_body, - user => $user, - group => $user, - mode => "0644", - }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { failed => $failed }}); - } - } - - return(0); -} - # Get a list of machine host keys and user public keys from other machines. sub get_other_keys { @@ -902,13 +566,13 @@ WHERE # Now read in the public key for other users on other machines. $query = " SELECT - host_key_host_uuid, - host_key_user_name, - host_key_public_key + ssh_key_host_uuid, + ssh_key_user_name, + ssh_key_public_key FROM - host_keys + ssh_keys WHERE - host_key_host_uuid != ".$anvil->Database->quote($anvil->Get->host_uuid)." + ssh_key_host_uuid != ".$anvil->Database->quote($anvil->Get->host_uuid)." ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }}); @@ -920,18 +584,18 @@ WHERE }}); foreach my $row (@{$results}) { - my $host_key_host_uuid = $row->[0]; - my $host_key_user_name = $row->[1]; - my $host_key_public_key = $row->[2]; + my $ssh_key_host_uuid = $row->[0]; + my $ssh_key_user_name = $row->[1]; + my $ssh_key_public_key = $row->[2]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - host_key_host_uuid => $host_key_host_uuid, - host_key_user_name => $host_key_user_name, - host_key_public_key => $host_key_public_key, + ssh_key_host_uuid => $ssh_key_host_uuid, + ssh_key_user_name => $ssh_key_user_name, + ssh_key_public_key => $ssh_key_public_key, }}); - $anvil->data->{peers}{ssh_keys}{$host_key_host_uuid}{user}{$host_key_user_name} = $host_key_public_key; + $anvil->data->{peers}{ssh_keys}{$ssh_key_host_uuid}{user}{$ssh_key_user_name} = $ssh_key_public_key; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - "peers::ssh_keys::${host_key_host_uuid}::user::${host_key_user_name}" => $anvil->data->{peers}{ssh_keys}{$host_key_host_uuid}{user}{$host_key_user_name}, + "peers::ssh_keys::${ssh_key_host_uuid}::user::${ssh_key_user_name}" => $anvil->data->{peers}{ssh_keys}{$ssh_key_host_uuid}{user}{$ssh_key_user_name}, }}); } @@ -945,9 +609,9 @@ sub check_install_target { my ($anvil) = @_; - my $system_type = $anvil->System->get_host_type(); + my $system_type = $anvil->Get->host_type(); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { system_type => $system_type }}); - if ($system_type ne "dashboard") + if ($system_type ne "striker") { # Not a dashboard, nothing to do. return(0); @@ -1004,8 +668,9 @@ sub run_once # Check to see if we need to do boot-time tasks. We only run these if we've just booted boot_time_tasks($anvil); - # Check the ssh stuff. - check_ssh_keys($anvil); + # Check the ssh stuff. + # NOTE: This actually runs again in the minutes tasks, but needs to run on boot as well. + $anvil->System->check_ssh_keys({debug => 3}); # Check setuid wrappers check_setuid_wrappers($anvil); @@ -1023,9 +688,9 @@ sub check_setuid_wrappers { my ($anvil) = @_; - my $host_type = $anvil->System->get_host_type(); + my $host_type = $anvil->Get->host_type(); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { host_type => $host_type }}); - if ($host_type ne "dashboard") + if ($host_type ne "striker") { # Not a dashboard, setuid scripts aren't needed. return(0); @@ -1136,7 +801,7 @@ sub boot_time_tasks my ($anvil) = @_; # If the uptime is less than ten minutes, clear the reboot flag. - my $uptime = $anvil->System->get_uptime; + my $uptime = $anvil->Get->uptime; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { uptime => $uptime }}); # Now find out if a reboot is listed as needed and when it was last changed. @@ -1220,9 +885,9 @@ sub prep_database my ($anvil) = @_; # Only run this if we're a dashboard. - my $host_type = $anvil->System->get_host_type(); + my $host_type = $anvil->Get->host_type(); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { host_type => $host_type }}); - if ($host_type eq "dashboard") + if ($host_type eq "striker") { my ($database_output, $return_code) = $anvil->System->call({ debug => 3, @@ -1273,7 +938,7 @@ sub keep_running } } - # If we're confiugured, write out the status JSON file. If we're not configured, Update hardware state files. + # If we're configured, write out the status JSON file. If we're not configured, Update hardware state files. my $configured = $anvil->System->check_if_configured; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { configured => $configured }}); if ((not $anvil->data->{sys}{mapping_network}) && ($configured)) @@ -1508,10 +1173,10 @@ sub update_state_file my ($anvil) = @_; my ($states_output, $return_code) = $anvil->System->call({debug => 3, shell_call => $anvil->data->{path}{exe}{'anvil-update-states'}, source => $THIS_FILE, line => __LINE__}); - if ($states_output) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { states_output => $states_output }}); - } + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + states_output => $states_output, + return_code => $return_code, + }}); return(0); } diff --git a/tools/anvil-join-anvil b/tools/anvil-join-anvil index 566ecf32..4a475e3c 100755 --- a/tools/anvil-join-anvil +++ b/tools/anvil-join-anvil @@ -55,6 +55,8 @@ load_manifest($anvil); # Check if we need to change any IPs or our hostname. check_local_network($anvil); +# (wait for out peer and) Configure pacemaker +configure_pacemaker($anvil); $anvil->nice_exit({code => 0}); @@ -62,6 +64,49 @@ $anvil->nice_exit({code => 0}); # Functions # ############################################################################################################# +# (wait for out peer and) Configure pacemaker. If this is a DR host, this is skipped. +sub configure_pacemaker +{ + my ($anvil) = @_; + + my $machine = $anvil->data->{sys}{machine}; + my $manifest_uuid = $anvil->data->{sys}{manifest_uuid}; + + ### TODO: Move these to variables in the 'sys' hash + my $anvil_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{name}; + my $host_name = $anvil->data->{sys}{host_name}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:machine' => $machine, + 's1:anvil_name' => $anvil_name, + 's3:host_name' => $host_name, + }}); + +=cut +909; xxx::upses::el8-ups01::uuid: [7ebecdda-782d-4624-841d-98d912ed3d50] +909; xxx::upses::el8-ups02::uuid: [7ffb4dc2-8b96-4ca7-80bb-49e309fb2f5f] +918; xxx::fences::an-nas02::uuid: [4117a862-f58f-4676-991a-9ca257a3c612] + +949; xxx::networks::name::bcn1::gateway: [], xxx::networks::name::bcn1::network: [10.201.0.0], xxx::networks::name::bcn1::subnet: [255.255.0.0] +949; xxx::networks::name::sn1::gateway: [], xxx::networks::name::sn1::network: [10.101.0.0], xxx::networks::name::sn1::subnet: [255.255.0.0] +949; xxx::networks::name::ifn1::gateway: [10.255.255.254], xxx::networks::name::ifn1::network: [10.255.0.0], xxx::networks::name::ifn1::subnet: [255.255.0.0] +961; xxx::networks::count::bcn: [1], xxx::networks::count::ifn: [1], xxx::networks::count::sn: [1] + +971; xxx::machine::node1::ipmi_ip: [], xxx::machine::node1::type: [!!undef!!] +980; xxx::machine::node1::fence::an-nas02::port: [el8-a01n01] +980; xxx::machine::node1::fence::el8-pdu01::port: [] +980; xxx::machine::node1::fence::el8-pdu02::port: [] +980; xxx::machine::node1::fence::pulsar::port: [] +989; xxx::machine::node1::ups::el8-ups01::used: [0] +989; xxx::machine::node1::ups::el8-ups02::used: [0] +998; xxx::machine::node1::network::bcn1::ip: [10.201.10.1] +998; xxx::machine::node1::network::ifn1::ip: [10.255.10.1] +998; xxx::machine::node1::network::sn1::ip: [10.101.10.1] +=cut + + + return(0); +} + # Check if we need to change any IPs or our hostname. sub check_local_network { @@ -71,7 +116,6 @@ sub check_local_network my $machine = $anvil->data->{sys}{machine}; my $manifest_uuid = $anvil->data->{sys}{manifest_uuid}; - my $anvil_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{name}; my $domain = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{domain}; my $old_host_name = $anvil->_host_name; my $new_host_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{name}; @@ -80,12 +124,13 @@ sub check_local_network $new_host_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{name}.".".$domain; } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 's1:anvil_name' => $anvil_name, 's2:domain' => $domain, 's3:old_host_name' => $old_host_name, 's4:new_host_name' => $new_host_name, }}); + $anvil->data->{sys}{host_name} = $new_host_name; + # If the hostname isn't the same, change it. if ($old_host_name ne $new_host_name) { @@ -770,28 +815,13 @@ sub check_local_network } } + ### TODO: Do we really need passwordless SSH anymore? + # Configure SSH by adding ours and our peer's SSH keys to ~/.ssh/known_hosts + $anvil->System->check_ssh_keys({debug => 2}); + + # Setup IPMI, if needed. -=cut -909; xxx::upses::el8-ups01::uuid: [7ebecdda-782d-4624-841d-98d912ed3d50] -909; xxx::upses::el8-ups02::uuid: [7ffb4dc2-8b96-4ca7-80bb-49e309fb2f5f] -918; xxx::fences::an-nas02::uuid: [4117a862-f58f-4676-991a-9ca257a3c612] - -949; xxx::networks::name::bcn1::gateway: [], xxx::networks::name::bcn1::network: [10.201.0.0], xxx::networks::name::bcn1::subnet: [255.255.0.0] -949; xxx::networks::name::sn1::gateway: [], xxx::networks::name::sn1::network: [10.101.0.0], xxx::networks::name::sn1::subnet: [255.255.0.0] -949; xxx::networks::name::ifn1::gateway: [10.255.255.254], xxx::networks::name::ifn1::network: [10.255.0.0], xxx::networks::name::ifn1::subnet: [255.255.0.0] -961; xxx::networks::count::bcn: [1], xxx::networks::count::ifn: [1], xxx::networks::count::sn: [1] - -971; xxx::machine::node1::ipmi_ip: [], xxx::machine::node1::type: [!!undef!!] -980; xxx::machine::node1::fence::an-nas02::port: [el8-a01n01] -980; xxx::machine::node1::fence::el8-pdu01::port: [] -980; xxx::machine::node1::fence::el8-pdu02::port: [] -980; xxx::machine::node1::fence::pulsar::port: [] -989; xxx::machine::node1::ups::el8-ups01::used: [0] -989; xxx::machine::node1::ups::el8-ups02::used: [0] -998; xxx::machine::node1::network::bcn1::ip: [10.201.10.1] -998; xxx::machine::node1::network::ifn1::ip: [10.255.10.1] -998; xxx::machine::node1::network::sn1::ip: [10.101.10.1] -=cut + ### TODO: Do this when on real hardware return(0); } @@ -815,17 +845,26 @@ sub load_job update_progress($anvil, ($anvil->data->{job}{progress} += 1), "job_0074,!!job-uuid!".$anvil->data->{switches}{'job-uuid'}."!!"); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0074", variables => { 'job-uuid' => $anvil->data->{switches}{'job-uuid'} }}); - my ($machine, $manifest_uuid) = ($anvil->data->{jobs}{job_data} =~ /as_machine=(.*?),manifest_uuid=(.*)$/); + my ($machine, $manifest_uuid, $node1_host_uuid, $node2_host_uuid, $dr1_host_uuid) = ($anvil->data->{jobs}{job_data} =~ /as_machine=(.*?),manifest_uuid=(.*?),node1_host_uuid=(.*?),node2_host_uuid=(.*?),dr1_host_uuid=(.*?)$/); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - machine => $machine, - manifest_uuid => $manifest_uuid, + machine => $machine, + manifest_uuid => $manifest_uuid, + node1_host_uuid => $node1_host_uuid, + node2_host_uuid => $node2_host_uuid, + dr1_host_uuid => $dr1_host_uuid, }}); - $anvil->data->{sys}{machine} = $machine; - $anvil->data->{sys}{manifest_uuid} = $manifest_uuid; + $anvil->data->{sys}{machine} = $machine; + $anvil->data->{sys}{manifest_uuid} = $manifest_uuid; + $anvil->data->{sys}{node1_host_uuid} = $node1_host_uuid; + $anvil->data->{sys}{node2_host_uuid} = $node2_host_uuid; + $anvil->data->{sys}{node1_host_uuid} = $node1_host_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - "sys::machine" => $anvil->data->{sys}{machine}, - "sys::manifest_uuid" => $anvil->data->{sys}{manifest_uuid}, + "sys::machine" => $anvil->data->{sys}{machine}, + "sys::manifest_uuid" => $anvil->data->{sys}{manifest_uuid}, + "sys::node1_host_uuid" => $anvil->data->{sys}{node1_host_uuid}, + "sys::node2_host_uuid" => $anvil->data->{sys}{node2_host_uuid}, + "sys::dr1_host_uuid" => $anvil->data->{sys}{dr1_host_uuid}, }}); update_progress($anvil, ($anvil->data->{job}{progress} += 1), "job_0075,!!machine!".$anvil->data->{sys}{machine}."!!,!!manifest_uuid!".$anvil->data->{sys}{manifest_uuid}."!!"); @@ -867,6 +906,9 @@ sub update_progress 's1:progress' => $progress, 's2:message' => $message, }}); + + # Disabled for the moment + return(0); $progress = 95 if $progress > 100; if (not $anvil->data->{switches}{'job-uuid'}) diff --git a/tools/anvil-manage-firewall b/tools/anvil-manage-firewall index 0f4a7333..5c7c3caf 100755 --- a/tools/anvil-manage-firewall +++ b/tools/anvil-manage-firewall @@ -341,7 +341,7 @@ sub check_initial_setup } # NOTE: We may want to do machine-specific stuff down the road. - my $type = $anvil->System->get_host_type(); + my $type = $anvil->Get->host_type(); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }}); return(0); diff --git a/tools/anvil-manage-power b/tools/anvil-manage-power index 31cfb110..1e4b2652 100755 --- a/tools/anvil-manage-power +++ b/tools/anvil-manage-power @@ -185,7 +185,7 @@ sub do_poweroff $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { task => $task }}); # We'll wait until the system has at least 10 minutes of uptime, unless '--no-wait' was given. - my $uptime = $anvil->data->{switches}{'no-wait'} ? 0 : $anvil->System->get_uptime; + my $uptime = $anvil->data->{switches}{'no-wait'} ? 0 : $anvil->Get->uptime; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::no-wait" => $anvil->data->{switches}{'no-delay'}, uptime => $uptime, diff --git a/tools/anvil-update-states b/tools/anvil-update-states index d2f2e04c..0900c99d 100755 --- a/tools/anvil-update-states +++ b/tools/anvil-update-states @@ -92,7 +92,7 @@ sub process_interface_cache network_interface_operational => $operational, network_interface_speed => $speed, }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_interface_uuid => $network_interface_uuid }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { network_interface_uuid => $network_interface_uuid }}); if (not $network_interface_uuid) { # Failed to update, could be that we cached data for an interface not yet @@ -146,7 +146,7 @@ sub update_network next if $file eq "."; next if $file eq ".."; next if $file eq "lo"; - my $full_path = "$directory/$file"; + my $full_path = $directory."/".$file; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { full_path => $full_path }}); if (-d $full_path) { @@ -226,7 +226,7 @@ sub update_network { ### Set some fake values. # Speed is "as fast as possible", so we'll record 100 Gbps, but that is really kind of arbitrary. - $speed = 100000 if ((not $speed) or ($speed eq "-1")); + $speed = 1000 if ((not $speed) or ($speed eq "-1")); $duplex = "full" if not $duplex; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { speed => $speed, @@ -991,7 +991,7 @@ WHERE # Write the JSON file, if we're a dashboard. Nodes and DR hosts don't have a WebUI, so they're not # needed. - if ($anvil->System->get_host_type eq "dashboard") + if ($anvil->Get->host_type eq "striker") { my $output_json = $anvil->data->{path}{directories}{html}."/status/network.json"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output_xml => $output_json }}); diff --git a/tools/striker-manage-install-target b/tools/striker-manage-install-target index c2ba2334..bb1692a5 100755 --- a/tools/striker-manage-install-target +++ b/tools/striker-manage-install-target @@ -192,7 +192,7 @@ if (not $configured) load_os_info($anvil); # If this isn't a Striker dashboard, exit. -if ($anvil->System->get_host_type ne "dashboard") +if ($anvil->Get->host_type ne "striker") { print $anvil->Words->string({key => "error_0044"})."\n"; update_progress($anvil, 100, "error_0044"); @@ -268,7 +268,7 @@ sub load_os_info { my ($anvil) = @_; - my ($os_type, $os_arch) = $anvil->System->get_os_type(); + 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; $anvil->data->{host_os}{version} = ($os_type =~ /(\d+)$/)[0]; @@ -2440,7 +2440,7 @@ sub load_packages ], }; - my ($os_type, $os_arch) = $anvil->System->get_os_type(); + my ($os_type, $os_arch) = $anvil->Get->os_type(); if ($os_type eq "rhel8") { push @{$anvil->data->{packages}{r}}, "redhat-backgrounds.noarch"; diff --git a/tools/test.pl b/tools/test.pl index d595bd7c..a1c6a750 100755 --- a/tools/test.pl +++ b/tools/test.pl @@ -25,10 +25,4 @@ $anvil->Database->connect({debug => 3}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); print "DB Connections: [".$anvil->data->{sys}{database}{connections}."]\n"; -$anvil->Striker->get_fence_data(); - -foreach my $name (sort {$a cmp $b} keys %{$anvil->data->{fence_data}{fence_virsh}{parameters}}) -{ - #print "Name: [".$name."]: [".sprintf('%vX', $anvil->data->{fence_data}{fence_virsh}{parameters}{$name}{'default'})."]\n"; - print "Name: [".$name."]: [".$anvil->data->{fence_data}{fence_virsh}{parameters}{$name}{'default'}."]\n"; -} +$anvil->System->check_ssh_keys({debug => 2});