* Created Database->get_ip_addresses() that pulls the IPs out and stores them in a hash that allows for easy referencing to associated interfaces and networks.

* Created Get->trusted_hosts() that finds the dashboards the host uses and, if the host is in an Anvil!, the peers in the same anvil.
* Created (but not finished yet) System->update_hosts() that will add and edit entries for all IPs to trusted hosts.
* Fixed a logging bug in Striker->load_manifest().
* Fixed a bug in System->call where, the the output from the shell call didn't end in a new-line, it would not parse the return code and lease the return code string appended to the shell output.
* Fixed a big in System->change_shell_user_password() where a new-line (\n) meant for the shell call wasn't escaped properly. There was also a duplicate 'return_code' variable preventing the actual return code from being read.
* Got more work done on anvil-join-anvil to update the hacluster password (when needed).

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent aa2fdfb609
commit 76b6550ac6
  1. 1
      Anvil/Tools.pm
  2. 224
      Anvil/Tools/Database.pm
  3. 48
      Anvil/Tools/Get.pm
  4. 2
      Anvil/Tools/Striker.pm
  5. 120
      Anvil/Tools/System.pm
  6. 2
      notes
  7. 4
      share/words.xml
  8. 228
      tools/anvil-join-anvil
  9. 2
      tools/test.pl

@ -1059,6 +1059,7 @@ sub _set_paths
'dhcpd.conf' => "/etc/dhcp/dhcpd.conf", 'dhcpd.conf' => "/etc/dhcp/dhcpd.conf",
'dnf.conf' => "/etc/dnf/dnf.conf", 'dnf.conf' => "/etc/dnf/dnf.conf",
'firewalld.conf' => "/etc/firewalld/firewalld.conf", 'firewalld.conf' => "/etc/firewalld/firewalld.conf",
hosts => "/etc/hosts",
'httpd.conf' => "/etc/httpd/conf/httpd.conf", 'httpd.conf' => "/etc/httpd/conf/httpd.conf",
'journald_anvil' => "/etc/systemd/journald.conf.d/anvil.conf", 'journald_anvil' => "/etc/systemd/journald.conf.d/anvil.conf",
'pg_hba.conf' => "/var/lib/pgsql/data/pg_hba.conf", 'pg_hba.conf' => "/var/lib/pgsql/data/pg_hba.conf",

@ -25,6 +25,7 @@ my $THIS_FILE = "Database.pm";
# get_host_from_uuid # get_host_from_uuid
# get_hosts # get_hosts
# get_hosts_info # get_hosts_info
# get_ip_addresses
# get_job_details # get_job_details
# get_jobs # get_jobs
# get_local_uuid # get_local_uuid
@ -2057,6 +2058,229 @@ AND
} }
=head2 get_ip_addresses
This loads all know IP addresses from the C<< ip_addresses >> table and stores them in a hash that simplifies knowing what host and network an IP belongs to.
The data will be stored in two hashes, one referenced by the network the IPs are on and the other referenced by the IP address.
hosts::host_uuid::<host_uuid>::network::<on_network>::ip_address = <ip_address>
hosts::host_uuid::<host_uuid>::network::<on_network>::subnet_mask = <subnet mask>
hosts::host_uuid::<host_uuid>::network::<on_network>::on_interface = <interface name>
hosts::host_uuid::<host_uuid>::ip_address::<ip_address>::subnet_mask = <subnet mask>
hosts::host_uuid::<host_uuid>::ip_address::<ip_address>::on_interface = <interface name>
hosts::host_uuid::<host_uuid>::ip_address::<ip_address>::on_network = <on_network>
This method takes no parameters.
=cut
sub get_ip_addresses
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
# Make sure we've loaded host data.
$anvil->Database->get_hosts({debug => $debug});
foreach my $host_uuid (keys %{$anvil->data->{hosts}{host_uuid}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid }});
# Load any bridges.
my $query = "
SELECT
bridge_uuid,
bridge_name
FROM
bridges
WHERE
bridge_host_uuid = ".$anvil->Database->quote($host_uuid)."
AND
bridge_id != 'DELETED'
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $bridge_uuid = $row->[0];
my $bridge_name = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
bridge_uuid => $bridge_uuid,
bridge_name => $bridge_name,
}});
$anvil->data->{hosts}{host_uuid}{$host_uuid}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_name} = $bridge_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hosts::host_uuid::${host_uuid}::bridges::bridge_uuid::${bridge_uuid}::bridge_name" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{bridges}{bridge_uuid}{$bridge_uuid}{bridge_name},
}});
}
undef $results;
undef $count;
# Read in bonds.
$query = "
SELECT
bond_uuid,
bond_name
FROM
bonds
WHERE
bond_host_uuid = ".$anvil->Database->quote($host_uuid)."
AND
bond_operational != 'DELETED'
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $bond_uuid = $row->[0];
my $bond_name = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
bond_uuid => $bond_uuid,
bond_name => $bond_name,
}});
$anvil->data->{hosts}{host_uuid}{$host_uuid}{bonds}{bond_uuid}{$bond_uuid}{bond_name} = $bond_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hosts::host_uuid::${host_uuid}::bonds::bond_uuid::${bond_uuid}::bond_name" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{bonds}{bond_uuid}{$bond_uuid}{bond_name},
}});
}
undef $results;
undef $count;
# Now load interfaces.
$query = "
SELECT
network_interface_uuid,
network_interface_name
FROM
network_interfaces
WHERE
network_interface_host_uuid = ".$anvil->Database->quote($host_uuid)."
AND
network_interface_operational != 'DELETED'
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $network_interface_uuid = $row->[0];
my $network_interface_name = $row->[1];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
network_interface_uuid => $network_interface_uuid,
network_interface_name => $network_interface_name,
}});
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name} = $network_interface_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hosts::host_uuid::${host_uuid}::network_interfaces::network_interface_uuid::${network_interface_uuid}::network_interface_name" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network_interfaces}{network_interface_uuid}{$network_interface_uuid}{network_interface_name},
}});
}
undef $results;
undef $count;
# Finally, load IP addresses.
$query = "
SELECT
ip_address_on_type,
ip_address_on_uuid,
ip_address_address,
ip_address_subnet_mask
FROM
ip_addresses
WHERE
ip_address_host_uuid = ".$anvil->Database->quote($host_uuid)."
AND
ip_address_note != 'DELETED';
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
$count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $ip_address_on_type = $row->[0];
my $ip_address_on_uuid = $row->[1];
my $ip_address_address = $row->[2];
my $ip_address_subnet_mask = $row->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
ip_address_on_type => $ip_address_on_type,
ip_address_on_uuid => $ip_address_on_uuid,
ip_address_address => $ip_address_address,
ip_address_subnet_mask => $ip_address_subnet_mask,
}});
# Which device is it on?
my $on_interface = "";
if ($ip_address_on_type eq "bridge")
{
$on_interface = $anvil->data->{hosts}{host_uuid}{$host_uuid}{bridges}{bridge_uuid}{$ip_address_on_uuid}{bridge_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { on_interface => $on_interface }});
}
elsif ($ip_address_on_type eq "bond")
{
$on_interface = $anvil->data->{hosts}{host_uuid}{$host_uuid}{bonds}{bond_uuid}{$ip_address_on_uuid}{bond_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { on_interface => $on_interface }});
}
elsif ($ip_address_on_type eq "interface")
{
$on_interface = $anvil->data->{hosts}{host_uuid}{$host_uuid}{network_interfaces}{network_interface_uuid}{$ip_address_on_uuid}{network_interface_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { on_interface => $on_interface }});
}
my $on_network = ($on_interface =~ /^(.*?)_/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { on_network => $on_network }});
# Store it.
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{ip_address} = $ip_address_address;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{subnet_mask} = $ip_address_subnet_mask;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{on_interface} = $on_interface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hosts::host_uuid::${host_uuid}::network::${on_network}::ip_address" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{ip_address},
"hosts::host_uuid::${host_uuid}::network::${on_network}::subnet_mask" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{subnet_mask},
"hosts::host_uuid::${host_uuid}::network::${on_network}::on_interface" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{on_interface},
}});
$anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{subnet_mask} = $ip_address_subnet_mask;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_interface} = $on_interface;
$anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_network} = $on_network;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hosts::host_uuid::${host_uuid}::ip_address::${ip_address_address}::subnet_mask" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{subnet_mask},
"hosts::host_uuid::${host_uuid}::ip_address::${ip_address_address}::on_interface" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_interface},
"hosts::host_uuid::${host_uuid}::ip_address::${ip_address_address}::on_network" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{ip_address}{$ip_address_address}{on_network},
}});
}
}
return(0);
}
=head2 get_job_details =head2 get_job_details
This gets the details for a given job. If the job is found, a hash reference is returned containing the tables that were read in. This gets the details for a given job. If the job is found, a hash reference is returned containing the tables that were read in.

@ -25,6 +25,7 @@ my $THIS_FILE = "Get.pm";
# md5sum # md5sum
# os_type # os_type
# switches # switches
# trusted_hosts
# uptime # uptime
# users_home # users_home
# uuid # uuid
@ -1080,6 +1081,53 @@ sub switches
return(0); return(0);
} }
=head2 trusted_hosts
This returns an array reference containing host UUIDs of hosts this machine should trust. Specifically, any Striker dashboards this host uses, and if this host is in an Anvil!, the peers. The array will include this host's UUID as well.
This method takes no parameters
=cut
sub trusted_hosts
{
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 $local_host_uuid = $anvil->Get->host_uuid;
my $in_anvil = $anvil->data->{hosts}{host_uuid}{$local_host_uuid}{anvil_name};
my $trusted_host_uuids = [$local_host_uuid];
foreach my $host_uuid (keys %{$anvil->data->{hosts}{host_uuid}})
{
# Skip ourselves.
next if $host_uuid eq $anvil->Get->host_uuid;
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
my $anvil_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:host_uuid' => $host_uuid,
's2:host_name' => $host_name,
's3:host_type' => $host_type,
's4:anvil_name' => $anvil_name,
}});
if ($anvil->Get->host_type eq "striker")
{
# Add all known machines
push @{$trusted_host_uuids}, $host_uuid;
}
elsif ((($in_anvil) && ($anvil_name eq $in_anvil)) or (exists $anvil->data->{database}{$host_uuid}))
{
# Add dashboards we use and peers
push @{$trusted_host_uuids}, $host_uuid;
}
}
return($trusted_host_uuids)
}
=head2 uptime =head2 uptime
This returns, in seconds, how long the host has been up and running for. This returns, in seconds, how long the host has been up and running for.

@ -969,7 +969,7 @@ WHERE
$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}{name} = $parsed_xml->{machines}{$machine}{name};
$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->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 => { $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}::name" => $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{name},
"manifests::manifest_uuid::${manifest_uuid}::parsed::machine::${machine}::ipmi_ip" => $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ipmi_ip}, "manifests::manifest_uuid::${manifest_uuid}::parsed::machine::${machine}::ipmi_ip" => $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ipmi_ip},
}}); }});

@ -39,6 +39,7 @@ my $THIS_FILE = "System.pm";
# start_daemon # start_daemon
# stop_daemon # stop_daemon
# stty_echo # stty_echo
# update_hosts
# _load_firewalld_zones # _load_firewalld_zones
# _load_specific_firewalld_zone # _load_specific_firewalld_zone
# _match_port_to_service # _match_port_to_service
@ -340,15 +341,32 @@ sub call
if ($line =~ /^return_code:(\d+)$/) if ($line =~ /^return_code:(\d+)$/)
{ {
$return_code = $1; $return_code = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => { return_code => $return_code }});
}
elsif ($line =~ /return_code:(\d+)$/)
{
# If the output of the shell call doesn't end in a newline,
# the return_code:X could be appended. This catches those
# cases and removes it.
$return_code = $1;
$line =~ s/return_code:\d+$//;
$output .= $line."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => {
line => $line,
output => $output,
return_code => $return_code,
}});
} }
else else
{ {
$output .= $line."\n"; $output .= $line."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => { output => $output }});
} }
} }
close $file_handle; close $file_handle;
chomp($output); chomp($output);
$output =~ s/\n$//s; $output =~ s/\n$//s;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => { output => $output }});
} }
} }
} }
@ -446,7 +464,7 @@ sub change_shell_user_password
} }
# Generate a salt and then use it to create a hash. # Generate a salt and then use it to create a hash.
(my $salt, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{openssl}." rand 1000 | ".$anvil->data->{path}{exe}{strings}." | ".$anvil->data->{path}{exe}{'grep'}." -io [0-9A-Za-z\.\/] | ".$anvil->data->{path}{exe}{head}." -n 16 | ".$anvil->data->{path}{exe}{'tr'}." -d '\n'" }); (my $salt, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{openssl}." rand 1000 | ".$anvil->data->{path}{exe}{strings}." | ".$anvil->data->{path}{exe}{'grep'}." -io [0-9A-Za-z\.\/] | ".$anvil->data->{path}{exe}{head}." -n 16 | ".$anvil->data->{path}{exe}{'tr'}." -d '\\n'" });
my $new_hash = crypt($new_password,"\$6\$".$salt."\$"); my $new_hash = crypt($new_password,"\$6\$".$salt."\$");
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => {
salt => $salt, salt => $salt,
@ -479,7 +497,7 @@ sub change_shell_user_password
else else
{ {
# Local call # Local call
($output, $return_code, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call}); ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { output => $output, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { output => $output, return_code => $return_code }});
} }
foreach my $line (split/\n/, $output) foreach my $line (split/\n/, $output)
@ -755,33 +773,7 @@ sub check_ssh_keys
# and the key has changed, update the line with the new key. If it isn't found, add it. Once # 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 # we check the old body for this entry, change the "old" body to the new one, then repeat the
# process. # process.
my $local_host_uuid = $anvil->Get->host_type; my $trusted_host_uuids = $anvil->Get->trusted_hosts();
my $in_anvil = $anvil->data->{hosts}{host_uuid}{$local_host_uuid}{anvil_name};
my $trusted_host_uuids = [];
foreach my $host_uuid (keys %{$anvil->data->{hosts}{host_uuid}})
{
# Skip ourselves.
next if $host_uuid eq $anvil->Get->host_uuid;
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
my $anvil_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
host_name => $host_name,
host_type => $host_type,
anvil_name => $anvil_name,
}});
if ($anvil->Get->host_type eq "striker")
{
# Add all known machines
push @{$trusted_host_uuids}, $host_uuid;
}
elsif ((($in_anvil) && ($anvil_name eq $in_anvil)) or (exists $anvil->data->{database}{$host_uuid}))
{
# Add dashboards we use and peers
push @{$trusted_host_uuids}, $host_uuid;
}
}
# Look at all the hosts I know about (other than myself) and see if any of the machine or # 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. # user keys either don't exist or have changed.
@ -2975,6 +2967,76 @@ sub stty_echo
return(0); return(0);
} }
=head2 update_hosts
This uses the host list from C<< Get->trusted_hosts >>, along with data from C<< ip_addresses >>, to create a list of host name to IP addresses that should be in C<< /etc/hosts >>. Existing hosts where the IP has changed will be updated. Missing entries will be added. All other existing entries are left unchanged.
This method takes no parameters.
=cut
sub update_hosts
{
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->stty_echo()" }});
# Get the list of hosts we trust.
my $trusted_host_uuids = $anvil->Get->trusted_hosts({debug => $debug});
$anvil->Database->get_ip_addresses({debug => $debug});
foreach my $host_uuid (keys %{$anvil->data->{hosts}{host_uuid}})
{
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
my $short_host_name = $host_name;
$short_host_name =~ s/\..*$//;
my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => {
's1:host_name' => $host_name,
's2:short_host_name' => $short_host_name,
's3:host_type' => $host_type,
}});
# We store this in a way that lets us later sort by type -> host_name
$anvil->data->{trusted_host}{$host_type}{$short_host_name}{host_name} = $host_name;
$anvil->data->{trusted_host}{$host_type}{$short_host_name}{host_uuid} = $host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => {
"trusted_host::${host_type}::${short_host_name}::host_name" => $anvil->data->{trusted_host}{$host_type}{$short_host_name}{host_name},
"trusted_host::${host_type}::${short_host_name}::host_uuid" => $anvil->data->{trusted_host}{$host_type}{$short_host_name}{host_uuid},
}});
foreach my $on_network (sort {$a cmp $b} keys %{$anvil->data->{hosts}{host_uuid}{$host_uuid}{network}})
{
# Break the network sequence off the name for later sorting
my ($network_type, $sequence) = ($on_network =~ /^(.*?)(\d+)$/);
my $ip_address = $anvil->data->{hosts}{host_uuid}{$host_uuid}{network}{$on_network}{ip_address};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:on_network" => $on_network,
"s2:network_type" => $network_type,
"s3:sequence" => $sequence,
"s4:ip_address" => $ip_address,
}});
$anvil->data->{trusted_host}{$host_type}{$short_host_name}{network}{$network_type}{$sequence}{ip_address} = $ip_address;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => {
"trusted_host::${host_type}::${short_host_name}::network::${network_type}::${sequence}::ip_address" => $anvil->data->{trusted_host}{$host_type}{$short_host_name}{network}{$network_type}{$sequence}{ip_address},
}});
}
}
die;
# Read in the existing hosts file
my $old_body = $anvil->Storage->read_file({
debug => $debug,
file => $anvil->data->{path}{configs}{hosts},
});
# Parse the existing
return(0);
}
# =head3 # =head3
# #
# Private Functions; # Private Functions;

@ -253,7 +253,7 @@ systemctl enable pcsd.service
systemctl disable libvirtd.service systemctl disable libvirtd.service
systemctl stop libvirtd.service systemctl stop libvirtd.service
==== One node ==== One node
pcs cluster auth m3-a01n01 m3-a01n02 pcs cluster auth el8-a01n01 el8-a01n02
# Username: hacluster # Username: hacluster
# Password: # Password:

@ -332,6 +332,10 @@ Failure! The return code: [#!variable!return_code!#] was received ('0' was expec
<key name="job_0090">Adding the NTP server: [#!variable!server!#].</key> <key name="job_0090">Adding the NTP server: [#!variable!server!#].</key>
<key name="job_0091">Restarting the daemon: [#!variable!daemon!#].</key> <key name="job_0091">Restarting the daemon: [#!variable!daemon!#].</key>
<key name="job_0092"><![CDATA[[ Error ] - The Job: [#!variabe!job-uuid!#] appears to have passed malformed data. The raw data was: [#!variable!raw!#]. Expected 'as_machine=<host_type>,manifest_uuid=<manifest_uuid>,anvil_uuid=<anvil_uuid>'. Either the parse failed, or the data was somehow invalid.]]></key> <key name="job_0092"><![CDATA[[ Error ] - The Job: [#!variabe!job-uuid!#] appears to have passed malformed data. The raw data was: [#!variable!raw!#]. Expected 'as_machine=<host_type>,manifest_uuid=<manifest_uuid>,anvil_uuid=<anvil_uuid>'. Either the parse failed, or the data was somehow invalid.]]></key>
<key name="job_0093">Updated the password for the: [#!variable!user!#] user.</key>
<key name="job_0094">Enabled and started the daemon: [#!variable!daemon!#].</key>
<key name="job_0095">Disable and stop the daemon: [#!variable!daemon!#].</key>
<key name="job_0096">This is a DR host, skipping pacemaker configuration.</key>
<!-- Log entries --> <!-- Log entries -->
<key name="log_0001">Starting: [#!variable!program!#].</key> <key name="log_0001">Starting: [#!variable!program!#].</key>

@ -75,24 +75,229 @@ sub configure_pacemaker
my $anvil_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{name}; my $anvil_name = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{name};
my $anvil_uuid = $anvil->data->{sys}{anvil_uuid}; my $anvil_uuid = $anvil->data->{sys}{anvil_uuid};
my $host_name = $anvil->data->{sys}{host_name}; my $host_name = $anvil->data->{sys}{host_name};
my $new_password = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_password};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:machine' => $machine, 's1:machine' => $machine,
's1:anvil_name' => $anvil_name, 's1:anvil_name' => $anvil_name,
's3:host_name' => $host_name, 's3:host_name' => $host_name,
's4:manifest_uuid' => $manifest_uuid, 's4:manifest_uuid' => $manifest_uuid,
's5:anvil_uuid' => $anvil_uuid, 's5:anvil_uuid' => $anvil_uuid,
's6:new_password' => $anvil->Log->is_secure($new_password),
}}); }});
print Dumper $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}; # If this is a DR box, we don't use pacemaker.
print "=============================================\n"; if ($machine =~ /dr\d+/)
print Dumper $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}; {
print "=============================================\n"; update_progress($anvil, ($anvil->data->{job}{progress} += 10), "job_0096");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0096"});
return(0);
}
### Run on both nodes.
# Set the 'hacluster' user password.
my ($return_code) = $anvil->System->change_shell_user_password({
debug => 3,
user => "hacluster",
new_password => $new_password,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { return_code => $return_code }});
$return_code = undef;
update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0093,!!user!hacluster!!");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0093", variables => { user => "hascluster" }});
# Enable pcsd and start the pcsd daemons.
($return_code) = $anvil->System->enable_daemon({daemon => "pcsd"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { return_code => $return_code }});
$return_code = undef;
($return_code) = $anvil->System->start_daemon({daemon => "pcsd"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { return_code => $return_code }});
$return_code = undef;
update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0094,!!daemon!pcsd!!");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0094", variables => { daemon => "pcsd" }});
# Disabled and stop the libvirtd daemons.
($return_code) = $anvil->System->disable_daemon({daemon => "libvirtd"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { return_code => $return_code }});
$return_code = undef;
($return_code) = $anvil->System->stop_daemon({daemon => "libvirtd"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { return_code => $return_code }});
$return_code = undef;
update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0095,!!daemon!libvirtd!!");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0095", variables => { daemon => "libvirtd" }});
### Run on node 1 only.
if ($machine eq "node2")
{
# We loop until the peer finishes.
}
else
{
# Proceed with cluster setup.
}
=cut =cut
echo Initial1 | passwd hacluster --stdin $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed};
systemctl start pcsd.service $VAR1 = {
systemctl enable pcsd.service 'fences' => {
systemctl disable libvirtd.service 'pulsar' => 'c2be8d2e-045e-45d0-80e7-7443f2314fb1',
systemctl stop libvirtd.service 'el8-pdu02' => '2681049b-1ae7-444a-890b-39aca262e79e',
'el8-pdu01' => 'bad1fc5c-5342-4385-8d0d-a87a342dd87d',
'an-nas02' => '4117a862-f58f-4676-991a-9ca257a3c612'
},
'domain' => 'digimer.ca',
'networks' => {
'count' => {
'ifn' => 1,
'bcn' => 1,
'sn' => 1
},
'dns' => '8.8.8.8,8.8.4.4',
'mtu' => '1500',
'ntp' => '10.201.14.1,10.201.14.2',
'name' => {
'ifn1' => {
'subnet' => '255.255.255.0',
'gateway' => '192.168.122.1',
'network' => '192.168.122.0'
},
'bcn1' => {
'network' => '10.201.0.0',
'gateway' => '',
'subnet' => '255.255.0.0'
},
'sn1' => {
'gateway' => '',
'network' => '10.101.0.0',
'subnet' => '255.255.0.0'
}
}
},
'upses' => {
'el8-ups01' => {
'uuid' => '7ebecdda-782d-4624-841d-98d912ed3d50'
},
'el8-ups02' => {
'uuid' => '7ffb4dc2-8b96-4ca7-80bb-49e309fb2f5f'
}
},
'machine' => {
'node2' => {
'network' => {
'bcn1' => {
'ip' => '10.201.10.2'
},
'sn1' => {
'ip' => '10.101.10.2'
},
'ifn1' => {
'ip' => '192.168.122.12'
}
},
'ups' => {
'el8-ups01' => {
'used' => '0'
},
'el8-ups02' => {
'used' => '0'
}
},
'fence' => {
'pulsar' => {
'port' => ''
},
'el8-pdu02' => {
'port' => ''
},
'el8-pdu01' => {
'port' => ''
},
'an-nas02' => {
'port' => 'el8-a01n02'
}
},
'name' => 'el8-a01n02',
'ipmi_ip' => ''
},
'node1' => {
'ipmi_ip' => '',
'name' => 'el8-a01n01',
'ups' => {
'el8-ups02' => {
'used' => '0'
},
'el8-ups01' => {
'used' => '0'
}
},
'network' => {
'ifn1' => {
'ip' => '192.168.122.11'
},
'bcn1' => {
'ip' => '10.201.10.1'
},
'sn1' => {
'ip' => '10.101.10.1'
}
},
'fence' => {
'el8-pdu02' => {
'port' => ''
},
'pulsar' => {
'port' => ''
},
'an-nas02' => {
'port' => 'el8-a01n01'
},
'el8-pdu01' => {
'port' => ''
}
}
},
'dr1' => {
'fence' => {
'pulsar' => {
'port' => ''
},
'el8-pdu02' => {
'port' => ''
},
'el8-pdu01' => {
'port' => ''
},
'an-nas02' => {
'port' => ''
}
},
'network' => {
'bcn1' => {
'ip' => '10.201.10.3'
},
'sn1' => {
'ip' => '10.101.10.3'
},
'ifn1' => {
'ip' => '192.168.122.13'
}
},
'ups' => {
'el8-ups02' => {
'used' => '0'
},
'el8-ups01' => {
'used' => '0'
}
},
'name' => 'el8-a01dr01',
'ipmi_ip' => ''
}
},
'sequence' => '01',
'name' => 'el8-anvil-01',
'prefix' => 'el8'
};
909; xxx::upses::el8-ups01::uuid: [7ebecdda-782d-4624-841d-98d912ed3d50] 909; xxx::upses::el8-ups01::uuid: [7ebecdda-782d-4624-841d-98d912ed3d50]
909; xxx::upses::el8-ups02::uuid: [7ffb4dc2-8b96-4ca7-80bb-49e309fb2f5f] 909; xxx::upses::el8-ups02::uuid: [7ffb4dc2-8b96-4ca7-80bb-49e309fb2f5f]
@ -591,7 +796,7 @@ sub check_local_network
update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0083,!!file!".$filename."!!"); update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0083,!!file!".$filename."!!");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0083", variables => { file => $filename }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0083", variables => { file => $filename }});
$anvil->Storage->write_file({ $anvil->Storage->write_file({
debug => 2, debug => 3,
file => $filename, file => $filename,
body => $new_config, body => $new_config,
user => "root", user => "root",
@ -827,6 +1032,9 @@ sub check_local_network
} }
} }
# Make sure the IPs of the dashboard(s) and our peers are in the hosts file.
### TODO: Do we really need passwordless SSH anymore? ### TODO: Do we really need passwordless SSH anymore?
# Configure SSH by adding ours and our peer's SSH keys to ~/.ssh/known_hosts # Configure SSH by adding ours and our peer's SSH keys to ~/.ssh/known_hosts
$anvil->System->check_ssh_keys({debug => 2}); $anvil->System->check_ssh_keys({debug => 2});

@ -24,4 +24,4 @@ print "Connecting to the database(s);\n";
$anvil->Database->connect(); $anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0132"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0132"});
$anvil->System->check_ssh_keys({debug => 2}); $anvil->System->update_hosts({debug => 2});

Loading…
Cancel
Save