Merge pull request #70 from ClusterLabs/webui_anvil_page

* Finished the 'get_X' enpoints so far defined. Added get_servers and…
main
digimer-bot 4 years ago committed by GitHub
commit 75343aadff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 33
      Anvil/Tools/Database.pm
  2. 1
      cgi-bin/Makefile.am
  3. 140
      cgi-bin/get_servers
  4. 176
      cgi-bin/get_status
  5. 5
      share/words.xml

@ -2620,23 +2620,25 @@ Get a list of hosts from the c<< hosts >> table, returned as an array of hash re
Each anonymous hash is structured as: Each anonymous hash is structured as:
host_uuid => $host_uuid, host_uuid => $host_uuid,
host_name => $host_name, host_name => $host_name,
host_type => $host_type, short_host_name => $short_host_name,
host_key => $host_key, host_type => $host_type,
host_ipmi => $host_ipmi, host_key => $host_key,
host_status => $host_status, host_ipmi => $host_ipmi,
modified_date => $modified_date, host_status => $host_status,
modified_date => $modified_date,
It also sets the variables; It also sets the variables;
hosts::host_uuid::<host_uuid>::host_name = <host_name>; hosts::host_uuid::<host_uuid>::host_name = <host_name>;
hosts::host_uuid::<host_uuid>::host_type = <host_type; node, dr or dashboard> hosts::host_uuid::<host_uuid>::short_host_name = <short_host_name>;
hosts::host_uuid::<host_uuid>::host_key = <Machine's public key / fingerprint, set to DELETED when the host is no longer used> hosts::host_uuid::<host_uuid>::host_type = <host_type; node, dr or dashboard>
hosts::host_uuid::<host_uuid>::host_ipmi = <If equiped, this is how to log into the host's IPMI BMC, including the password!> hosts::host_uuid::<host_uuid>::host_key = <Machine's public key / fingerprint, set to DELETED when the host is no longer used>
hosts::host_uuid::<host_uuid>::host_status = <This is the power state of the host. Default is 'unknown', and can be "powered off", "online", "stopping" and "booting.> hosts::host_uuid::<host_uuid>::host_ipmi = <If equiped, this is how to log into the host's IPMI BMC, including the password!>
hosts::host_uuid::<host_uuid>::anvil_name = <anvil_name if associated with an anvil> hosts::host_uuid::<host_uuid>::host_status = <This is the power state of the host. Default is 'unknown', and can be "powered off", "online", "stopping" and "booting.>
hosts::host_uuid::<host_uuid>::anvil_uuid = <anvil_uuid if associated with an anvil> hosts::host_uuid::<host_uuid>::anvil_name = <anvil_name if associated with an anvil>
hosts::host_uuid::<host_uuid>::anvil_uuid = <anvil_uuid if associated with an anvil>
And to simplify look-ups by UUID or name; And to simplify look-ups by UUID or name;
@ -2779,10 +2781,9 @@ WHERE
} }
### TODO: Why does this method exist?
=head2 get_hosts_info =head2 get_hosts_info
This gathers up all the known information about all known hosts. This gathers up all the known information about all known hosts, inlcuding information from the C<< variables >> table linked to each host.
This method takes no parameters. This method takes no parameters.

@ -8,6 +8,7 @@ dist_cgibin_SCRIPTS = \
get_cpu \ get_cpu \
get_memory \ get_memory \
get_replicated_storage \ get_replicated_storage \
get_servers \
get_shared_storage \ get_shared_storage \
get_status \ get_status \
set_membership \ set_membership \

@ -0,0 +1,140 @@
#!/usr/bin/perl
#
# This prints JSON formated data reporting the status of servers on an Anvil! system.
#
use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;
use JSON;
$| = 1;
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
$running_directory =~ s/^\./$ENV{PWD}/;
}
my $anvil = Anvil::Tools->new();
$anvil->Get->switches;
$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});
}
# Read in any CGI variables, if needed.
$anvil->Get->cgi();
$anvil->Database->get_hosts();
$anvil->Database->get_anvils();
print $anvil->Template->get({file => "shared.html", name => "json_headers", show_name => 0})."\n";
my $hash = {};
my $anvil_uuid = "";
if ($anvil->data->{cgi}{anvil_uuid}{value})
{
$anvil_uuid = $anvil->data->{cgi}{anvil_uuid}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }});
}
elsif ($anvil->data->{switches}{'anvil-uuid'})
{
$anvil_uuid = $anvil->data->{switches}{'anvil-uuid'};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }});
}
if ((not $anvil_uuid) or (not exists $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}))
{
$anvil->data->{anvil_status}{anvil_name} = "!!invalid!anvil_uuid!!";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'anvil_status::anvil_name' => $anvil->data->{anvil_status}{anvil_name} }});
}
else
{
my $node1_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $node1_host_name = $anvil->data->{hosts}{host_uuid}{$node1_uuid}{short_host_name};
my $node2_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
my $node2_host_name = $anvil->data->{hosts}{host_uuid}{$node2_uuid}{short_host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
node1_uuid => $node1_uuid,
node1_host_name => $node1_host_name,
node2_uuid => $node2_uuid,
node2_host_name => $node2_host_name,
}});
$hash->{servers} = [];
# For each node, check to see if it's "online" and, if so, if the node is in the cluster.
$anvil->Database->get_hosts_info();
my $query = "
SELECT
server_uuid,
server_name,
server_state,
server_host_uuid
FROM
servers
WHERE
server_anvil_uuid = ".$anvil->Database->quote($anvil_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,
}});
foreach my $row (@{$results})
{
# How online is it?
my $server_uuid = $row->[0];
my $server_name = $row->[1];
my $server_state = $row->[2];
my $server_host_uuid = $row->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
server_uuid => $server_uuid,
server_name => $server_name,
server_state => $server_state,
server_host_uuid => $server_host_uuid,
}});
# Ignore deleted servers.
next if $server_state eq "DELETED";
my $server_host_index = undef;
if ($server_state ne "shut off")
{
if ($server_host_uuid eq $node1_uuid)
{
$server_host_index = 0;
}
elsif ($server_host_uuid eq $node2_uuid)
{
$server_host_index = 1;
}
else
{
# Is it on DR?
}
}
push @{$hash->{servers}}, {
server_uuid => $server_uuid,
server_name => $server_name,
server_state => $server_state,
server_host_uuid => $server_state eq "shut off" ? undef : $server_host_uuid,
server_host_index => $server_host_index,
};
}
}
print JSON->new->utf8->encode($hash)."\n";

@ -60,111 +60,127 @@ else
{ {
my $node1_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}; my $node1_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $node2_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid}; my $node2_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
my $dr1_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
node1_uuid => $node1_uuid, node1_uuid => $node1_uuid,
node2_uuid => $node2_uuid, node2_uuid => $node2_uuid,
dr1_uuid => $dr1_uuid,
}}); }});
my $query = " # For each node, check to see if it's "online" and, if so, if the node is in the cluster.
SELECT $anvil->Database->get_hosts_info();
FROM # Read in the
hosts a, my $node1_status = $anvil->data->{hosts}{host_uuid}{$node1_uuid}{host_status};
scan_filesystems b my $node1_host_name = $anvil->data->{hosts}{host_uuid}{$node1_uuid}{short_host_name};
WHERE my $node2_status = $anvil->data->{hosts}{host_uuid}{$node2_uuid}{host_status};
a.host_uuid = b.scan_filesystem_host_uuid my $node2_host_name = $anvil->data->{hosts}{host_uuid}{$node2_uuid}{short_host_name};
AND
(
a.host_uuid = ".$anvil->Database->quote($node1_uuid)."
OR
a.host_uuid = ".$anvil->Database->quote($node2_uuid);
if ($dr1_uuid)
{
$query .= "
OR
a.host_uuid = ".$anvil->Database->quote($dr1_uuid);
}
$query .= "
)
ORDER BY
a.host_name ASC,
b.scan_filesystem_mount_point DESC
;";
$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 => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results, node1_status => $node1_status,
count => $count, node1_host_name => $node1_host_name,
node2_status => $node2_status,
node2_host_name => $node2_host_name,
}}); }});
foreach my $row (@{$results})
# Array index 0 is node 1, index 1 is node 2.
$hash->{anvil_state} = "optimal";
$hash->{nodes}->[0] = {
host_uuid => $node1_uuid,
'state' => "offline",
state_percent => 0,
state_message => "message_0222,!!host_name!".$node1_host_name."!!",
maintenance_mode => 'undefined',
};
$hash->{nodes}->[1] = {
host_uuid => $node2_uuid,
'state' => "offline",
state_percent => 0,
state_message => "message_0222,!!host_name!".$node2_host_name."!!",
maintenance_mode => 'undefined',
};
foreach my $i (0..1)
{ {
my $host_uuid = $row->[0]; my $host_uuid = $hash->{nodes}->[$i]->{host_uuid};
my $host_name = $row->[1]; my $short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name};
my $mount_point = $row->[2]; my $host_status = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_status};
my $size = $row->[3];
my $used = $row->[4];
my $free = $size - $used;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid, 's1:short_host_name' => $short_host_name,
host_name => $host_name, 's2:host_uuid' => $host_uuid,
mount_point => $mount_point, 's3:host_status' => $host_status,
size => $anvil->Convert->add_commas({number => $size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $size}).")",,
used => $anvil->Convert->add_commas({number => $used})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $used}).")",,
free => $anvil->Convert->add_commas({number => $free})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $free}).")",,
}}); }});
$anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{host_name} = $host_name; # If the node is not "online", nothing else matters.
$anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{total} = $size; next if $host_status ne "online";
$anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{free} = $free;
my $query = "
SELECT
scan_cluster_node_in_ccm,
scan_cluster_node_crmd_member,
scan_cluster_node_cluster_member,
scan_cluster_node_maintenance_mode
FROM
scan_cluster_nodes
WHERE
scan_cluster_node_host_uuid = ".$anvil->Database->quote($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 => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"raw::file_systems::${mount_point}::nodes::${host_uuid}::host_name" => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{host_name}, results => $results,
"raw::file_systems::${mount_point}::nodes::${host_uuid}::total" => $anvil->Convert->add_commas({number => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{total}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{total}}).")",, count => $count,
"raw::file_systems::${mount_point}::nodes::${host_uuid}::free" => $anvil->Convert->add_commas({number => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{free}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{free}}).")",,
}}); }});
}
$anvil->data->{file_systems} = []; if (not $count)
foreach my $mount_point (sort {$a cmp $b} keys %{$anvil->data->{raw}{file_systems}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mount_point => $mount_point }});
$hash->{mount_point} = $mount_point;
$hash->{nodes} = [];
my $nodes = [$node1_uuid, $node2_uuid];
if ($dr1_uuid)
{ {
push @{$nodes}, $dr1_uuid; # Weird, looks like this host isn't a node.
next;
} }
foreach my $host_uuid (@{$nodes}) foreach my $row (@{$results})
{ {
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name}; # How online is it?
my $scan_cluster_node_in_ccm = $row->[0];
my $scan_cluster_node_crmd_member = $row->[1];
my $scan_cluster_node_cluster_member = $row->[2];
my $scan_cluster_node_maintenance_mode = $row->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid, scan_cluster_node_in_ccm => $scan_cluster_node_in_ccm,
host_name => $host_name, scan_cluster_node_crmd_member => $scan_cluster_node_crmd_member,
scan_cluster_node_cluster_member => $scan_cluster_node_cluster_member,
scan_cluster_node_maintenance_mode => $scan_cluster_node_maintenance_mode,
}}); }});
if (exists $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid})
$hash->{nodes}->[$i]->{maintenance_mode} = $scan_cluster_node_maintenance_mode ? 1 : 0;
if ($scan_cluster_node_cluster_member)
{
$hash->{nodes}->[$i]->{'state'} = "online";
$hash->{nodes}->[$i]->{state_percent} = 100;
$hash->{nodes}->[$i]->{state_message} = "message_0223,!!host_name!".$node2_host_name."!!",
}
elsif ($scan_cluster_node_crmd_member)
{ {
push @{$hash->{nodes}}, { $hash->{nodes}->[$i]->{'state'} = "crmd";
host_uuid => $host_uuid, $hash->{nodes}->[$i]->{state_percent} = 75;
host_name => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{host_name}, $hash->{nodes}->[$i]->{state_message} = "message_0224,!!host_name!".$node2_host_name."!!",
is_mounted => 1, }
total => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{total}, elsif ($scan_cluster_node_in_ccm)
free => $anvil->data->{raw}{file_systems}{$mount_point}{nodes}{$host_uuid}{free}, {
} $hash->{nodes}->[$i]->{'state'} = "in_ccm";
$hash->{nodes}->[$i]->{state_percent} = 50;
$hash->{nodes}->[$i]->{state_message} = "message_0225,!!host_name!".$node2_host_name."!!",
} }
else else
{ {
push @{$hash->{nodes}}, { $hash->{nodes}->[$i]->{'state'} = "booted";
host_uuid => $host_uuid, $hash->{nodes}->[$i]->{state_percent} = 25;
host_name => $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name}, $hash->{nodes}->[$i]->{state_message} = "message_0226,!!host_name!".$node2_host_name."!!",
is_mounted => 0,
total => 0,
free => 0,
}
} }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"hash->{nodes}->[".$i."]->{state}" => $hash->{nodes}->[$i]->{'state'},
"hash->{nodes}->[".$i."]->{state_percent}" => $hash->{nodes}->[$i]->{state_percent},
"hash->{nodes}->[".$i."]->{state_message}" => $hash->{nodes}->[$i]->{state_message},
"hash->{nodes}->[".$i."]->{maintenance_mode}" => $hash->{nodes}->[$i]->{maintenance_mode},
}});
} }
} }
} }

@ -1757,6 +1757,11 @@ Are you sure that you want to delete the server: [#!variable!server_name!#]? [Ty
<key name="message_0219">- #!variable!server_name!# (Current state: [#!variable!server_state!#])</key> <key name="message_0219">- #!variable!server_name!# (Current state: [#!variable!server_state!#])</key>
<key name="message_0220">- * #!variable!server_name!# (Deleted, name can be reused)</key> <key name="message_0220">- * #!variable!server_name!# (Deleted, name can be reused)</key>
<key name="message_0221">We're Striker: [#!variable!striker!#], and we're now configured, so we're done. Striker 1 will finish configuration.</key> <key name="message_0221">We're Striker: [#!variable!striker!#], and we're now configured, so we're done. Striker 1 will finish configuration.</key>
<key name="message_0222">The node: [#!variable!host_name!#] is in an unknown state.</key>
<key name="message_0223">The node: [#!variable!host_name!#] is a full cluster member.</key>
<key name="message_0224">The node: [#!variable!host_name!#] is coming online; the cluster resource manager is running. (step 2/3)</key>
<key name="message_0225">The node: [#!variable!host_name!#] is coming online; the node is a consensus cluster member. (step 1/3)</key>
<key name="message_0226">The node: [#!variable!host_name!#] has booted, but it is not (yet) joining the cluster.</key>
<!-- Success messages shown to the user --> <!-- Success messages shown to the user -->
<key name="ok_0001">Saved the mail server information successfully!</key> <key name="ok_0001">Saved the mail server information successfully!</key>

Loading…
Cancel
Save