Local modifications to ClusterLabs/Anvil by Alteeve
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

746 lines
42 KiB

#!/usr/bin/perl
#
# NOTE: This tool is NOT meant for production use! It is meant as a tool for CI/CD testing.
#
# If this is used for any other purpose, it is at he user's own risk. Please be sure to thoroughly test the
# resulting Anvil! before going into production (which, honestly, you should do anyways).
#
use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;
use NetAddr::IP;
$| = 1;
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
$running_directory =~ s/^\./$ENV{PWD}/;
}
=cut
# At this point, the Striker should be coming up at the IP. Once both/all Strikers are up, update their anvil.conf to add each other's UUID database entry.
# FROM ONE STRIKER;
job_uuid | job_host_uuid | job_command | job_data | job_picked_up_by | job_picked_up_at | job_updated | job_name | job_progress | job_title | job_description | job_status | modified_date
--------------------------------------+--------------------------------------+------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+------------------+------------------+-------------+-------------------+--------------+-----------+-----------------+------------+-------------------------------
6ca30d0b-c03c-43f9-bd7c-c40a79ca52a8 | 46c00674-fea2-44af-981d-2833d5c8270a | /usr/sbin/striker-manage-peers --add --host-uuid a64c477b-b0a1-4985-9968-f4b46d75fb0c --host 10.201.4.2 --port 5432 --ping 1 | password=super secret password +| 0 | 0 | 1613699163 | striker-peer::add | 0 | job_0011 | job_0012 | | 2021-02-18 20:46:03.305568-05
| | | peer_job_command=/usr/sbin/striker-manage-peers --add --host-uuid 46c00674-fea2-44af-981d-2833d5c8270a --host 10.201.4.1 --port 5432 --ping 1 | | | | | | | | |
(1 row)
# Initialize nodes / dr hosts (may need to call striker-get-peer-data)
anvil=# SELECT * FROM jobs ;
job_uuid | job_host_uuid | job_command | job_data | job_picked_up_by | job_picked_up_at | job_updated | job_name | job_progress | job_title | job_description | job_status | modified_date
--------------------------------------+--------------------------------------+-----------------------------------+---------------------------------+------------------+------------------+-------------+-----------------------------------+--------------+-----------+-----------------+------------+------------------------------
a5c3381c-c581-4020-baa0-72e136c75a68 | 46c00674-fea2-44af-981d-2833d5c8270a | /usr/sbin/striker-initialize-host | password=Initial1 +| 0 | 0 | 1613957250 | initialize::node::192.168.122.207 | 0 | job_0020 | job_0022 | | 2021-02-21 20:27:30.73576-05
| | | rh_password= +| | | | | | | | |
| | | rh_user= +| | | | | | | | |
| | | host_ip_address=192.168.122.207+| | | | | | | | |
| | | ssh_port=22 +| | | | | | | | |
| | | type=node +| | | | | | | | |
| | | host_name=di-a02n01.alteeve.com+| | | | | | | | |
| | | | | | | | | | | |
(1 row)
anvil=# SELECT * FROM jobs WHERE job_progress != 100;
job_uuid | job_host_uuid | job_command | job_data | job_picked_up_by | job_picked_up_at | job_updated | job_name | job_progress | job_title | job_description | job_status | modified_date
--------------------------------------+--------------------------------------+-----------------------------------+----------------------------------+------------------+------------------+-------------+---------------------------------+--------------+-----------+-----------------+------------+-------------------------------
6c21d7ca-1c86-4389-9821-0ae945529754 | 46c00674-fea2-44af-981d-2833d5c8270a | /usr/sbin/striker-initialize-host | password=Initial1 +| 0 | 0 | 1614047831 | initialize::dr::192.168.122.141 | 0 | job_0021 | job_0022 | | 2021-02-22 21:37:11.082112-05
| | | rh_password= +| | | | | | | | |
| | | rh_user= +| | | | | | | | |
| | | host_ip_address=192.168.122.141 +| | | | | | | | |
| | | ssh_port=22 +| | | | | | | | |
| | | type=dr +| | | | | | | | |
| | | host_name=di-a02dr01.alteeve.com+| | | | | | | | |
| | | | | | | | | | | |
(1 row)
=cut
my $anvil = Anvil::Tools->new();
$anvil->Database->connect;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
# No databases, exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0003"});
$anvil->nice_exit({exit_code => 1});
}
$anvil->data->{switches}{config} = "";
$anvil->data->{switches}{'job-uuid'} = "";
$anvil->Get->switches;
# Read in the config file
if ((not $anvil->data->{switches}{config}) or (not -f $anvil->data->{switches}{config}))
{
# Print the usage.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0240", variables => { program => $THIS_FILE }});
$anvil->nice_exit({exit_code => 1});
}
# Load the config.
$anvil->Storage->read_config({file => $anvil->data->{switches}{config}});
# Check that 'prefix' is now set as a rough test that the file we read was useful.
if ((not exists $anvil->data->{base}{prefix}) or ($anvil->data->{base}{prefix} eq ""))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0241", variables => { file => $anvil->data->{switches}{config} }});
$anvil->nice_exit({exit_code => 1});
}
# Find myself
find_myself($anvil);
if (not $anvil->data->{i_am}{striker})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0242", variables => { file => $anvil->data->{switches}{config} }});
$anvil->nice_exit({exit_code => 1});
}
# If I am not configured, configure myself now.
my $configured = $anvil->System->check_if_configured;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { configured => $configured }});
if ($configured)
{
# If I am not Striker 1, I am done.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "i_am::striker" => $anvil->data->{i_am}{striker} }});
if ($anvil->data->{i_am}{striker} ne "1")
{
# We're done.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "message_0221", variables => { striker => $anvil->data->{i_am}{striker} }});
$anvil->nice_exit({exit_code => 0});
}
striker_stage2($anvil);
}
else
{
# Do the initial setup of ourselves.
striker_stage1($anvil);
}
#print Dumper $anvil->data->{base};
#print Dumper $anvil->data->{striker};
$anvil->nice_exit({exit_code => 0});
#############################################################################################################
# Functions #
#############################################################################################################
# This does the rest of the setup.
sub striker_stage2
{
my ($anvil) = @_;
# Merge my peer Striker.
merge_peer_striker($anvil);
return(0);
}
# Merge my peer Striker.
sub merge_peer_striker
{
my ($anvil) = @_;
# For each peer, see if we're already connected to it.
foreach my $striker_number (sort {$a cmp $b} keys %{$anvil->data->{striker}})
{
next if $striker_number !~ /^\d+$/;
next if $striker_number == $anvil->data->{i_am}{striker};
next if not exists $anvil->data->{striker}{$striker_number}{network};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { striker_number => $striker_number }});
# Use the MAC address(es) to look for a host UUID. If we don't find one, we need to peer it.
my $peer_host_uuid = 0;
my $peer_ips = [];
foreach my $network (sort {$a cmp $b} keys %{$anvil->data->{striker}{$striker_number}{network}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network => $network }});
foreach my $network_number (sort {$a cmp $b} keys %{$anvil->data->{striker}{$striker_number}{network}{$network}})
{
my $ip = $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{ip};
my $subnet_mask = $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{subnet_mask};
push @{$peer_ips}, $ip."/".$subnet_mask;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_number => $network_number,
ip => $ip,
subnet_mask => $subnet_mask,
}});
foreach my $link_number (sort {$a cmp $b} keys %{$anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}})
{
next if $peer_host_uuid;
my $mac_address = lc($anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}{$link_number}{mac});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
link_number => $link_number,
mac_address => $mac_address,
}});
my $query = "
SELECT
network_interface_host_uuid
FROM
network_interfaces
WHERE
network_interface_operational != 'DELETED'
AND
network_interface_mac_address = ".$anvil->Database->quote($mac_address)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, 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 => 2, list => {
results => $results,
count => $count,
}});
if ($count)
{
$peer_host_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_host_uuid => $peer_host_uuid }});
}
}
}
}
if (not $peer_host_uuid)
{
### Add the peer.
# First, wait for access.
my $waiting = 1;
my $joining = 0;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0227", variables => { number => $striker_number }});
while ($waiting)
{
foreach my $network (@{$peer_ips})
{
next if not $waiting;
my ($ip, $subnet_mask) = ($network =~ /^(.*?)\/(.*)$/);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ip => $ip,
subnet_mask => $subnet_mask,
}});
# Try to read the host uuid.
my $file = $anvil->data->{path}{data}{host_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file => $file }});
my $shell_call = "
if [ -e ".$file." ];
then
cat ".$file.";
else
echo 0;
fi;
";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0166", variables => {
shell_call => $shell_call,
target => $ip,
remote_user => "root",
}});
my ($host_uuid, $error, $return_code) = $anvil->Remote->call({
shell_call => $shell_call,
target => $ip,
password => $anvil->data->{base}{password}{desired},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid,
error => $error,
return_code => $return_code,
}});
if (($host_uuid) && ($anvil->Validate->uuid({uuid => $host_uuid})))
{
# Success!
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0228", variables => {
number => $striker_number,
ip => $ip,
}});
$peer_host_uuid = $host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_host_uuid => $peer_host_uuid }});
# Find the IP we used to reach the peer.
my $our_ip = "";
$anvil->Network->load_ips({
host => "local",
host_uuid => $anvil->Get->host_uuid(),
});
foreach my $interface_name (sort {$a cmp $b} keys %{$anvil->data->{network}{'local'}{interface}})
{
my $local_ip = $anvil->data->{network}{'local'}{interface}{$interface_name}{ip};
my $local_subnet_mask = $anvil->data->{network}{'local'}{interface}{$interface_name}{subnet_mask};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface_name => $interface_name,
local_ip => $local_ip,
local_subnet_mask => $local_subnet_mask,
}});
next if $local_subnet_mask ne $subnet_mask;
# See if this IP is in the same subnet.
my $first = NetAddr::IP->new($local_ip."/".$local_subnet_mask);
my $second = NetAddr::IP->new($ip."/".$subnet_mask);
if ($second->within($first))
{
# Found the IP to tell the peer to use
$our_ip = $local_ip;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { our_ip => $our_ip }});
last;
}
}
if (not $our_ip)
{
# wtf;
die;
}
# Register a job and then wait for it to show up in our database.
my $job_data = "password=".$anvil->data->{base}{password}{desired}."\n";
$job_data .= "peer_job_command=".$anvil->data->{path}{exe}{'striker-manage-peers'}." --add --host-uuid ".$anvil->Get->host_uuid." --host ".$our_ip." --port 5432 --ping 1";
my $job_command = $anvil->data->{path}{exe}{'striker-manage-peers'}." --add --host-uuid ".$host_uuid." --host ".$ip." --port 5432 --ping 1";
$waiting = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
job_command => $job_command,
job_data => $anvil->Log->is_secure($job_data),
waiting => $waiting,
}});
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
job_command => $job_command,
job_data => $job_data,
job_name => "striker-peer::remove",
job_title => "job_0013",
job_description => "job_0014",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
}
else
{
# No access
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0229", variables => {
number => $striker_number,
ip => $ip,
}});
}
}
if ($waiting)
{
# Wait 30 seconds and try again
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0230", variables => { number => $striker_number }});
sleep 30;
}
}
}
# Now wait until the peer is in our database.
my $peer_host_name = "";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0231", variables => {
number => $striker_number,
peer_host_uuid => $peer_host_uuid,
}});
until ($peer_host_name)
{
my $query = "SELECT host_name FROM hosts WHERE host_uuid = ".$anvil->Database->quote($peer_host_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, 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 => 2, list => {
results => $results,
count => $count,
}});
if ($count)
{
$peer_host_name = $results->[0]->[0];
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0232", variables => {
number => $striker_number,
peer_host_name => $peer_host_name,
}});
}
else
{
# Sleep for a bit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0233", variables => {
number => $striker_number,
peer_host_uuid => $peer_host_uuid,
}});
sleep 5;
}
}
}
# By here, the peer(s) are joined.
return(0);
}
# This preps and requests the initial configuration job.
sub striker_stage1
{
my ($anvil) = @_;
### TODO: Validate all steps up front before starting anything.
if ((not defined $anvil->data->{base}{organization_name}) or (not $anvil->data->{base}{organization_name}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0243", variables => { variable => 'base::organization_name' }});
$anvil->nice_exit({exit_code => 1});
}
if ((not defined $anvil->data->{base}{prefix}) or (not $anvil->data->{base}{prefix}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0243", variables => { variable => 'base::prefix' }});
$anvil->nice_exit({exit_code => 1});
}
elsif (length($anvil->data->{base}{prefix}) > 5)
{
# Prefix is too long
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0244", variables => {
prefix => $anvil->data->{base}{prefix},
'length' => length($anvil->data->{base}{prefix}),
}});
$anvil->nice_exit({exit_code => 1});
}
if ((not defined $anvil->data->{base}{domain}) or (not $anvil->data->{base}{domain}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0243", variables => { variable => 'base::domain' }});
$anvil->nice_exit({exit_code => 1});
}
elsif (not $anvil->Validate->domain_name({name => $anvil->data->{base}{domain}}))
{
# Domain is not valid
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0117", variables => { name => $anvil->data->{base}{domain} }});
$anvil->nice_exit({exit_code => 1});
}
if ((not defined $anvil->data->{base}{password}{desired}) or (not $anvil->data->{base}{password}{desired}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0243", variables => { variable => 'base::password::desired' }});
$anvil->nice_exit({exit_code => 1});
}
if ((not defined $anvil->data->{base}{dns}) or (not $anvil->data->{base}{dns}))
{
$anvil->data->{base}{dns} = "8.8.8.8,8.8.4.4";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "base::dns" => $anvil->data->{base}{dns} }});
}
else
{
# Make sure any/all DNS are valid.
foreach my $ip (split/,/, $anvil->data->{base}{dns})
{
if (not $anvil->Validate->ipv4({ip => $ip}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0245", variables => { ip => $ip }});
$anvil->nice_exit({exit_code => 1});
}
}
}
if ((defined $anvil->data->{base}{gateway}) && ($anvil->data->{base}{gateway}))
{
if (not $anvil->Validate->ipv4({ip => $anvil->data->{base}{gateway}}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0246", variables => { ip => $anvil->data->{base}{gateway} }});
$anvil->nice_exit({exit_code => 1});
}
}
my $striker_number = $anvil->data->{i_am}{striker};
my $organization_name = $anvil->data->{base}{organization_name};
my $prefix = $anvil->data->{base}{prefix};
my $domain = $anvil->data->{base}{domain};
my $ifn_count = keys %{$anvil->data->{striker}{$striker_number}{network}{ifn}};
my $host_name = $prefix."-striker0".$striker_number.".".$domain;
my $new_password = $anvil->data->{base}{password}{desired};
my $dns = $anvil->data->{base}{dns};
my $gateway = $anvil->data->{base}{gateway};
my $gateway_network = defined $anvil->data->{base}{gateway_network} ? $anvil->data->{base}{gateway_network} : "ifn1";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
striker_number => $striker_number,
organization_name => $organization_name,
prefix => $prefix,
domain => $domain,
ifn_count => $ifn_count,
host_name => $host_name,
new_password => $anvil->Log->is_secure($new_password),
dns => $dns,
gateway => $gateway,
gateway_network => $gateway_network,
}});
# Load the variables.
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::organization::value'}{variable_value} = $organization_name;
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::organization::value'}{variable_description} = "striker_0004";
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::organization::value'}{variable_section} = "config_step1";
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::prefix::value'}{variable_value} = $prefix;
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::prefix::value'}{variable_description} = "striker_0006";
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::prefix::value'}{variable_section} = "config_step1";
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::domain::value'}{variable_value} = $domain;
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::domain::value'}{variable_description} = "striker_0008";
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::domain::value'}{variable_section} = "config_step1";
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::ifn_count::value'}{variable_value} = $ifn_count;
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::ifn_count::value'}{variable_description} = "striker_0012";
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::ifn_count::value'}{variable_section} = "config_step1";
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::sequence::value'}{variable_value} = $striker_number;
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::sequence::value'}{variable_description} = "striker_0010";
$anvil->data->{striker}{stage1}{variables}{'form::config_step1::sequence::value'}{variable_section} = "config_step1";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::host_name::value'}{variable_value} = $host_name;
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::host_name::value'}{variable_description} = "striker_0017";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::host_name::value'}{variable_section} = "config_step2";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::striker_user::value'}{variable_value} = "admin";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::striker_user::value'}{variable_description} = "striker_0032";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::striker_user::value'}{variable_section} = "config_step2";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::striker_password::value'}{variable_value} = $new_password;
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::striker_password::value'}{variable_description} = "striker_0034";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::striker_password::value'}{variable_section} = "config_step2";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::dns::value'}{variable_value} = $dns;
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::dns::value'}{variable_description} = "striker_0038";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::dns::value'}{variable_section} = "config_step2";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::gateway::value'}{variable_value} = $gateway;
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::gateway::value'}{variable_description} = "striker_0036";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::gateway::value'}{variable_section} = "config_step2";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::gateway_interface::value'}{variable_value} = $gateway_network;
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::gateway_interface::value'}{variable_description} = "";
$anvil->data->{striker}{stage1}{variables}{'form::config_step2::gateway_interface::value'}{variable_section} = "config_step2";
foreach my $network (sort {$a cmp $b} keys %{$anvil->data->{striker}{$striker_number}{network}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network => $network }});
foreach my $network_number (sort {$a cmp $b} keys %{$anvil->data->{striker}{$striker_number}{network}{$network}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_number => $network_number }});
if ((not defined $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{ip}) or (not $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{ip}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0243", variables => {
variable => "striker::${striker_number}::network::${network}::${network_number}::ip",
}});
$anvil->nice_exit({exit_code => 1});
}
elsif (not $anvil->Validate->ipv4({ip => $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{ip}}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0247", variables => {
variable => "striker::${striker_number}::network::${network}::${network_number}::ip",
value => $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{ip},
}});
$anvil->nice_exit({exit_code => 1});
}
if ((not defined $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{subnet_mask}) or (not $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{subnet_mask}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0243", variables => {
variable => "striker::${striker_number}::network::${network}::${network_number}::subnet_mask",
}});
$anvil->nice_exit({exit_code => 1});
}
elsif (not $anvil->Validate->ipv4({ip => $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{subnet_mask}}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0247", variables => {
variable => "striker::${striker_number}::network::${network}::${network_number}::subnet_mask",
value => $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{subnet_mask},
}});
$anvil->nice_exit({exit_code => 1});
}
if ((not defined $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}{1}{mac}) or (not $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}{1}{mac}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0243", variables => {
variable => "striker::${striker_number}::network::${network}::${network_number}::link::1::mac",
}});
$anvil->nice_exit({exit_code => 1});
}
my $ip_key = "form::config_step2::".$network.$network_number."_ip::value";
my $ip = $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{ip};
my $subnet_mask_key = "form::config_step2::".$network.$network_number."_subnet_mask::value";
my $subnet_mask = $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{subnet_mask};
my $link1_mac_key = "form::config_step2::".$network.$network_number."_link1_mac_to_set::value";
my $link1_mac = $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}{1}{mac};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:ip_key' => $ip_key,
's2:ip' => $ip,
's3:subnet_mask_key' => $subnet_mask_key,
's4:subnet_mask' => $subnet_mask,
's4:link1_mac_key' => $link1_mac_key,
's5:link1_mac' => $link1_mac,
}});
$anvil->data->{striker}{stage1}{variables}{$ip_key}{variable_value} = $ip;
$anvil->data->{striker}{stage1}{variables}{$ip_key}{variable_description} = "striker_0024";
$anvil->data->{striker}{stage1}{variables}{$ip_key}{variable_section} = "config_step2";
$anvil->data->{striker}{stage1}{variables}{$subnet_mask_key}{variable_value} = $subnet_mask;
$anvil->data->{striker}{stage1}{variables}{$subnet_mask_key}{variable_description} = "striker_0025";
$anvil->data->{striker}{stage1}{variables}{$subnet_mask_key}{variable_section} = "config_step2";
$anvil->data->{striker}{stage1}{variables}{$link1_mac_key}{variable_value} = $link1_mac;
$anvil->data->{striker}{stage1}{variables}{$link1_mac_key}{variable_description} = "striker_0029";
$anvil->data->{striker}{stage1}{variables}{$link1_mac_key}{variable_section} = "config_step2";
if (exists $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}{2})
{
if ((not defined $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}{2}{mac}) or (not $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}{2}{mac}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0243", variables => {
variable => "striker::${striker_number}::network::${network}::${network_number}::link::2::mac",
}});
$anvil->nice_exit({exit_code => 1});
}
my $link2_mac_key = "form::config_step2::".$network.$network_number."_link2_mac_to_set::value";
my $link2_mac = $anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}{2}{mac};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:link2_mac_key' => $link2_mac_key,
's2:link2_mac' => $link2_mac,
}});
$anvil->data->{striker}{stage1}{variables}{$link2_mac_key}{variable_value} = $link2_mac;
$anvil->data->{striker}{stage1}{variables}{$link2_mac_key}{variable_description} = "striker_0029";
$anvil->data->{striker}{stage1}{variables}{$link2_mac_key}{variable_section} = "config_step2";
}
}
}
# Now, for each variable, record it to the database.
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{striker}{stage1}{variables}})
{
my $value = $anvil->data->{striker}{stage1}{variables}{$variable}{variable_value};
my $description = $anvil->data->{striker}{stage1}{variables}{$variable}{variable_description};
my $section = $anvil->data->{striker}{stage1}{variables}{$variable}{variable_section};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:variable' => $variable,
's2:value' => $value,
's3:description' => $description,
's4:section' => $section,
}});
my ($variable_uuid) = $anvil->Database->insert_or_update_variables({
variable_name => $variable,
variable_value => $value,
variable_default => "",
variable_description => $description,
variable_section => $section,
variable_source_uuid => $anvil->Get->host_uuid,
variable_source_table => "hosts",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
}
# Call anvil-configure-host now.
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
debug => 2,
job_host_uuid => $anvil->data->{cgi}{host_uuid}{value},
job_command => $anvil->data->{path}{exe}{'anvil-configure-host'},
job_data => "form::config_step2",
job_name => "configure::network",
job_title => "job_0001",
job_description => "job_0071",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
# If we're striker 1, add a job to restart ourselves when ScanCore starts (after the reboot)
if ($striker_number eq "1")
{
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
debug => 2,
job_host_uuid => $anvil->data->{cgi}{host_uuid}{value},
job_command => $anvil->data->{path}{exe}{'striker-auto-initialize-all'}." --config ".$anvil->data->{switches}{config},
job_data => "",
job_name => "configure::auto_initialize",
job_title => "job_0225",
job_description => "job_0226",
job_status => "scancore_startup",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
}
return(0);
}
# This looks to see if we can map a 'striker::X::' to this machine.
sub find_myself
{
my ($anvil) = @_;
# Find my MAC addresses.
my $short_host_name = $anvil->Get->short_host_name();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { short_host_name => $short_host_name }});
$anvil->Network->get_ips({debug => 3});
$anvil->data->{i_am}{striker} = 0;
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{$short_host_name}{interface}})
{
my $ip_address = $anvil->data->{network}{$short_host_name}{interface}{$interface}{ip};
my $subnet_mask = $anvil->data->{network}{$short_host_name}{interface}{$interface}{subnet_mask};
my $mac_address = $anvil->data->{network}{$short_host_name}{interface}{$interface}{mac_address};
my $mtu = $anvil->data->{network}{$short_host_name}{interface}{$interface}{mtu};
my $default_gateway = $anvil->data->{network}{$short_host_name}{interface}{$interface}{default_gateway};
my $gateway = $anvil->data->{network}{$short_host_name}{interface}{$interface}{gateway};
my $dns = $anvil->data->{network}{$short_host_name}{interface}{$interface}{dns};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface,
ip_address => $ip_address,
subnet_mask => $subnet_mask,
mac_address => $mac_address,
mtu => $mtu,
default_gateway => $default_gateway,
gateway => $gateway,
dns => $dns,
}});
foreach my $striker_number (sort {$a cmp $b} keys %{$anvil->data->{striker}})
{
next if $striker_number !~ /^\d+$/;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { striker_number => $striker_number }});
foreach my $network (sort {$a cmp $b} keys %{$anvil->data->{striker}{$striker_number}{network}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network => $network }});
foreach my $network_number (sort {$a cmp $b} keys %{$anvil->data->{striker}{$striker_number}{network}{$network}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_number => $network_number }});
foreach my $link_number (sort {$a cmp $b} keys %{$anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { link_number => $link_number }});
my $this_mac_address = lc($anvil->data->{striker}{$striker_number}{network}{$network}{$network_number}{'link'}{$link_number}{mac});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
mac_address => $mac_address,
this_mac_address => $this_mac_address,
}});
if ((not $anvil->data->{i_am}{striker}) && ($this_mac_address eq $mac_address))
{
# This is us.
$anvil->data->{i_am}{striker} = $striker_number;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "i_am::striker" => $anvil->data->{i_am}{striker} }});
return($anvil->data->{i_am}{striker});
}
}
}
}
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { i_am_striker => $anvil->data->{i_am}{striker} }});
return($anvil->data->{i_am}{striker});
}
# If this is being called as a job, this will allow the progress to be updated.
sub update_progress
{
my ($anvil, $progress, $message) = @_;
$progress = 95 if $progress > 100;
if (not $anvil->data->{switches}{'job-uuid'})
{
return(0);
}
$anvil->Job->update_progress({
debug => 3,
progress => $progress,
message => $message,
job_uuid => $anvil->data->{switches}{'job-uuid'},
});
return(0);
}