diff --git a/Anvil/Tools/System.pm b/Anvil/Tools/System.pm index 6fab08d6..59179357 100755 --- a/Anvil/Tools/System.pm +++ b/Anvil/Tools/System.pm @@ -10,6 +10,7 @@ use Net::SSH2; use Scalar::Util qw(weaken isweak); use Time::HiRes qw(gettimeofday tv_interval); use Proc::Simple; +use NetAddr::IP; our $VERSION = "3.0.0"; my $THIS_FILE = "System.pm"; @@ -22,6 +23,7 @@ my $THIS_FILE = "System.pm"; # check_memory # determine_host_type # enable_daemon +# find_matching_ip # get_ips # hostname # is_local @@ -620,6 +622,88 @@ sub enable_daemon return($return); } +=head2 find_matching_ip + +This takes an IP (or hostname, which is translated to an IP using local resources), and tries to figure out which local IP address is on the same subnet. + +If no match is found, an empty string is returned. If there is an error, C<< !!error!! >> is returned. + +Parameters; + +=head3 host (required) + +This is the IP address or host name we're going to use when searching for a local IP address that can reach it. + +=cut +sub find_matching_ip +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + + my $local_ip = ""; + my $host = defined $parameter->{host} ? $parameter->{host} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host => $host }}); + + # Do I have a host? + if (not $host) + { + # Woops! + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Systeme->find_matching_ip()", parameter => "host" }}); + return("!!error!!"); + } + + # Translate the host name to an IP address, if it isn't already an IP address. + if (not $anvil->Validate->is_ipv4({ip => $host})) + { + # This will be '0' if it failed, and pre-validated if it returns an IP. + $host = $anvil->Convert->hostname_to_ip({hostname => $host}); + if (not $host) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "log_0211", variables => { host => $parameter->{host} }}); + return(0); + } + } + + # Get my local IPs + $anvil->System->get_ips({debug => $debug}); + + my $ip = NetAddr::IP->new($host); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip => $ip }}); + + # Look through our IPs. First match wins. + foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { interface => $interface }}); + next if not $anvil->data->{sys}{network}{interface}{$interface}{ip}; + my $this_ip = $anvil->data->{sys}{network}{interface}{$interface}{ip}; + my $this_subnet = $anvil->data->{sys}{network}{interface}{$interface}{subnet}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "s1:this_ip" => $this_ip, + "s2:this_subnet" => $this_subnet, + }}); + + my $network_range = $this_ip."/".$this_subnet; + my $network = NetAddr::IP->new($network_range); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "s1:network_range" => $network_range, + "s2:network" => $network, + }}); + + if ($ip->within($network)) + { + $local_ip = $this_ip; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { local_ip => $local_ip }}); + last; + } + + } + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { local_ip => $local_ip }}); + return($local_ip); +} + =head2 get_ips This method checks the local system for interfaces and stores them in: diff --git a/cgi-bin/striker b/cgi-bin/striker index c495545b..c24c81ed 100755 --- a/cgi-bin/striker +++ b/cgi-bin/striker @@ -572,6 +572,7 @@ sub add_sync_peer my $user = $anvil->data->{sys}{database}{user}; my $host = $anvil->data->{cgi}{new_peer_access}{value}; my $name = $anvil->data->{sys}{database}{name}; + my $ping = $anvil->data->{cgi}{new_peer_ping}{value} eq "on" 1 : 0; my $port = 5432; my $ssh_tcp = 22; my $peer_uuid = ""; @@ -716,6 +717,42 @@ sub add_sync_peer if ($anvil->data->{cgi}{confirm}{value}) { # OK, save the job! + my $job_command = "anvil-manage-striker-peers --add "; + $job_command .= "--host-uuid ".$peer_uuid." "; + $job_command .= "--host ".$host." "; + $job_command .= "--port ".$port." "; + $job_command .= "--ping ".$ping; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_command => $job_command }}); + +# my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ +# file => $THIS_FILE, +# line => __LINE__, +# job_command => $job_command, +# job_data => "password=".$anvil->data->{cgi}{new_peer_password}{value}, +# job_name => "striker-peer::add", +# job_title => "job_0011", +# job_description => "job_0012", +# }); +# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }}); + + # Are we adding ourselves to the peer? + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::new_peer_bidirection::value" => $anvil->data->{cgi}{new_peer_bidirection}{value} }}); + if ($anvil->data->{cgi}{new_peer_bidirection}{value} eq "on") + { + my $use_ip = $anvil->System->find_matching_ip({debug => 2, host => $host}); + # See which of our IPs match theirs. If the peer is a hostname, first + } + + # We don't need to store anything as hidden variables, we'll read it back from the database + # later. + $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "system_update_recorded", variables => { + title_id => "", + message_id => "", + title => "#!string!striker_0044!#", + description => $ping ? "#!string!striker_0103!#" : "#!string!striker_0102!#", + }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); + } else { diff --git a/html/skins/alteeve/main.css b/html/skins/alteeve/main.css index 70ce61ce..055bea60 100644 --- a/html/skins/alteeve/main.css +++ b/html/skins/alteeve/main.css @@ -301,7 +301,8 @@ td { } .menu_title { - font-size: 1.1em; + color: #dbe0e5; + font-size: 2em; padding-top: 30px; padding-left: 20px; padding-bottom: 10px; diff --git a/html/skins/alteeve/striker.html b/html/skins/alteeve/striker.html index f2395bd8..01de89ed 100644 --- a/html/skins/alteeve/striker.html +++ b/html/skins/alteeve/striker.html @@ -1,3 +1,38 @@ + + + +
+
+ + + + + + + + + + + + + + + + + +
+   +
+ #!string!striker_0098!# + + +
+ + @@ -102,41 +137,6 @@
- - - -
-
- - - - - - - - - - - - - - - - - -
-   -
- #!string!striker_0098!# - - -
- - diff --git a/share/words.xml b/share/words.xml index e4c3be4b..ba7987d0 100644 --- a/share/words.xml +++ b/share/words.xml @@ -348,6 +348,7 @@ The database connection error was: update_progress() called with the 'job_uuid': [#!variable!job_uuid!#], which was not found. Unable to find the job to update.]]>update_progress() called with 'progress' set to an invalid value: [#!variable!progress!#]. This must be a whole number between '0' and '100' (fractions not allowed).]]> + find_matching_ip(), but it failed to resolve to an IP address.]]>Test @@ -488,6 +489,8 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st JobReboot this system? If you proceed, you will be logged out and this system will be rebooted. Please be sure you have access in the rare chance that the system fails to boot back up.Power off this system? If you proceed, you will be logged out and this system will be powered off. You will need physical access to the machine to turn it back on in most cases. A properly condigured Striker dashboard will power on after a power cycle (via a PDU) or any machine with IPMI if you have access to a machine on the BCN. + The peer will be added to the local configuration shortly. Expect slight performance impacts if there is a lot of data to synchronize. + The peer will be added to the local configuration shortly, and we will be added to their configuration as well. Expect slight performance impacts if there is a lot of data to synchronize.Configure Network @@ -500,6 +503,8 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st This system will be powered off momentarily. It will not respond until it has turned back on.Reboot..Powering off... + Add a Striker Peer + The Striker peer will now be added to the local configuration.The IP address will change. You will need to reconnect after applying these changes. diff --git a/tools/anvil-manage-striker-peers b/tools/anvil-manage-striker-peers index b6f395f4..5d14f4ab 100755 --- a/tools/anvil-manage-striker-peers +++ b/tools/anvil-manage-striker-peers @@ -13,12 +13,16 @@ # ### Show existing entries # /usr/sbin/anvil-manage-striker-peers --list +# ### Add a new entry, or edit an existing one # /usr/sbin/anvil-manage-striker-peers --add --host-uuid e20c3f10-c35d-4543-b5e6-8a373f27977a --host localhost --port 5432 --password-file /tmp/anvil-manage-striker-peers.2e410b43-42a0-4eaf-985c-670f92c482b8 --ping 0 +# ### Edit an existing entry, but don't add it if it wasn't found. # /usr/sbin/anvil-manage-striker-peers --host-uuid e20c3f10-c35d-4543-b5e6-8a373f27977a --host localhost --port 5432 --password-file /tmp/anvil-manage-striker-peers.2e410b43-42a0-4eaf-985c-670f92c482b8 --ping 0 +# ### Remove an entry # /usr/sbin/anvil-manage-striker-peers --remove --host-uuid e20c3f10-c35d-4543-b5e6-8a373f27977a +# use strict; diff --git a/units/anvil-boot-time.service b/units/anvil-boot-time.service deleted file mode 100644 index cb7fde58..00000000 --- a/units/anvil-boot-time.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Anvil! Intelligent Availability Platform - Boot-time tasks -# Don't run until we can talk to our and our peer's databases. -Wants=network.target -Wants=postgresql.service - -[Service] -Type=simple -ExecStart=/usr/sbin/anvil-clear-reboot -ExecStop=/bin/kill -WINCH ${MAINPID} - -[Install] -WantedBy=default.target