* Renamed Network->match_gateway() to ->is_ip_in_network(), and changed the parameters 'gateway -> ip' and 'ip_address -> network'. This is to clarify it's use as a general purpose "does this IP fall in the given network range?".

* Created the shell of Striker->generate_manifest() that will pull out CGI data to generate the install manifest itself and save/update it.
* Got step 3 menu finished along with the corresponding sanity checks.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent e54aaad807
commit 23c17dbb98
  1. 50
      Anvil/Tools/Network.pm
  2. 19
      Anvil/Tools/Striker.pm
  3. 577
      cgi-bin/striker
  4. 190
      html/skins/alteeve/anvil.html
  5. 13
      share/words.xml

@ -23,7 +23,7 @@ my $THIS_FILE = "Network.pm";
# is_local # is_local
# load_interfces # load_interfces
# load_ips # load_ips
# match_gateway # is_ip_in_network
# ping # ping
# read_nmcli # read_nmcli
@ -1956,66 +1956,64 @@ sub is_local
return($anvil->data->{cache}{is_local}{$host}); return($anvil->data->{cache}{is_local}{$host});
} }
=head2 match_gateway =head2 is_ip_in_network
This takes a gateway and the IP address / subnet mask and sees if the gateway matches that network. If it does, it returns C<< 1 >>. If the gateway doesn't match the network, C<< 0 >> is returned. This takes an IP address, along with network and subnet mask and sees if the IP address is within the network. If it is, it returns C<< 1 >>. If the IP address doesn't match the network, C<< 0 >> is returned.
B<< Note >>: This can be used to test if any given IP is within subnet, of course. The name comes from the primary use of this method.
Parameters Parameters
=head3 gateway (required) =head3 ip (required)
This is the gateway IP address being analyzed. This is the ip IP address being analyzed.
=head3 ip_address (required) =head3 network (required)
This is the IP address that will be paired with the subnet mask to see if the gateway matches. This is the IP address that will be paired with the subnet mask to see if the ip matches.
=head3 subnet_mask (required) =head3 subnet_mask (required)
This is the subnet mask paired against the IP address used to check the gateway against. This is the subnet mask paired against the IP address used to check the ip against.
=cut =cut
sub match_gateway sub is_ip_in_network
{ {
my $self = shift; my $self = shift;
my $parameter = shift; my $parameter = shift;
my $anvil = $self->parent; my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
my $gateway = defined $parameter->{gateway} ? $parameter->{gateway} : ""; my $ip = defined $parameter->{ip} ? $parameter->{ip} : "";
my $ip_address = defined $parameter->{ip_address} ? $parameter->{ip_address} : ""; my $network = defined $parameter->{network} ? $parameter->{network} : "";
my $subnet_mask = defined $parameter->{subnet_mask} ? $parameter->{subnet_mask} : ""; my $subnet_mask = defined $parameter->{subnet_mask} ? $parameter->{subnet_mask} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
gateway => $gateway, ip => $ip,
ip_address => $ip_address, network => $network,
subnet_mask => $subnet_mask, subnet_mask => $subnet_mask,
}}); }});
if (not $ip_address) if (not $network)
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->match_gateway()", parameter => "ip_address" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->is_ip_in_network()", parameter => "network" }});
return(0); return(0);
} }
elsif (not $anvil->Validate->is_ipv4({ip => $ip_address})) elsif (not $anvil->Validate->is_ipv4({ip => $network}))
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "warning_0019", variables => { parameter => "ip_address", ip_address => $ip_address }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "warning_0019", variables => { parameter => "network", network => $network }});
return(0); return(0);
} }
if (not $gateway) if (not $ip)
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->match_gateway()", parameter => "gateway" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->is_ip_in_network()", parameter => "ip" }});
return(0); return(0);
} }
elsif (not $anvil->Validate->is_ipv4({ip => $gateway})) elsif (not $anvil->Validate->is_ipv4({ip => $ip}))
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "warning_0019", variables => { parameter => "gateway", ip_address => $gateway }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "warning_0019", variables => { parameter => "ip", network => $ip }});
return(0); return(0);
} }
if (not $subnet_mask) if (not $subnet_mask)
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->match_gateway()", parameter => "subnet_mask" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Network->is_ip_in_network()", parameter => "subnet_mask" }});
return(0); return(0);
} }
elsif (not $anvil->Validate->is_subnet_mask({subnet_mask => $subnet_mask})) elsif (not $anvil->Validate->is_subnet_mask({subnet_mask => $subnet_mask}))
@ -2025,8 +2023,8 @@ sub match_gateway
} }
my $match = 0; my $match = 0;
my $block = Net::Netmask->new($ip_address."/".$subnet_mask); my $block = Net::Netmask->new($network."/".$subnet_mask);
if ($block->match($gateway)) if ($block->match($ip))
{ {
# This is a match! # This is a match!
$match = 1; $match = 1;

@ -13,6 +13,7 @@ our $VERSION = "3.0.0";
my $THIS_FILE = "Striker.pm"; my $THIS_FILE = "Striker.pm";
### Methods; ### Methods;
# generate_manifest
# get_fence_data # get_fence_data
# get_local_repo # get_local_repo
# get_peer_data # get_peer_data
@ -79,6 +80,24 @@ sub parent
# Public methods # # Public methods #
############################################################################################################# #############################################################################################################
=head2 generate_manifest
This reads the CGI data coming from the manifest form to generate the manifest JSON.
=cut
sub generate_manifest
{
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 => "Striker->get_fence_data()" }});
my $manifest_uuid = "";
return($manifest_uuid);
}
=head2 get_fence_data =head2 get_fence_data
This parses the unified metadata file from the avaialable fence_devices on this host. If the unified file (location stored in C<< path::data::fences_unified_metadata >>, default is C<< /tmp/fences_unified_metadata.xml >> is not found or fails to parse, C<< 1 >> is returned. If the file is successfully parsed. C<< 0 >> is returned. This parses the unified metadata file from the avaialable fence_devices on this host. If the unified file (location stored in C<< path::data::fences_unified_metadata >>, default is C<< /tmp/fences_unified_metadata.xml >> is not found or fails to parse, C<< 1 >> is returned. If the file is successfully parsed. C<< 0 >> is returned.

@ -1543,6 +1543,8 @@ sub handle_manifest
$anvil->data->{cgi}{sequence}{alert} = 0 if not defined $anvil->data->{cgi}{sequence}{alert}; $anvil->data->{cgi}{sequence}{alert} = 0 if not defined $anvil->data->{cgi}{sequence}{alert};
$anvil->data->{cgi}{bcn_count}{value} = 1 if not defined $anvil->data->{cgi}{bcn_count}{value}; $anvil->data->{cgi}{bcn_count}{value} = 1 if not defined $anvil->data->{cgi}{bcn_count}{value};
$anvil->data->{cgi}{bcn_count}{alert} = 0 if not defined $anvil->data->{cgi}{bcn_count}{alert}; $anvil->data->{cgi}{bcn_count}{alert} = 0 if not defined $anvil->data->{cgi}{bcn_count}{alert};
$anvil->data->{cgi}{sn_count}{value} = 1 if not defined $anvil->data->{cgi}{sn_count}{value};
$anvil->data->{cgi}{sn_count}{alert} = 0 if not defined $anvil->data->{cgi}{sn_count}{alert};
$anvil->data->{cgi}{ifn_count}{value} = 1 if not defined $anvil->data->{cgi}{ifn_count}{value}; $anvil->data->{cgi}{ifn_count}{value} = 1 if not defined $anvil->data->{cgi}{ifn_count}{value};
$anvil->data->{cgi}{ifn_count}{alert} = 0 if not defined $anvil->data->{cgi}{ifn_count}{alert}; $anvil->data->{cgi}{ifn_count}{alert} = 0 if not defined $anvil->data->{cgi}{ifn_count}{alert};
$anvil->data->{cgi}{dns}{value} = "8.8.8.8,8.8.4.4" if not defined $anvil->data->{cgi}{dns}{value}; $anvil->data->{cgi}{dns}{value} = "8.8.8.8,8.8.4.4" if not defined $anvil->data->{cgi}{dns}{value};
@ -1557,6 +1559,7 @@ sub handle_manifest
"cgi::domain::value" => $anvil->data->{cgi}{domain}{value}, "cgi::domain::value" => $anvil->data->{cgi}{domain}{value},
"cgi::sequence::value" => $anvil->data->{cgi}{sequence}{value}, "cgi::sequence::value" => $anvil->data->{cgi}{sequence}{value},
"cgi::bcn_count::value" => $anvil->data->{cgi}{bcn_count}{value}, "cgi::bcn_count::value" => $anvil->data->{cgi}{bcn_count}{value},
"cgi::sn_count::value" => $anvil->data->{cgi}{sn_count}{value},
"cgi::ifn_count::value" => $anvil->data->{cgi}{ifn_count}{value}, "cgi::ifn_count::value" => $anvil->data->{cgi}{ifn_count}{value},
"cgi::dns::value" => $anvil->data->{cgi}{dns}{value}, "cgi::dns::value" => $anvil->data->{cgi}{dns}{value},
"cgi::ntp::value" => $anvil->data->{cgi}{ntp}{value}, "cgi::ntp::value" => $anvil->data->{cgi}{ntp}{value},
@ -1583,6 +1586,25 @@ sub handle_manifest
$anvil->data->{cgi}{step}{value} = 2; $anvil->data->{cgi}{step}{value} = 2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::step::value" => $anvil->data->{cgi}{step}{value} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::step::value" => $anvil->data->{cgi}{step}{value} }});
} }
elsif ($anvil->data->{cgi}{step}{value} > 3)
{
my ($sane) = sanity_check_manifest_step3($anvil);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sane => $sane }});
if (not $sane)
{
# Go back to the third page
$anvil->data->{cgi}{step}{value} = 3;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::step::value" => $anvil->data->{cgi}{step}{value} }});
}
else
{
# Save the manifest!
$anvil->data->{cgi}{step}{value} = 3;
# my ($manifest_uuid) = $anvil->Striker->generate_manifest({
#
# });
}
}
} }
} }
@ -1719,22 +1741,45 @@ sub handle_manifest
}}); }});
} }
# There's only ever 1 SN # There's only ever 1 SN. Just in case we change our mind later, we'll set it up as if it's
my $say_sn = $anvil->Words->string({key => "striker_0020", variables => { number => '1' }}); # variable.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_sn => $say_sn }}); foreach my $i (1..$anvil->data->{cgi}{bcn_count}{value})
{
$anvil->data->{cgi}{sn1_network}{value} = "10.101.0.0" if not defined $anvil->data->{cgi}{sn1_network}{value}; my $say_sn = $anvil->Words->string({key => "striker_0020", variables => { number => '1' }});
$anvil->data->{cgi}{sn1_network}{alert} = 0 if not defined $anvil->data->{cgi}{sn1_network}{alert}; my $network_key = "sn".$i."_network";
$anvil->data->{cgi}{sn1_subnet}{value} = "255.255.0.0" if not defined $anvil->data->{cgi}{sn1_subnet}{value}; my $subnet_key = "sn".$i."_subnet";
$anvil->data->{cgi}{sn1_subnet}{alert} = 0 if not defined $anvil->data->{cgi}{sn1_subnet}{alert}; my $gateway_key = "sn".$i."_gateway";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::sn1_network::value" => $anvil->data->{cgi}{sn1_network}{value} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step2-network-entry", variables => { say_sn => $say_sn,
network => $say_sn, network_key => $network_key,
network_name => "sn1_network", subnet_key => $subnet_key,
network_class => $anvil->data->{cgi}{sn1_network}{alert} ? "input_alert" : "", gateway_key => $gateway_key,
network_value => $anvil->data->{cgi}{sn1_network}{value}, }});
subnet => '255.255.0.0 <input type="hidden" name="sn1_subnet" id="sn1_subnet" value="'.$anvil->data->{cgi}{sn1_subnet}{value}.'" />',
}}); $anvil->data->{cgi}{$network_key}{value} = "10.10".$i.".0.0" if not defined $anvil->data->{cgi}{$network_key}{value};
$anvil->data->{cgi}{$network_key}{alert} = 0 if not defined $anvil->data->{cgi}{$network_key}{alert};
$anvil->data->{cgi}{$subnet_key}{value} = "255.255.0.0" if not defined $anvil->data->{cgi}{$subnet_key}{value};
$anvil->data->{cgi}{$subnet_key}{alert} = 0 if not defined $anvil->data->{cgi}{$subnet_key}{alert};
$anvil->data->{cgi}{$gateway_key}{value} = "" if not defined $anvil->data->{cgi}{$gateway_key}{value};
$anvil->data->{cgi}{$gateway_key}{alert} = 0 if not defined $anvil->data->{cgi}{$gateway_key}{alert};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::sn1_network::value" => $anvil->data->{cgi}{sn1_network}{value} }});
$network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step2-network-entry", variables => {
network => $say_sn,
network_name => $network_key,
network_class => $anvil->data->{cgi}{$network_key}{alert} ? "input_alert" : "",
network_value => $anvil->data->{cgi}{$network_key}{value},
subnet => '255.255.0.0 <input type="hidden" name="'.$network_key.'" id="'.$network_key.'" value="'.$anvil->data->{cgi}{sn1_subnet}{value}.'" />',
}});
}
# Now IFNs # Now IFNs
foreach my $i (1..$anvil->data->{cgi}{ifn_count}{value}) foreach my $i (1..$anvil->data->{cgi}{ifn_count}{value})
@ -1787,8 +1832,12 @@ sub handle_manifest
}}); }});
} }
$anvil->data->{form}{back_link} = "?anvil=true&task=manifests&manifest_uuid=".$anvil->data->{cgi}{manifest_uuid}{value}."&step=1&prefix=".$anvil->data->{cgi}{prefix}{value}."&domain=".$anvil->data->{cgi}{domain}{value}."&sequence=".$anvil->data->{cgi}{sequence}{value}."&ifn_count=".$anvil->data->{cgi}{ifn_count}{value}; my $back_link = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{refresh_link} = "?anvil=true&task=manifests&manifest_uuid=".$anvil->data->{cgi}{manifest_uuid}{value}."&step=2&prefix=".$anvil->data->{cgi}{prefix}{value}."&domain=".$anvil->data->{cgi}{domain}{value}."&sequence=".$anvil->data->{cgi}{sequence}{value}."&ifn_count=".$anvil->data->{cgi}{ifn_count}{value}; $back_link =~ s/step=2/step=1/;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { back_link => $back_link}});
$anvil->data->{form}{back_link} = $back_link;
$anvil->data->{form}{refresh_link} = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "manifest-step2", variables => { $anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "manifest-step2", variables => {
title => $anvil->Words->string({key => "striker_0226", variables => { number => 2 }}), title => $anvil->Words->string({key => "striker_0226", variables => { number => 2 }}),
networks => $network_form, networks => $network_form,
@ -1804,116 +1853,264 @@ sub handle_manifest
elsif ($anvil->data->{cgi}{step}{value} eq "3") elsif ($anvil->data->{cgi}{step}{value} eq "3")
{ {
# Build and show the main manifest page! # Build and show the main manifest page!
$anvil->data->{cgi}{node1_ipmi_ip}{value} = "" if not defined $anvil->data->{cgi}{node1_ipmi_ip}{value};
$anvil->data->{cgi}{node1_ipmi_ip}{alert} = 0 if not defined $anvil->data->{cgi}{node1_ipmi_ip}{alert};
$anvil->data->{cgi}{node2_ipmi_ip}{value} = "" if not defined $anvil->data->{cgi}{node2_ipmi_ip}{value};
$anvil->data->{cgi}{node2_ipmi_ip}{alert} = 0 if not defined $anvil->data->{cgi}{node2_ipmi_ip}{alert};
$anvil->data->{cgi}{dr1_ipmi_ip}{value} = "" if not defined $anvil->data->{cgi}{dr1_ipmi_ip}{value};
$anvil->data->{cgi}{dr1_ipmi_ip}{alert} = 0 if not defined $anvil->data->{cgi}{dr1_ipmi_ip}{alert};
my $sequence = $anvil->data->{cgi}{sequence}{value}; my $sequence = $anvil->data->{cgi}{sequence}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sequence => $sequence }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { sequence => $sequence }});
my $network_form = ""; my $network_form = "";
my $ipmi_ip_guess = ""; my $network_note = "";
foreach my $i (1..$anvil->data->{cgi}{bcn_count}{value}) foreach my $network ("bcn", "sn", "ifn")
{ {
my $say_bcn = $anvil->Words->string({key => "striker_0018", variables => { number => $i }}); if ($network eq "sn")
my $network_key = "bcn".$i."_network"; {
my $subnet_key = "bcn".$i."_subnet"; # We've finished BCN, inject the IPMI.
my $gateway_key = "bcn".$i."_gateway"; $network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-ipmi-entry", variables => {
my $node1_network_key = "node1_bcn".$i."_network"; node1_value => $anvil->data->{cgi}{node1_ipmi_ip}{value},
my $node2_network_key = "node2_bcn".$i."_network"; node1_class => $anvil->data->{cgi}{node1_ipmi_ip}{alert} ? "input_alert" : "",
my $dr1_network_key = "dr1_bcn".$i."_network"; node2_value => $anvil->data->{cgi}{node2_ipmi_ip}{value},
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node2_class => $anvil->data->{cgi}{node2_ipmi_ip}{alert} ? "input_alert" : "",
say_bcn => $say_bcn, dr1_value => $anvil->data->{cgi}{dr1_ipmi_ip}{value},
network_key => $network_key, dr1_class => $anvil->data->{cgi}{dr1_ipmi_ip}{alert} ? "input_alert" : "",
subnet_key => $subnet_key, }});
gateway_key => $gateway_key, }
node1_network_key => $node1_network_key,
node2_network_key => $node2_network_key,
dr1_network_key => $dr1_network_key,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
}});
# On the BCN, we can confidently take the first two octets from 'network' and add our my $count_key = $network."_count";
# guesses to the last two octets. foreach my $i (1..$anvil->data->{cgi}{$count_key}{value})
if ($anvil->data->{cgi}{$network_key}{value} =~ /^(\d{1,3}\.\d{1,3})\.0\.0/)
{ {
my $first_two_octets = $1; my $say_network_code = "striker_0018";
my $ip_third_octet = 8 + (2 * $sequence); # Thanks to Leigh Nunan (@leighnunan) for this elegant sequence formula if ($network eq "sn") { $say_network_code = "striker_0020"; }
my $host_ip = $first_two_octets.".".$ip_third_octet; elsif ($network eq "ifn") { $say_network_code = "striker_0022"; }
my $say_network = $anvil->Words->string({key => $say_network_code, variables => { number => $i }});
my $network_key = $network.$i."_network";
my $subnet_key = $network.$i."_subnet";
my $gateway_key = $network.$i."_gateway";
my $node1_network_key = "node1_".$network.$i."_network";
my $node2_network_key = "node2_".$network.$i."_network";
my $dr1_network_key = "dr1_".$network.$i."_network";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
first_two_octets => $first_two_octets, say_bcn => $say_network,
ip_third_octet => $ip_third_octet, network_key => $network_key,
host_ip => $host_ip, subnet_key => $subnet_key,
gateway_key => $gateway_key,
node1_network_key => $node1_network_key,
node2_network_key => $node2_network_key,
dr1_network_key => $dr1_network_key,
}}); }});
$anvil->data->{cgi}{$node1_network_key}{value} = $host_ip.".1" if not defined $anvil->data->{cgi}{$node1_network_key}{value};
$anvil->data->{cgi}{$node2_network_key}{value} = $host_ip.".2" if not defined $anvil->data->{cgi}{$node2_network_key}{value};
$anvil->data->{cgi}{$dr1_network_key}{value} = $host_ip.".3" if not defined $anvil->data->{cgi}{$dr1_network_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${node1_network_key}::value" => $anvil->data->{cgi}{$node1_network_key}{value}, "cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${node2_network_key}::value" => $anvil->data->{cgi}{$node2_network_key}{value}, "cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${dr1_network_key}::value" => $anvil->data->{cgi}{$dr1_network_key}{value}, "cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${gateway_key}::value" => $anvil->data->{cgi}{$gateway_key}{value},
"cgi::${gateway_key}::alert" => $anvil->data->{cgi}{$gateway_key}{alert},
}});
# The note also shows the network range.
my $message = $anvil->Words->string({key => "striker_0267", variables => { network => $anvil->data->{cgi}{$network_key}{value}."/".$anvil->data->{cgi}{$subnet_key}{value} }});
$network_note .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-network-note-entry", variables => {
name => $say_network,
message => $message,
}}); }});
# If $i = 1, build the IPMI IP guess # On the BCN and SN, we can confidently take the first two octets from
if ($i == 1) # 'network' and add our guesses to the last two octets. We only guess the IFN
# if it's /16 or a larger subnet.
if ($anvil->data->{cgi}{$network_key}{value} =~ /^(\d{1,3}\.\d{1,3})\.0\.0/)
{ {
my $ipmi_third_octet = 8 + (2 * $sequence) + 1; my $first_two_octets = $1;
$ipmi_ip_guess = $first_two_octets.".".$ipmi_third_octet; my $ip_third_octet = 8 + (2 * $sequence); # Thanks to Leigh Nunan (@leighnunan) for this elegant sequence formula
my $host_ip = $first_two_octets.".".$ip_third_octet;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ipmi_third_octet => $ipmi_third_octet, first_two_octets => $first_two_octets,
ipmi_ip_guess => $ipmi_ip_guess, ip_third_octet => $ip_third_octet,
host_ip => $host_ip,
}}); }});
$anvil->data->{cgi}{node1_ipmi_ip}{value} = $ipmi_ip_guess.".1" if not defined $anvil->data->{cgi}{node1_ipmi_ip}{value}; $anvil->data->{cgi}{$node1_network_key}{value} = $host_ip.".1" if not defined $anvil->data->{cgi}{$node1_network_key}{value};
$anvil->data->{cgi}{node2_ipmi_ip}{value} = $ipmi_ip_guess.".2" if not defined $anvil->data->{cgi}{node2_ipmi_ip}{value}; $anvil->data->{cgi}{$node2_network_key}{value} = $host_ip.".2" if not defined $anvil->data->{cgi}{$node2_network_key}{value};
$anvil->data->{cgi}{dr1_ipmi_ip}{value} = $ipmi_ip_guess.".3" if not defined $anvil->data->{cgi}{dr1_ipmi_ip}{value}; $anvil->data->{cgi}{$dr1_network_key}{value} = $host_ip.".3" if not defined $anvil->data->{cgi}{$dr1_network_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::node1_ipmi_ip::value" => $anvil->data->{cgi}{node1_ipmi_ip}{value}, "cgi::${node1_network_key}::value" => $anvil->data->{cgi}{$node1_network_key}{value},
"cgi::node2_ipmi_ip::value" => $anvil->data->{cgi}{node2_ipmi_ip}{value}, "cgi::${node2_network_key}::value" => $anvil->data->{cgi}{$node2_network_key}{value},
"cgi::dr1_ipmi_ip::value" => $anvil->data->{cgi}{dr1_ipmi_ip}{value}, "cgi::${dr1_network_key}::value" => $anvil->data->{cgi}{$dr1_network_key}{value},
}}); }});
# If this is the BCN and $i = 1, build the IPMI IP guess.
if (($network eq "bcn") && ($i == 1))
{
my $ipmi_third_octet = 8 + (2 * $sequence) + 1;
my $ipmi_ip_guess = $first_two_octets.".".$ipmi_third_octet;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ipmi_third_octet => $ipmi_third_octet,
ipmi_ip_guess => $ipmi_ip_guess,
}});
$anvil->data->{cgi}{node1_ipmi_ip}{value} = $ipmi_ip_guess.".1" if not $anvil->data->{cgi}{node1_ipmi_ip}{value};
$anvil->data->{cgi}{node2_ipmi_ip}{value} = $ipmi_ip_guess.".2" if not $anvil->data->{cgi}{node2_ipmi_ip}{value};
$anvil->data->{cgi}{dr1_ipmi_ip}{value} = $ipmi_ip_guess.".3" if not $anvil->data->{cgi}{dr1_ipmi_ip}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::node1_ipmi_ip::value" => $anvil->data->{cgi}{node1_ipmi_ip}{value},
"cgi::node2_ipmi_ip::value" => $anvil->data->{cgi}{node2_ipmi_ip}{value},
"cgi::dr1_ipmi_ip::value" => $anvil->data->{cgi}{dr1_ipmi_ip}{value},
}});
}
} }
# It should never happen, but in case the regex missed, set the guessed IPs to empty strings.
$anvil->data->{cgi}{$node1_network_key}{value} = "" if not $anvil->data->{cgi}{$node1_network_key}{value};
$anvil->data->{cgi}{$node2_network_key}{value} = "" if not $anvil->data->{cgi}{$node2_network_key}{value};
$anvil->data->{cgi}{$dr1_network_key}{value} = "" if not $anvil->data->{cgi}{$dr1_network_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${node1_network_key}::value" => $anvil->data->{cgi}{$node1_network_key}{value},
"cgi::${node2_network_key}::value" => $anvil->data->{cgi}{$node2_network_key}{value},
"cgi::${dr1_network_key}::value" => $anvil->data->{cgi}{$dr1_network_key}{value},
}});
$network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-network-entry", variables => {
network => $say_network,
network_name => $network_key,
network_value => $anvil->data->{cgi}{$network_key}{value},
subnet_name => $subnet_key,
subnet_value => $anvil->data->{cgi}{$subnet_key}{value},
gateway_name => $gateway_key,
gateway_value => $anvil->data->{cgi}{$gateway_key}{value},
node1_network_name => $node1_network_key,
node1_network_value => $anvil->data->{cgi}{$node1_network_key}{value},
node1_network_class => $anvil->data->{cgi}{$node1_network_key}{alert} ? "input_alert" : "",
node2_network_name => $node2_network_key,
node2_network_value => $anvil->data->{cgi}{$node2_network_key}{value},
node2_network_class => $anvil->data->{cgi}{$node2_network_key}{alert} ? "input_alert" : "",
dr1_network_name => $dr1_network_key,
dr1_network_value => $anvil->data->{cgi}{$dr1_network_key}{value},
dr1_network_class => $anvil->data->{cgi}{$dr1_network_key}{alert} ? "input_alert" : "",
}});
}
}
# List any known fence devices.
my $fence_form = "";
$anvil->Database->get_fences({});
foreach my $fence_name (sort {$a cmp $b} keys %{$anvil->data->{fences}{fence_name}})
{
### NOTE: For now, we don't care about DR fencing. As such, the code to track it is
### commented out (in case we decide to track it someday down the road).
my $fence_uuid = $anvil->data->{fences}{fence_name}{$fence_name}{fence_uuid};
my $node1_fence_key = "node1_fence_".$fence_name;
my $node2_fence_key = "node2_fence_".$fence_name;
#my $dr1_fence_key = "dr1_fence_".$fence_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
fence_name => $fence_name,
fence_uuid => $fence_uuid,
node1_fence_key => $node1_fence_key,
node2_fence_key => $node2_fence_key,
# dr1_fence_key => $dr1_fence_key,
}});
$anvil->data->{cgi}{$node1_fence_key}{value} = "" if not defined $anvil->data->{cgi}{$node1_fence_key}{value};
$anvil->data->{cgi}{$node1_fence_key}{alert} = 0 if not defined $anvil->data->{cgi}{$node1_fence_key}{alert};
$anvil->data->{cgi}{$node2_fence_key}{value} = "" if not defined $anvil->data->{cgi}{$node2_fence_key}{value};
$anvil->data->{cgi}{$node2_fence_key}{alert} = 0 if not defined $anvil->data->{cgi}{$node2_fence_key}{alert};
#$anvil->data->{cgi}{$dr1_fence_key}{value} = "" if not defined $anvil->data->{cgi}{$dr1_fence_key}{value};
#$anvil->data->{cgi}{$dr1_fence_key}{alert} = 0 if not defined $anvil->data->{cgi}{$dr1_fence_key}{alert};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${node1_fence_key}::value" => $anvil->data->{cgi}{$node1_fence_key}{value},
"cgi::${node1_fence_key}::alert" => $anvil->data->{cgi}{$node1_fence_key}{alert},
"cgi::${node2_fence_key}::value" => $anvil->data->{cgi}{$node2_fence_key}{value},
"cgi::${node2_fence_key}::alert" => $anvil->data->{cgi}{$node2_fence_key}{alert},
# "cgi::${dr1_fence_key}::value" => $anvil->data->{cgi}{$dr1_fence_key}{value},
# "cgi::${dr1_fence_key}::alert" => $anvil->data->{cgi}{$dr1_fence_key}{alert},
}});
$fence_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-fence-entry", variables => {
name => $fence_name,
fence_uuid_name => "fence_".$fence_name,
fence_uuid_value => $fence_uuid,
node1_fence_name => $node1_fence_key,
node1_fence_value => $anvil->data->{cgi}{$node1_fence_key}{value},
node1_fence_class => $anvil->data->{cgi}{$node1_fence_key}{alert} ? "input_alert" : "",
node2_fence_name => $node2_fence_key,
node2_fence_value => $anvil->data->{cgi}{$node2_fence_key}{value},
node2_fence_class => $anvil->data->{cgi}{$node2_fence_key}{alert} ? "input_alert" : "",
# dr1_fence_name => $dr1_fence_key,
# dr1_fence_value => $anvil->data->{cgi}{$dr1_fence_key}{value},
# dr1_fence_class => $anvil->data->{cgi}{$dr1_fence_key}{alert} ? "input_alert" : "",
}});
}
my $ups_form = "";
$anvil->Database->get_upses({});
foreach my $ups_name (sort {$a cmp $b} keys %{$anvil->data->{upses}{ups_name}})
{
### NOTE: For now, we don't care about DR UPSes. As such, the code to track it is
### commented out (in case we decide to track it someday down the road).
my $ups_uuid = $anvil->data->{upses}{ups_name}{$ups_name}{ups_uuid};
my $node1_ups_key = "node1_ups_".$ups_name;
my $node2_ups_key = "node2_ups_".$ups_name;
#my $dr1_ups_key = "dr1_ups_".$ups_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
ups_name => $ups_name,
ups_uuid => $ups_uuid,
node1_ups_key => $node1_ups_key,
node2_ups_key => $node2_ups_key,
# dr1_ups_key => $dr1_ups_key,
}});
# Checkboxes that are not checked do not return anything at all. To deal with this,
# if we're reloading, we use 'undefined' as "not checked". Otherwise, "undefined" is
# "checked" (default).
if ((exists $anvil->data->{cgi}{reload}) && ($anvil->data->{cgi}{reload}{value}))
{
$anvil->data->{cgi}{$node1_ups_key}{value} = "" if not defined $anvil->data->{cgi}{$node1_ups_key}{value};
$anvil->data->{cgi}{$node2_ups_key}{value} = "" if not defined $anvil->data->{cgi}{$node2_ups_key}{value};
#$anvil->data->{cgi}{$dr1_ups_key}{value} = "" if not defined $anvil->data->{cgi}{$dr1_ups_key}{value};
}
else
{
$anvil->data->{cgi}{$node1_ups_key}{value} = "checked" if not defined $anvil->data->{cgi}{$node1_ups_key}{value};
$anvil->data->{cgi}{$node2_ups_key}{value} = "checked" if not defined $anvil->data->{cgi}{$node2_ups_key}{value};
#$anvil->data->{cgi}{$dr1_ups_key}{value} = "" if not defined $anvil->data->{cgi}{$dr1_ups_key}{value};
} }
# It should never happen, but in case the regex missed, set the guessed IPs to empty strings. $anvil->data->{cgi}{$node1_ups_key}{value} = "checked" if $anvil->data->{cgi}{$node1_ups_key}{value} eq "on";
$anvil->data->{cgi}{$node1_network_key}{value} = "" if not defined $anvil->data->{cgi}{$node1_network_key}{value}; $anvil->data->{cgi}{$node2_ups_key}{value} = "checked" if $anvil->data->{cgi}{$node2_ups_key}{value} eq "on";
$anvil->data->{cgi}{$node2_network_key}{value} = "" if not defined $anvil->data->{cgi}{$node2_network_key}{value}; #$anvil->data->{cgi}{$dr1_ups_key}{value} = "checked" if $anvil->data->{cgi}{$dr1_ups_key}{value} eq "on";
$anvil->data->{cgi}{$dr1_network_key}{value} = "" if not defined $anvil->data->{cgi}{$dr1_network_key}{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${node1_network_key}::value" => $anvil->data->{cgi}{$node1_network_key}{value}, "cgi::${node1_ups_key}::value" => $anvil->data->{cgi}{$node1_ups_key}{value},
"cgi::${node2_network_key}::value" => $anvil->data->{cgi}{$node2_network_key}{value}, "cgi::${node2_ups_key}::value" => $anvil->data->{cgi}{$node2_ups_key}{value},
"cgi::${dr1_network_key}::value" => $anvil->data->{cgi}{$dr1_network_key}{value}, # "cgi::${dr1_ups_key}::value" => $anvil->data->{cgi}{$dr1_ups_key}{value},
}}); }});
$network_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-network-entry", variables => { $ups_form .= $anvil->Template->get({file => "anvil.html", name => "manifest-step3-ups-entry", variables => {
network => $say_bcn, name => $ups_name,
network_name => $network_key, ups_uuid_name => "ups_".$ups_name,
network_value => $anvil->data->{cgi}{$network_key}{value}, ups_uuid_value => $ups_uuid,
subnet_name => $subnet_key, node1_ups_name => $node1_ups_key,
subnet_value => $anvil->data->{cgi}{$subnet_key}{value}, node1_ups_checked => $anvil->data->{cgi}{$node1_ups_key}{value},
gateway_name => $gateway_key, node2_ups_name => $node2_ups_key,
gateway_value => $anvil->data->{cgi}{$gateway_key}{value}, node2_ups_checked => $anvil->data->{cgi}{$node2_ups_key}{value},
node1_network_name => $node1_network_key, # dr1_ups_name => $dr1_ups_key,
node1_network_value => $anvil->data->{cgi}{$node1_network_key}{value}, # dr1_ups_checked => $anvil->data->{cgi}{$dr1_ups_key}{value},
node1_network_class => $anvil->data->{cgi}{$node1_network_key}{alert} ? "input_alert" : "",
node2_network_name => $node2_network_key,
node2_network_value => $anvil->data->{cgi}{$node2_network_key}{value},
node2_network_class => $anvil->data->{cgi}{$node2_network_key}{alert} ? "input_alert" : "",
dr1_network_name => $dr1_network_key,
dr1_network_value => $anvil->data->{cgi}{$dr1_network_key}{value},
dr1_network_class => $anvil->data->{cgi}{$dr1_network_key}{alert} ? "input_alert" : "",
}}); }});
} }
$anvil->data->{form}{back_link} = "?anvil=true&task=manifests&manifest_uuid=".$anvil->data->{cgi}{manifest_uuid}{value}."&step=1&prefix=".$anvil->data->{cgi}{prefix}{value}."&domain=".$anvil->data->{cgi}{domain}{value}."&sequence=".$anvil->data->{cgi}{sequence}{value}."&ifn_count=".$anvil->data->{cgi}{ifn_count}{value}; my $back_link = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{refresh_link} = "?anvil=true&task=manifests&manifest_uuid=".$anvil->data->{cgi}{manifest_uuid}{value}."&step=2&prefix=".$anvil->data->{cgi}{prefix}{value}."&domain=".$anvil->data->{cgi}{domain}{value}."&sequence=".$anvil->data->{cgi}{sequence}{value}."&ifn_count=".$anvil->data->{cgi}{ifn_count}{value}; $back_link =~ s/step=3/step=2/;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { back_link => $back_link}});
$anvil->data->{form}{back_link} = $back_link;
$anvil->data->{form}{refresh_link} = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "manifest-step3", variables => { $anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "manifest-step3", variables => {
title => $anvil->Words->string({key => "striker_0226", variables => { number => 3 }}), title => $anvil->Words->string({key => "striker_0226", variables => { number => 3 }}),
networks => $network_form, networks => $network_form,
fences => $fence_form,
upses => $ups_form,
network_note => $network_note,
}}); }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
} }
@ -1921,6 +2118,173 @@ sub handle_manifest
return(0); return(0);
} }
sub sanity_check_manifest_step3
{
my ($anvil) = @_;
my $sane = 1;
# Check the IPMI values. They're allowed to be blank. If they're set, they need to be in a BCN or
# IFN network.
foreach my $machine ("node1", "node2", "dr1")
{
my $key = $machine."_ipmi_ip";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
machine => $machine,
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
}});
if ($anvil->data->{cgi}{$key}{value})
{
# Is it a valid IPv4 address?
if (not $anvil->Validate->is_ipv4({ip => $anvil->data->{cgi}{$key}{value}}))
{
# Bad subnet
my $say_network = "#!string!striker_0255!#";
if ($machine eq "node2") { $say_network = "#!string!striker_0256!#"; }
elsif ($machine eq "dr1") { $say_network = "#!string!striker_0257!#"; }
my $message = $anvil->Words->string({key => "error_0125", variables => { network => $say_network }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${key}::alert" => $anvil->data->{cgi}{$key}{alert},
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
}});
}
else
{
# It's a valid IP. Does it match any BCN or IFN network?
my $match_found = 0;
foreach my $network ("bcn", "sn", "ifn")
{
my $count_key = $network."_count";
foreach my $i (1..$anvil->data->{cgi}{$count_key}{value})
{
next if $match_found;
my $network_key = $network.$i."_network";
my $subnet_key = $network.$i."_subnet";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
}});
$match_found = $anvil->Network->is_ip_in_network({
debug => 2,
ip => $anvil->data->{cgi}{$key}{value},
network => $anvil->data->{cgi}{$network_key}{value},
subnet_mask => $anvil->data->{cgi}{$subnet_key}{value},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_found => $match_found }});
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_found => $match_found }});
if (not $match_found)
{
# IP is valid, but not in any of the networks.
my $message = $anvil->Words->string({key => "error_0124", variables => { ip => $anvil->data->{cgi}{$key}{value} }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${key}::alert" => $anvil->data->{cgi}{$key}{alert},
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
}});
}
}
}
# Now check that the IPs are sane.
foreach my $network ("bcn", "sn", "ifn")
{
my $count_key = $network."_count";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network => $network,
count_key => $count_key,
"cgi::${count_key}::value" => $anvil->data->{cgi}{$count_key}{value},
}});
foreach my $i (1..$anvil->data->{cgi}{$count_key}{value})
{
my $say_network_code = "striker_0018";
if ($network eq "sn") { $say_network_code = "striker_0020"; }
elsif ($network eq "ifn") { $say_network_code = "striker_0022"; }
my $say_network = $anvil->Words->string({key => $say_network_code, variables => { number => $i }});
my $network_key = $network.$i."_network";
my $subnet_key = $network.$i."_subnet";
my $machine_ip_key = $machine."_".$network.$i."_network";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_network => $say_network,
network_key => $network_key,
subnet_key => $subnet_key,
machine_ip_key => $machine_ip_key,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"cgi::${network_key}::value" => $anvil->data->{cgi}{$network_key}{value},
"cgi::${network_key}::alert" => $anvil->data->{cgi}{$network_key}{alert},
"cgi::${subnet_key}::value" => $anvil->data->{cgi}{$subnet_key}{value},
"cgi::${subnet_key}::alert" => $anvil->data->{cgi}{$subnet_key}{alert},
"cgi::${machine_ip_key}::value" => $anvil->data->{cgi}{$machine_ip_key}{value},
"cgi::${machine_ip_key}::alert" => $anvil->data->{cgi}{$machine_ip_key}{alert},
}});
# Is the IP valid?
if (not $anvil->Validate->is_ipv4({ip => $anvil->data->{cgi}{$machine_ip_key}{value}}))
{
# Bad subnet
my $say_network = "#!string!striker_0255!#";
if ($machine eq "node2") { $say_network = "#!string!striker_0256!#"; }
elsif ($machine eq "dr1") { $say_network = "#!string!striker_0257!#"; }
my $message = $anvil->Words->string({key => "error_0016", variables => { network => $say_network }});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$machine_ip_key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${machine_ip_key}::alert" => $anvil->data->{cgi}{$machine_ip_key}{alert},
"cgi::${machine_ip_key}::value" => $anvil->data->{cgi}{$machine_ip_key}{value},
}});
}
else
{
# It's a valid IP. Is it in the network?
my $match_found = $anvil->Network->is_ip_in_network({
debug => 2,
ip => $anvil->data->{cgi}{$machine_ip_key}{value},
network => $anvil->data->{cgi}{$network_key}{value},
subnet_mask => $anvil->data->{cgi}{$subnet_key}{value},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_found => $match_found }});
if (not $match_found)
{
# IP is valid, but not in any of the networks.
my $message = $anvil->Words->string({key => "error_0126", variables => {
ip => $anvil->data->{cgi}{$key}{value},
network => $anvil->data->{cgi}{$network_key}{value}."/".$anvil->data->{cgi}{$subnet_key}{value},
}});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->data->{cgi}{$key}{alert} = 1;
$sane = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
sane => $sane,
"cgi::${key}::alert" => $anvil->data->{cgi}{$key}{alert},
"cgi::${key}::value" => $anvil->data->{cgi}{$key}{value},
}});
}
}
}
}
}
### TODO: We can't (at least yet) validate ports. They could be numeric or strings... To sanity check
### this, we'll need to look up the fence agent, look up the port type, and use that to decide
### how to check. That's more than we can do for 3.0.
return($sane);
}
sub sanity_check_manifest_step2 sub sanity_check_manifest_step2
{ {
my ($anvil) = @_; my ($anvil) = @_;
@ -4077,16 +4441,15 @@ sub process_prep_network
(not $anvil->data->{cgi}{gateway}{alert}) && (not $anvil->data->{cgi}{gateway}{alert}) &&
($anvil->data->{cgi}{$ip_key}{value})) ($anvil->data->{cgi}{$ip_key}{value}))
{ {
my $match = $anvil->Network->match_gateway({ my $match = $anvil->Network->is_ip_in_network({
ip_address => $anvil->data->{cgi}{$ip_key}{value}, network => $anvil->data->{cgi}{$ip_key}{value},
subnet_mask => $anvil->data->{cgi}{$subnet_key}{value}, subnet_mask => $anvil->data->{cgi}{$subnet_key}{value},
gateway => $anvil->data->{cgi}{gateway}{value}, ip => $anvil->data->{cgi}{gateway}{value},
}); });
# Found the match!
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { match => $match }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { match => $match }});
if ($match) if ($match)
{ {
# Found the match!
if ($anvil->data->{cgi}{$ip_key}{value}) if ($anvil->data->{cgi}{$ip_key}{value})
{ {
$say_ip_address .= ",<br /> &nbsp; #!string!striker_0026!#: ".$anvil->data->{cgi}{gateway}{value}; $say_ip_address .= ",<br /> &nbsp; #!string!striker_0026!#: ".$anvil->data->{cgi}{gateway}{value};
@ -4720,7 +5083,7 @@ sub process_prep_host_page
} }
else else
{ {
# Connected! Ask th euser to confirm. # Connected! Ask the user to confirm.
my $new_host_name = "#!string!striker_0139!#"; my $new_host_name = "#!string!striker_0139!#";
if ((exists $anvil->data->{cgi}{host_name}) && ($anvil->data->{cgi}{host_name}{value})) if ((exists $anvil->data->{cgi}{host_name}) && ($anvil->data->{cgi}{host_name}{value}))
{ {

@ -199,6 +199,15 @@
#!string!striker_0245!# #!string!striker_0245!#
</td> </td>
</tr> </tr>
<tr style="border: 1px dotted #7f7f7f;">
<td class="column_header">
<!-- Password note -->
#!string!striker_0051!#
</td>
<td>
#!string!striker_0259!#
</td>
</tr>
</table> </table>
</td> </td>
</tr> </tr>
@ -340,6 +349,7 @@
<input type="hidden" name="domain" id="domain" value="#!data!cgi::domain::value!#"> <input type="hidden" name="domain" id="domain" value="#!data!cgi::domain::value!#">
<input type="hidden" name="sequence" id="sequence" value="#!data!cgi::sequence::value!#"> <input type="hidden" name="sequence" id="sequence" value="#!data!cgi::sequence::value!#">
<input type="hidden" name="bcn_count" id="bcn_count" value="#!data!cgi::bcn_count::value!#"> <input type="hidden" name="bcn_count" id="bcn_count" value="#!data!cgi::bcn_count::value!#">
<input type="hidden" name="sn_count" id="sn_count" value="#!data!cgi::bcn_count::value!#">
<input type="hidden" name="ifn_count" id="ifn_count" value="#!data!cgi::ifn_count::value!#"> <input type="hidden" name="ifn_count" id="ifn_count" value="#!data!cgi::ifn_count::value!#">
<input type="hidden" name="step" id="step" value="3"> <input type="hidden" name="step" id="step" value="3">
<input type="hidden" name="anvil" id="anvil" value="true"> <input type="hidden" name="anvil" id="anvil" value="true">
@ -465,17 +475,77 @@
<input type="hidden" name="#!variable!gateway_name!#" id="#!variable!gateway_name!#" value="#!variable!gateway_value!#" /> <input type="hidden" name="#!variable!gateway_name!#" id="#!variable!gateway_name!#" value="#!variable!gateway_value!#" />
</td> </td>
<td class="fixed_width_no_wrap"> <td class="fixed_width_no_wrap">
<input type="text" name="#!variable!node1_network_name!#" id="#!variable!node1_network_name!#" value="#!variable!node1_network_value!#" width="15" style="width: 15em;" class="#!variable!node1_network_class!#" /> <input type="text" name="#!variable!node1_network_name!#" id="#!variable!node1_network_name!#" value="#!variable!node1_network_value!#" width="15" style="width: 15em;" class="#!variable!node1_network_class!#" /> &nbsp;
</td> </td>
<td class="fixed_width_no_wrap"> <td class="fixed_width_no_wrap">
<input type="text" name="#!variable!node2_network_name!#" id="#!variable!node2_network_name!#" value="#!variable!node2_network_value!#" width="15" style="width: 15em;" class="#!variable!node2_network_class!#" /> &nbsp; <input type="text" name="#!variable!node2_network_name!#" id="#!variable!node2_network_name!#" value="#!variable!node2_network_value!#" width="15" style="width: 15em;" class="#!variable!node2_network_class!#" /> &nbsp;
</td> </td>
<td class="fixed_width_no_wrap"> <td class="fixed_width_no_wrap">
<input type="text" name="#!variable!dr1_network_name!#" id="#!variable!dr1_network_name!#" value="#!variable!dr1_network_value!#" width="15" style="width: 15em;" class="#!variable!dr1_network_class!#" /> &nbsp; <input type="text" name="#!variable!dr1_network_name!#" id="#!variable!dr1_network_name!#" value="#!variable!dr1_network_value!#" width="15" style="width: 15em;" class="#!variable!dr1_network_class!#" />
</td> </td>
</tr> </tr>
<!-- end manifest-step3-network-entry --> <!-- end manifest-step3-network-entry -->
<!-- start manifest-step3-ipmi-entry -->
<tr>
<td class="column_header">
<!-- Network Name -->
#!string!striker_0258!#: &nbsp;
</td>
<td class="fixed_width_no_wrap">
<input type="text" name="node1_ipmi_ip" id="node1_ipmi_ip" value="#!variable!node1_value!#" width="15" style="width: 15em;" class="#!variable!node1_class!#" /> &nbsp;
</td>
<td class="fixed_width_no_wrap">
&nbsp; <input type="text" name="node2_ipmi_ip" id="node2_ipmi_ip" value="#!variable!node2_value!#" width="15" style="width: 15em;" class="#!variable!node2_class!#" /> &nbsp;
</td>
<td class="fixed_width_no_wrap">
&nbsp; <input type="text" name="dr1_ipmi_ip" id="dr1_ipmi_ip" value="#!variable!dr1_value!#" width="15" style="width: 15em;" class="#!variable!dr1_class!#" />
</td>
</tr>
<!-- end manifest-step3-ipmi-entry -->
<!-- start manifest-step3-fence-entry -->
<tr>
<td class="column_header">
<!-- Fence Name -->
#!variable!name!#: &nbsp;
<input type="hidden" name="#!variable!fence_uuid_name!#" id="#!variable!fence_uuid_name!#" value="#!variable!fence_uuid_value!#" />
</td>
<td class="fixed_width_no_wrap">
<input type="text" name="#!variable!node1_fence_name!#" id="#!variable!node1_fence_name!#" value="#!variable!node1_fence_value!#" style="width: 15em;" class="#!variable!node1_fence_class!#" /> &nbsp;
</td>
<td class="fixed_width_no_wrap">
&nbsp; <input type="text" name="#!variable!node2_fence_name!#" id="#!variable!node2_fence_name!#" value="#!variable!node2_fence_value!#" style="width: 15em;" class="#!variable!node2_fence_class!#" /> &nbsp;
</td>
<td class="fixed_width_no_wrap">
<!-- For now, we don't care about DR fencing, Maybe this will change later -->
<!-- &nbsp; <input type="text" name="#!variable!dr1_fence_name!#" id="#!variable!dr1_fence_name!#" value="#!variable!dr1_fence_value!#" style="width: 15em;" class="#!variable!dr1_fence_class!#" /> -->
&nbsp;
</td>
</tr>
<!-- end manifest-step3-fence-entry -->
<!-- start manifest-step3-ups-entry -->
<tr>
<td class="column_header">
<!-- UPS Name -->
#!variable!name!#: &nbsp;
<input type="hidden" name="#!variable!ups_uuid_name!#" id="#!variable!ups_uuid_name!#" value="#!variable!ups_uuid_value!#" />
</td>
<td class="fixed_width_no_wrap">
<input type="checkbox" name="#!variable!node1_ups_name!#" id="#!variable!node1_ups_name!#" #!variable!node1_ups_checked!# /> &nbsp;
</td>
<td class="fixed_width_no_wrap">
<input type="checkbox" name="#!variable!node2_ups_name!#" id="#!variable!node2_ups_name!#" #!variable!node2_ups_checked!# /> &nbsp;
</td>
<td class="fixed_width_no_wrap">
<!-- For now, we don't care about DR's UPSes, Maybe this will change later -->
<!-- <input type="checkbox" name="#!variable!dr1_ups_name!#" id="#!variable!dr1_ups_name!#" #!variable!dr1_ups_checked!# /> &nbsp; -->
&nbsp;
</td>
</tr>
<!-- end manifest-step3-ups-entry -->
<!-- start manifest-step3 --> <!-- start manifest-step3 -->
<table align="center" class="anvil_main_menu"> <table align="center" class="anvil_main_menu">
<script type="text/javascript" src="/skins/alteeve/anvil.js"></script> <script type="text/javascript" src="/skins/alteeve/anvil.js"></script>
@ -508,6 +578,7 @@
<td> <td>
<form name="manifest_step3" action="" method="post"> <form name="manifest_step3" action="" method="post">
<table align="center" class="anvil_main_menu"> <table align="center" class="anvil_main_menu">
<!-- IPs -->
<tr> <tr>
<td class="column_header"> <td class="column_header">
<!-- Variable --> <!-- Variable -->
@ -519,14 +590,58 @@
</td> </td>
<td class="column_header"> <td class="column_header">
<!-- Node 2 --> <!-- Node 2 -->
#!string!striker_0256!# &nbsp; &nbsp; #!string!striker_0256!#
</td> </td>
<td class="column_header"> <td class="column_header">
<!-- DR Host --> <!-- DR Host -->
#!string!striker_0257!# &nbsp; &nbsp; #!string!striker_0257!#
</td> </td>
</tr> </tr>
#!variable!networks!# #!variable!networks!#
<!-- Fences -->
<tr>
<td class="column_header">
<!-- Fence Name -->
&nbsp;
</td>
<td class="column_header">
<!-- Node 1 -->
#!string!striker_0262!#
</td>
<td class="column_header">
<!-- Node 2 -->
&nbsp; &nbsp; #!string!striker_0262!#
</td>
<td class="column_header">
<!-- DR Host -->
<!-- For now, we don't care about DR fencing, Maybe this will change later -->
<!-- &nbsp; &nbsp; #!string!striker_0262!# -->
&nbsp;
</td>
</tr>
#!variable!fences!#
<!-- UPSes -->
<tr>
<td class="column_header">
<!-- UPS Name -->
&nbsp;
</td>
<td class="column_header">
<!-- Node 1 -->
#!string!striker_0264!#
</td>
<td class="column_header">
<!-- Node 2 -->
&nbsp; &nbsp; #!string!striker_0264!#
</td>
<td class="column_header">
<!-- DR Host -->
<!-- For now, we don't care about DR fencing, Maybe this will change later -->
<!-- &nbsp; &nbsp; #!string!striker_0264!# -->
&nbsp;
</td>
</tr>
#!variable!upses!#
<tr> <tr>
<td colspan="4"> <td colspan="4">
&nbsp; &nbsp;
@ -543,8 +658,13 @@
<input type="hidden" name="domain" id="domain" value="#!data!cgi::domain::value!#"> <input type="hidden" name="domain" id="domain" value="#!data!cgi::domain::value!#">
<input type="hidden" name="sequence" id="sequence" value="#!data!cgi::sequence::value!#"> <input type="hidden" name="sequence" id="sequence" value="#!data!cgi::sequence::value!#">
<input type="hidden" name="bcn_count" id="bcn_count" value="#!data!cgi::bcn_count::value!#"> <input type="hidden" name="bcn_count" id="bcn_count" value="#!data!cgi::bcn_count::value!#">
<input type="hidden" name="sn_count" id="sn_count" value="#!data!cgi::sn_count::value!#">
<input type="hidden" name="ifn_count" id="ifn_count" value="#!data!cgi::ifn_count::value!#"> <input type="hidden" name="ifn_count" id="ifn_count" value="#!data!cgi::ifn_count::value!#">
<input type="hidden" name="step" id="step" value="3"> <input type="hidden" name="dns" id="dns" value="#!data!cgi::dns::value!#" />
<input type="hidden" name="ntp" id="ntp" value="#!data!cgi::ntp::value!#" />
<input type="hidden" name="mtu" id="mtu" value="#!data!cgi::mtu::value!#" />
<input type="hidden" name="step" id="step" value="4">
<input type="hidden" name="reload" id="reload" value="true">
<input type="hidden" name="anvil" id="anvil" value="true"> <input type="hidden" name="anvil" id="anvil" value="true">
<input type="hidden" name="task" id="task" value="manifests"> <input type="hidden" name="task" id="task" value="manifests">
<input type="hidden" name="manifest_uuid" id="manifest_uuid" value="#!data!cgi::manifest_uuid::value!#"> <input type="hidden" name="manifest_uuid" id="manifest_uuid" value="#!data!cgi::manifest_uuid::value!#">
@ -563,68 +683,62 @@
<table class="centered"> <table class="centered">
<tr style="border: 1px dotted #7f7f7f;"> <tr style="border: 1px dotted #7f7f7f;">
<td class="column_header"> <td class="column_header">
<!-- Network --> <!-- IPMI IP -->
#!string!striker_0149!# #!string!striker_0258!# &nbsp;
</td> </td>
<td> <td>
#!string!message_0163!# #!string!striker_0261!#
</td> </td>
</tr> </tr>
<tr style="border: 1px dotted #7f7f7f;"> <tr style="border: 1px dotted #7f7f7f;">
<td class="column_header"> <td class="column_header">
<!-- Subnet Mask --> <!-- IPMI Note -->
#!string!striker_0025!# #!string!striker_0260!# &nbsp;
</td> </td>
<td> <td>
#!string!message_0164!# #!string!striker_0266!#
</td> </td>
</tr> </tr>
<tr style="border: 1px dotted #7f7f7f;"> <tr style="border: 1px dotted #7f7f7f;">
<td class="column_header"> <td class="column_header">
<!-- Gateway --> <!-- Fence Note -->
#!string!striker_0026!# #!string!striker_0262!# &nbsp;
</td> </td>
<td> <td>
#!string!message_0165!# #!string!striker_0263!#
</td>
</tr>
<tr>
<td colspan="2">
&nbsp;
</td> </td>
</tr> </tr>
<tr style="border: 1px dotted #7f7f7f;"> <tr style="border: 1px dotted #7f7f7f;">
<td class="column_header"> <td class="column_header">
<!-- BCN --> <!-- UPS Note -->
#!string!message_0160!# &nbsp; #!string!striker_0264!# &nbsp;
</td> </td>
<td> <td>
#!string!message_0131!# #!string!striker_0265!#
</td> </td>
</tr> </tr>
<tr style="border: 1px dotted #7f7f7f;"> <tr>
<td class="column_header"> <td colspan="2">
<!-- SN --> &nbsp;
#!string!message_0161!# &nbsp;
</td>
<td>
#!string!message_0132!#
</td> </td>
</tr> </tr>
#!variable!network_note!#
</table>
</td>
</tr>
</table>
<!-- end manifest-step3 -->
<!-- start manifest-step3-network-note-entry -->
<tr style="border: 1px dotted #7f7f7f;"> <tr style="border: 1px dotted #7f7f7f;">
<td class="column_header"> <td class="column_header">
<!-- IFN --> #!variable!name!# &nbsp;
#!string!message_0162!# &nbsp;
</td> </td>
<td> <td>
#!string!message_0133!# #!variable!message!#
</td> </td>
</tr> </tr>
</table> <!-- end manifest-step3-network-note-entry -->
</td>
</tr>
</table>
<!-- end manifest-step3 -->
<!-- start fence-agent-configuration --> <!-- start fence-agent-configuration -->
<table align="center" class="anvil_main_menu"> <table align="center" class="anvil_main_menu">

@ -182,6 +182,9 @@ The error was:
<key name="error_0121">The gateway: [#!variable!gateway!#] does not apear to be in the network: [#!variable!network!#]/[#!variable!subnet!#].</key> <key name="error_0121">The gateway: [#!variable!gateway!#] does not apear to be in the network: [#!variable!network!#]/[#!variable!subnet!#].</key>
<key name="error_0122">An NTP entry is bad. One or more IPv4 addresses can be specified, with a comma separating multiple IPs.</key> <key name="error_0122">An NTP entry is bad. One or more IPv4 addresses can be specified, with a comma separating multiple IPs.</key>
<key name="error_0123">The MTU needs to be a positive integer equal or above '512' bytes.</key> <key name="error_0123">The MTU needs to be a positive integer equal or above '512' bytes.</key>
<key name="error_0124">The IP address: [#!variable!ip!#] does not appear to be within any of the configured networks.</key>
<key name="error_0125">The IPv4 address assigned to the IPMI interface on: [#!variable!network!#] is invalid.</key>
<key name="error_0126">The IP address: [#!variable!ip!#] does not appear to be in the network: [#!variable!network!#].</key>
<!-- Table headers --> <!-- Table headers -->
<key name="header_0001">Current Network Interfaces and States</key> <key name="header_0001">Current Network Interfaces and States</key>
@ -1371,6 +1374,16 @@ If you are comfortable that the target has changed for a known reason, you can s
<key name="striker_0255">Node 1</key> <key name="striker_0255">Node 1</key>
<key name="striker_0256">Node 2</key> <key name="striker_0256">Node 2</key>
<key name="striker_0257">DR Host</key> <key name="striker_0257">DR Host</key>
<key name="striker_0258">IPMI IP</key>
<key name="striker_0259"><![CDATA[<span class="notice">Note</span>: The password to use for an #!string!brand_0006!# will be asked when the manifest is actually run. The password is not stored in the manifest.]]></key>
<key name="striker_0260">IPMI Details</key>
<key name="striker_0261"><![CDATA[<span class="notice">Note</span>: The IPMI information is set when a node is initialized. The only thing set here is the IP address.]]></key>
<key name="striker_0262">Fence Port</key>
<key name="striker_0263">This is the "port" (outlet, name or other ID) that the associated fence device uses to terminate the target node. This could be the outlet number on a PDU, VM name on a hypervisor host, etc.</key>
<key name="striker_0264">Powered By UPS</key>
<key name="striker_0265">If the machine is powered by a given UPS, click to check the corresponding box. This information will be used in power loss events to decide what machine should host servers, which should be powered off during load-shed conditions and when to gracefully power off entirely.</key>
<key name="striker_0266">If your machine has an IPMI BMC, (iDRAC, iLO, iRMC, etc), then you can enter the IP to give it here. Further details will be collected when the manifest runs. Leave blank if the machine doesn't have IPMI.</key>
<key name="striker_0267"><![CDATA[Network: [<span class="code">#!variable!network!#</span>].]]></key>
<!-- These are generally units and appended to numbers --> <!-- These are generally units and appended to numbers -->
<key name="suffix_0001">#!variable!number!#/sec</key> <key name="suffix_0001">#!variable!number!#/sec</key>

Loading…
Cancel
Save