From 93427a7a381ae7a4cddf8dc136cd4a4343ee528f Mon Sep 17 00:00:00 2001 From: Digimer Date: Tue, 18 Oct 2022 19:16:32 -0400 Subject: [PATCH] * Updated Get->switches() to always support job-uuid. * Updated striker-initialize-host to support calls from command line switches, and wrote the man page for it. Signed-off-by: Digimer --- Anvil/Tools/Get.pm | 1 + man/striker-initialize-host.8 | 55 ++++++++++ share/words.xml | 3 + tools/anvil-manage-files | 2 +- tools/striker-initialize-host | 197 +++++++++++++++++++++++++++------- 5 files changed, 217 insertions(+), 41 deletions(-) create mode 100644 man/striker-initialize-host.8 diff --git a/Anvil/Tools/Get.pm b/Anvil/Tools/Get.pm index e272bda2..8f7cdf68 100644 --- a/Anvil/Tools/Get.pm +++ b/Anvil/Tools/Get.pm @@ -2299,6 +2299,7 @@ sub switches next if $set_switch eq "?"; next if $set_switch eq "h"; next if $set_switch eq "help"; + next if $set_switch eq "job-uuid"; next if $set_switch eq "log-secure"; next if $set_switch eq "log-db-transactions"; next if $set_switch eq "raw"; diff --git a/man/striker-initialize-host.8 b/man/striker-initialize-host.8 new file mode 100644 index 00000000..1fc59698 --- /dev/null +++ b/man/striker-initialize-host.8 @@ -0,0 +1,55 @@ +.\" Manpage for the Alteeve! striker-initialize-host tool +.\" Contact mkelly@alteeve.com to report issues, concerns or suggestions. +.TH striker-initialize-host "8" "August 02 2022" "Anvil! Intelligent Availability™ Platform" +.SH NAME +striker-initialize-host \- Tool used on Striker dashboards to initialize new Nodes and DR hosts. +.SH SYNOPSIS +.B striker-initialize-host +\fI\, \/\fR[\fI\,options\/\fR] +.SH DESCRIPTION +striker-initialize-host \- This tool logs into a target Anvil! sub-node or DR host, adds the Alteeve! repository, installs \fBanvil-node\fR or \fBanvil-dr\fR, and then configures \fBanvil.conf\fR so that the target can start communicating with any peered Striker dashboards. +.TP +.SH OPTIONS +.TP +\-?, \-h, \fB\-\-help\fR +Show this man page. +.TP +\-d, \fB\-\-job-uuid\fR +This is the jobs -> job_uuid of the job to run, if it exists. +.TP +\fB\-\-log-secure\fR +When logging, record sensitive data, like passwords. +.TP +\fB\-v\fR, \fB\-vv\fR, \fB\-vvv\fR +Set the log level for this run to 1, 2 or 3 (higher == more verbose). +.TP +.SS "Commands:" +.TP +\-k, \fB\-\-enterprise-uuid\fR +If you have a key, provide it this way. This will configure the host to use the Alteeve enterprise repository. (see 'man alteeve-repo-setup' for repo options). +.TP +\-k, \fB\-\-host-ip-address\fR +This is the IP address of the target node or DR host. +.TP +\-k, \fB\-\-password\fR +This is the current \fBroot\fR user's password on the target node or DR host. +.TP +\-k, \fB\-\-rh-password\fR +If the target is a Red Hat Enterprise Linux OS, and if the target is not yet connected to a subscription, you can provide the \fBrh-user\fR and this password to have the target subscribed during initialization. +.TP +\-k, \fB\-\-rh-user\fR +If the target is a Red Hat Enterprise Linux OS, and if the target is not yet connected to a subscription, you can provide this user name and \fBrh-password\fR to have the target subscribed during initialization. +.TP +\-k, \fB\-\-ssh-port\fR +If you need to connect over a non-standard port, you can set it with this switch. +.TP +\-k, \fB\-\-target\fR +Alternative to \fB\-\-host-ip-address\fR. +.TP +\-k, \fB\-\-type\fR <'node' or 'dr'> +This indicates how you want the target to be initialized as. +.IP +.SH AUTHOR +Written by Madison Kelly, Alteeve staff and the Anvil! project contributors. +.SH "REPORTING BUGS" +Report bugs to users@clusterlabs.org diff --git a/share/words.xml b/share/words.xml index c8467ce5..750fe0ab 100644 --- a/share/words.xml +++ b/share/words.xml @@ -531,6 +531,9 @@ The definition data passed in was: The long-throw license file: [#!variable!file!#] was not found, so unable to install it. There was a problem with the "Long-throw" lincense file. This will prevent Long-Throw DR from working. Details of the error will be recorded in the log file. [ Error ] - (At least) two interfaces have the same MAC address assigned to them. This should not happen, and would cause endless reboots. Unable to complete configuration, please re-map the network again and watch for duplicates. The duplicate MAC address is: [#!variable!mac_address!#] which is used by both: [#!variable!iface1!#] and: [#!variable!iface2!#]. + [ Error ] - The '--type' must be 'host' or 'dr'. Was given: [#!variable!type!#]. + [ Error ] - The UUID: [#!variable!uuid!#] is not a valid UUID. + [ Error ] - Neither '--host-ip-address' or '--target' were used to define who we are trying to connect to. diff --git a/tools/anvil-manage-files b/tools/anvil-manage-files index cbb61a06..03ab133d 100755 --- a/tools/anvil-manage-files +++ b/tools/anvil-manage-files @@ -52,7 +52,7 @@ if (($running_directory =~ /^\./) && ($ENV{PWD})) my $anvil = Anvil::Tools->new(); -$anvil->Get->switches({list => ["add", "check", "delete", "download", "file", "is-script", "job-uuid", "rename", "remove", "to"], man => $THIS_FILE}); +$anvil->Get->switches({list => ["add", "check", "delete", "download", "file", "is-script", "rename", "remove", "to"], man => $THIS_FILE}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}}); # Connect or die diff --git a/tools/striker-initialize-host b/tools/striker-initialize-host index 44d47823..27f9dd3e 100755 --- a/tools/striker-initialize-host +++ b/tools/striker-initialize-host @@ -30,17 +30,15 @@ $| = 1; my $anvil = Anvil::Tools->new(); -# Read switches (target ([user@]host[:port]) and the file with the target's password. -$anvil->data->{switches}{'job-uuid'} = ""; -$anvil->Get->switches; ### TODO: Remove this before final release $anvil->Log->level({set => 2}); $anvil->Log->secure({set => 1}); ########################################## + +# Read switches (target ([user@]host[:port]) and the file with the target's password. +$anvil->Get->switches({list => ["enterprise-uuid", "host-ip-address", "password", "rh-password", "rh-user", "ssh-port", "target", "type"], man => $THIS_FILE}); +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }}); -$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 'switches::job-uuid' => $anvil->data->{switches}{'job-uuid'}, -}}); # Connect to the database(s). $anvil->Database->connect({check_for_resync => 1}); @@ -383,9 +381,6 @@ sub add_repos # If this striker is an enterprise user, get the key for when we initialize targets. my $enterprise_key = ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - "path::configs::alteeve-release.repo" => $anvil->data->{path}{configs}{'alteeve-release.repo'}, - }}); if (-e $anvil->data->{path}{configs}{'alteeve-release.repo'}) { # Read the file @@ -403,6 +398,15 @@ sub add_repos } } + # If the user set an enterprise key, use it, even if we found one on disk. + if ($anvil->data->{data}{enterprise_uuid}) + { + $enterprise_key = $anvil->data->{data}{enterprise_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "path::configs::alteeve-release.repo" => $anvil->data->{path}{configs}{'alteeve-release.repo'}, + }}); + } + if ($repo) { # NOTE: We can't use Storage->write_file() because the target may not have 'rsync' installed @@ -431,7 +435,7 @@ EOF update_progress($anvil, $anvil->data->{job}{progress}, "job_0029"); } - # If I have a Red Hat user and password, try to subscribe this syste,. + # If I have a Red Hat user and password, try to subscribe this system. if (($anvil->data->{data}{rh_user}) && ($anvil->data->{data}{rh_password})) { # If there's no internet, this will fail. If the network is up, we can see if the @@ -1002,19 +1006,34 @@ sub get_job_details } } - if (not $anvil->data->{switches}{'job-uuid'}) + # It's now possible to run without a job_uuid +# if (not $anvil->data->{switches}{'job-uuid'}) +# { +# # No job UUID. +# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0073"}); +# $anvil->nice_exit({exit_code => 2}); +# } + + my $return = 0; + if ($anvil->data->{switches}{'job-uuid'}) { - # No job UUID. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0073"}); - $anvil->nice_exit({exit_code => 2}); + $return = $anvil->Database->get_job_details({debug => 3, job_uuid => $anvil->data->{switches}{'job-uuid'}}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'return' => $return }}); } - - my $return = $anvil->Database->get_job_details({debug => 3, job_uuid => $anvil->data->{switches}{'job-uuid'}}); - if (not $return) +# if (not $return) +# { +# # No job details +# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0034", variables => { job_uuid => $anvil->data->{switches}{'job-uuid'} }}); +# $anvil->nice_exit({exit_code => 3}); +# } + + # If the user used '--target', but not '--host-ip-address', set it. + if ((not $anvil->data->{switches}{'host-ip-address'}) && ($anvil->data->{switches}{'target'})) { - # No job details - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0034", variables => { job_uuid => $anvil->data->{switches}{'job-uuid'} }}); - $anvil->nice_exit({exit_code => 3}); + $anvil->data->{switches}{'host-ip-address'} = $anvil->data->{switches}{'target'}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 'switches::host-ip-address' => $anvil->data->{switches}{'host-ip-address'}, + }}); } # Set up all possible variables. @@ -1025,34 +1044,121 @@ sub get_job_details $anvil->data->{data}{rh_user} = ""; $anvil->data->{data}{ssh_port} = ""; $anvil->data->{data}{type} = ""; + $anvil->data->{jobs}{job_uuid} = ""; - $anvil->data->{jobs}{job_uuid} = $anvil->data->{switches}{'job-uuid'}; - $anvil->data->{jobs}{job_command} = $return->{job_command}; - $anvil->data->{jobs}{job_data} = $return->{job_data}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - 'jobs::job_uuid' => $anvil->data->{jobs}{job_uuid}, - 'jobs::job_command' => $anvil->data->{jobs}{job_command}, - 'jobs::job_data' => $anvil->Log->is_secure($anvil->data->{jobs}{job_data}), - }}); - - foreach my $line (split/\n/, $anvil->data->{jobs}{job_data}) + # If we have a job_uuid, load the data. + if ($return) { - my $secure = $line =~ /passw/ ? 1 : 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => $secure, list => { line => $line }}); - - my ($variable, $value) = ($line =~ /^(.*?)=(.*)$/); + $anvil->data->{jobs}{job_uuid} = $anvil->data->{switches}{'job-uuid'}; + $anvil->data->{jobs}{job_command} = $return->{job_command}; + $anvil->data->{jobs}{job_data} = $return->{job_data}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - variable => $variable, - value => $secure ? $anvil->Log->is_secure($value) : $value, + 'jobs::job_uuid' => $anvil->data->{jobs}{job_uuid}, + 'jobs::job_command' => $anvil->data->{jobs}{job_command}, + 'jobs::job_data' => $anvil->Log->is_secure($anvil->data->{jobs}{job_data}), }}); - $anvil->data->{data}{$variable} = $value; + foreach my $line (split/\n/, $anvil->data->{jobs}{job_data}) + { + my $secure = $line =~ /passw/ ? 1 : 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => $secure, list => { line => $line }}); + + my ($variable, $value) = ($line =~ /^(.*?)=(.*)$/); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + variable => $variable, + value => $secure ? $anvil->Log->is_secure($value) : $value, + }}); + + $anvil->data->{data}{$variable} = $value; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "data::${variable}" => $secure ? $anvil->Log->is_secure($anvil->data->{data}{$variable}) : $anvil->data->{data}{$variable}, + }}); + } + } + + # If the user set command line switches, they will override the values read from the job. + if ($anvil->data->{switches}{'enterprise-uuid'}) + { + $anvil->data->{data}{enterprise_uuid} = $anvil->data->{switches}{'enterprise-uuid'}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - "data::${variable}" => $secure ? $anvil->Log->is_secure($anvil->data->{data}{$variable}) : $anvil->data->{data}{$variable}, + "data::enterprise_uuid" => $anvil->data->{data}{enterprise_uuid}, + }}); + } + if ($anvil->data->{switches}{'host-ip-address'}) + { + $anvil->data->{data}{host_ip_address} = $anvil->data->{switches}{'host-ip-address'}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "data::host_ip_address" => $anvil->data->{data}{host_ip_address}, + }}); + } + if ($anvil->data->{switches}{'password'}) + { + $anvil->data->{data}{password} = $anvil->data->{switches}{'password'}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "data::password" => $anvil->Log->is_secure($anvil->data->{data}{password}), + }}); + } + if ($anvil->data->{switches}{'rh-password'}) + { + $anvil->data->{data}{rh_password} = $anvil->data->{switches}{'rh-password'}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "data::rh_password" => $anvil->Log->is_secure($anvil->data->{data}{rh_password}), + }}); + } + if ($anvil->data->{switches}{'rh-user'}) + { + $anvil->data->{data}{rh_user} = $anvil->data->{switches}{'rh-user'}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "data::rh_user" => $anvil->data->{data}{rh_user}, + }}); + } + if ($anvil->data->{switches}{'ssh-port'}) + { + $anvil->data->{data}{ssh_port} = $anvil->data->{switches}{'ssh-port'}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "data::ssh_port" => $anvil->data->{data}{ssh_port}, + }}); + } + if ($anvil->data->{switches}{'type'}) + { + $anvil->data->{data}{type} = $anvil->data->{switches}{'type'}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "data::type" => $anvil->data->{data}{type}, }}); } - $anvil->data->{data}{say_target} = "root\@".$anvil->data->{data}{host_ip_address}.":".$anvil->data->{data}{ssh_port}; + ### Sanity checks. + my $problem = 0; + # Good type? + if (($anvil->data->{data}{type} ne "node") && ($anvil->data->{data}{type} ne "dr")) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0377", variables => { type => $anvil->data->{data}{type} }}); + update_progress($anvil, 100, "error_0377,!!type!".$anvil->data->{data}{type}."!!"); + $anvil->nice_exit({exit_code => 1}); + } + # Valid enterprise UUID? + if (($anvil->data->{data}{enterprise_uuid}) && (not $anvil->Validate->uuid({uuid => $anvil->data->{data}{enterprise_uuid}}))) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0378", variables => { uuid => $anvil->data->{data}{$anvil->data->{data}{enterprise_uuid}} }}); + update_progress($anvil, 100, "error_0378,!!uuid!".$anvil->data->{data}{$anvil->data->{data}{enterprise_uuid}}."!!"); + $anvil->nice_exit({exit_code => 1}); + } + if (not $anvil->data->{data}{host_ip_address}) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0379"}); + update_progress($anvil, 100, "error_0379"); + $anvil->nice_exit({exit_code => 1}); + } + + # Create our target + $anvil->data->{data}{say_target} = "root\@".$anvil->data->{data}{host_ip_address}; + if (($anvil->data->{data}{ssh_port}) && ($anvil->data->{data}{ssh_port} != 22)) + { + $anvil->data->{data}{say_target} .= ":".$anvil->data->{data}{ssh_port}; + } + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "data::say_target" => $anvil->data->{data}{say_target}, + }}); # Update that we've picked the job up. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0027", variables => { 'job-uuid' => $anvil->data->{switches}{'job-uuid'} }}); @@ -1071,7 +1177,18 @@ sub update_progress $progress = 95 if $progress > 100; if (not $anvil->data->{switches}{'job-uuid'}) { - return(0); + if ($anvil->data->{jobs}{job_uuid}) + { + $anvil->data->{switches}{'job-uuid'} = $anvil->data->{jobs}{job_uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'}, + }}); + } + else + { + # Just return. + return(0); + } } $anvil->Job->update_progress({