Author: arkurth
Date: Fri Dec 12 20:17:47 2014
New Revision: 1645057
URL: http://svn.apache.org/r1645057
Log:
VCL-174
Changed iptables.pm::initialize to only check for the iptables command, not the
service. The command can be used if firewalld is used.
Updated configure_nat to figure out the internal network address and network
bits. The MASQUERADE rule was tightened so that it matches only if the
destination address is not on the internal network to allow things to work if
the public and internal networks are using the same interface.
Added check to Windows.pm::grant_access when process_connect_methods is called.
It was not returning if process_connect_methods failed. As a result, the
reservation did not fail when it should have.
Other
Updated Linux.pm::update_public_hostname. It was generating unnecessary
warnings if the public IP address did not resolve. Added
utils.pm::ip_address_to_hostname. This is called by update_public_hostname
instead of running ipcalc. If the hostname can't be resolved the hostname is
set to the name in the VCL database.
Updated Linux.pm::set_static_public_address to continue to try to set the
default route even if the IP address is correct to begin with.
Modified:
vcl/trunk/managementnode/lib/VCL/Module/OS.pm
vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
vcl/trunk/managementnode/lib/VCL/utils.pm
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Fri Dec 12 20:17:47 2014
@@ -2112,7 +2112,7 @@ sub remove_lines_from_file {
=cut
sub execute {
-#return execute_new(@_);
+ my @original_arguments = @_;
my ($argument) = @_;
my ($computer_name, $command, $display_output, $timeout_seconds,
$max_attempts, $port, $user, $password, $identity_key, $ignore_error);
@@ -2178,6 +2178,11 @@ sub execute {
return;
}
+ # TESTING: use the new subroutine if $ENV{execute_new} is set and the
command isn't one that's known to fail with the new subroutine
+ if ($ENV{execute_new} && $command !~
/(vmkfstools|qemu-img|Convert-VHD|scp)/) {
+ return execute_new(@original_arguments);
+ }
+
my $arguments = {
node => $computer_name,
command => $command,
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Fri Dec 12 20:17:47 2014
@@ -644,8 +644,7 @@ sub update_public_hostname {
return;
}
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
+ my $computer_node_name = $self->data->get_computer_node_name();
# Get the IP address of the public adapter
my $public_ip_address = $self->get_public_ip_address();
@@ -654,42 +653,11 @@ sub update_public_hostname {
return;
}
notify($ERRORS{'DEBUG'}, 0, "retrieved public IP address of
$computer_node_name: $public_ip_address");
- sleep 5;
# Get the hostname for the public IP address
- my $ipcalc_command = "/bin/ipcalc --hostname $public_ip_address";
- my ($ipcalc_exit_status, $ipcalc_output) = run_command($ipcalc_command);
- if (!defined($ipcalc_output)) {
- notify($ERRORS{'WARNING'}, 0, "failed to run ipcalc command on
management node to determine public hostname of $computer_node_name, command:
'$ipcalc_command'");
- return;
- }
-
- my ($public_hostname) = ("@$ipcalc_output" =~ /HOSTNAME=(.*)/i);
- if ($public_hostname) {
- notify($ERRORS{'DEBUG'}, 0, "determined registered public
hostname of $computer_node_name ($public_ip_address) by running ipcalc on the
management node: '$public_hostname'");
- }
- else {
- notify($ERRORS{'DEBUG'}, 0, "failed to determine registered
public hostname of $computer_node_name ($public_ip_address), command:
'$ipcalc_command', output:\n" . join("\n", @$ipcalc_output));
-
- # Attempt to run the ipcalc command on the host
- my ($ipcalc_exit_status, $ipcalc_output) =
$self->execute($ipcalc_command);
- if (!defined($ipcalc_output)) {
- notify($ERRORS{'WARNING'}, 0, "failed to run ipcalc
command on $computer_node_name to determine its public hostname, command:
'$ipcalc_command'");
- return;
- }
-
- ($public_hostname) = ("@$ipcalc_output" =~ /HOSTNAME=(.*)/i);
- if ($public_hostname) {
- notify($ERRORS{'DEBUG'}, 0, "determined registered
public hostname of $computer_node_name ($public_ip_address) by running ipcalc
on $computer_node_name: '$public_hostname'");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to determine
registered public hostname of $computer_node_name ($public_ip_address) by
running ipcalc on either the management node or $computer_node_name, command:
'$ipcalc_command', output:\n" . join("\n", @$ipcalc_output));
- return;
- }
- }
+ my $public_hostname = ip_address_to_hostname($public_ip_address) ||
$computer_node_name;
# Set the node's hostname to public hostname
-
if ($self->can("update_hostname_file")) {
if (!$self->update_hostname_file($public_hostname)) {
notify($ERRORS{'WARNING'}, 0, "failed to update
hostname file");
@@ -712,10 +680,8 @@ sub update_public_hostname {
}
return 1;
-
}
-
#/////////////////////////////////////////////////////////////////////////////
=head2 update_hostname_file
@@ -856,43 +822,40 @@ EOF
# Get the current public IP address being used by the computer
# Pass the $ignore_error flag to prevent warnings if not defined
my $current_public_ip_address = $self->get_public_ip_address(1);
- if ($current_public_ip_address) {
- if ($current_public_ip_address eq $computer_public_ip_address) {
- notify($ERRORS{'DEBUG'}, 0, "static public IP address
does not need to be set, $computer_name is already configured to use
$current_public_ip_address");
- return 1;
+ if ($current_public_ip_address && $current_public_ip_address eq
$computer_public_ip_address) {
+ notify($ERRORS{'DEBUG'}, 0, "static public IP address does not
need to be set, $computer_name is already configured to use
$current_public_ip_address");
+ }
+ else {
+ if ($current_public_ip_address) {
+ notify($ERRORS{'DEBUG'}, 0, "static public IP address
needs to be set, public IP address currently being used by $computer_name
$current_public_ip_address does NOT match correct public IP address:
$computer_public_ip_address");
}
else {
- notify($ERRORS{'DEBUG'}, 0, "static public IP address
needs to be set, public IP address currently being used by $computer_name
$current_public_ip_address does NOT match correct public IP address:
$computer_public_ip_address");
+ notify($ERRORS{'DEBUG'}, 0, "static public IP address
needs to be set, unable to determine public IP address currently in use on
$computer_name");
}
- }
- else {
- notify($ERRORS{'DEBUG'}, 0, "static public IP address needs to
be set, unable to determine public IP address currently in use on
$computer_name");
- }
-
-
- # Make sure required info was retrieved
- if ("$computer_public_ip_address $subnet_mask $default_gateway" =~
/undefined/) {
- notify($ERRORS{'WARNING'}, 0, "failed to retrieve required
network configuration for $computer_name:\n$configuration_info_string");
- return;
- }
- else {
- notify($ERRORS{'OK'}, 0, "attempting to set static public IP
address on $computer_name:\n$configuration_info_string");
- }
-
- # Try to ping address to make sure it's available
- # FIXME -- need to add other tests for checking ip_address is or is
not available.
- if ((_pingnode($computer_public_ip_address))) {
- notify($ERRORS{'WARNING'}, 0, "ip_address
$computer_public_ip_address is pingable, can not assign to $computer_name ");
- return;
- }
-
- # Assemble the ifcfg file path
- my $network_scripts_path = "/etc/sysconfig/network-scripts";
- my $ifcfg_file_path =
"$network_scripts_path/ifcfg-$interface_name";
- notify($ERRORS{'DEBUG'}, 0, "public interface ifcfg file path:
$ifcfg_file_path");
-
- # Assemble the ifcfg file contents
- my $ifcfg_contents = <<EOF;
+
+ # Make sure required info was retrieved
+ if ("$computer_public_ip_address $subnet_mask $default_gateway"
=~ /undefined/) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve
required network configuration for
$computer_name:\n$configuration_info_string");
+ return;
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "attempting to set static
public IP address on $computer_name:\n$configuration_info_string");
+ }
+
+ # Try to ping address to make sure it's available
+ # FIXME -- need to add other tests for checking ip_address is
or is not available.
+ if ((_pingnode($computer_public_ip_address))) {
+ notify($ERRORS{'WARNING'}, 0, "ip_address
$computer_public_ip_address is pingable, can not assign to $computer_name ");
+ return;
+ }
+
+ # Assemble the ifcfg file path
+ my $network_scripts_path = "/etc/sysconfig/network-scripts";
+ my $ifcfg_file_path =
"$network_scripts_path/ifcfg-$interface_name";
+ notify($ERRORS{'DEBUG'}, 0, "public interface ifcfg file path:
$ifcfg_file_path");
+
+ # Assemble the ifcfg file contents
+ my $ifcfg_contents = <<EOF;
DEVICE=$interface_name
BOOTPROTO=static
IPADDR=$computer_public_ip_address
@@ -902,25 +865,35 @@ STARTMODE=onboot
ONBOOT=yes
EOF
- # Echo the contents to the ifcfg file
- my $echo_ifcfg_command = "echo \"$ifcfg_contents\" > $ifcfg_file_path";
- my ($echo_ifcfg_exit_status, $echo_ifcfg_output) =
$self->execute($echo_ifcfg_command);
- if (!defined($echo_ifcfg_output)) {
- notify($ERRORS{'WARNING'}, 0, "failed to run command to
recreate $ifcfg_file_path on $computer_name: '$echo_ifcfg_command'");
- return;
- }
- elsif ($echo_ifcfg_exit_status || grep(/echo:/i, @$echo_ifcfg_output)) {
- notify($ERRORS{'WARNING'}, 0, "failed to recreate
$ifcfg_file_path on $computer_name, exit status: $echo_ifcfg_exit_status,
command: '$echo_ifcfg_command', output:\n" . join("\n", @$echo_ifcfg_output));
- return;
- }
- else {
- notify($ERRORS{'DEBUG'}, 0, "recreated $ifcfg_file_path on
$computer_name:\n$ifcfg_contents");
- }
-
- # Restart the interface
- if (!$self->restart_network_interface($interface_name)) {
- notify($ERRORS{'WARNING'}, 0, "failed to restart public
interface $interface_name on $computer_name");
- return;
+ # Echo the contents to the ifcfg file
+ my $echo_ifcfg_command = "echo \"$ifcfg_contents\" >
$ifcfg_file_path";
+ my ($echo_ifcfg_exit_status, $echo_ifcfg_output) =
$self->execute($echo_ifcfg_command);
+ if (!defined($echo_ifcfg_output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to run command to
recreate $ifcfg_file_path on $computer_name: '$echo_ifcfg_command'");
+ return;
+ }
+ elsif ($echo_ifcfg_exit_status || grep(/echo:/i,
@$echo_ifcfg_output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to recreate
$ifcfg_file_path on $computer_name, exit status: $echo_ifcfg_exit_status,
command: '$echo_ifcfg_command', output:\n" . join("\n", @$echo_ifcfg_output));
+ return;
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "recreated $ifcfg_file_path
on $computer_name:\n$ifcfg_contents");
+ }
+
+ # Restart the interface
+ if (!$self->restart_network_interface($interface_name)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to restart public
interface $interface_name on $computer_name");
+ return;
+ }
+
+ my $ext_sshd_config_file_path = '/etc/ssh/external_sshd_config';
+ if ($self->file_exists($ext_sshd_config_file_path)) {
+ # Remove existing ListenAddress lines from
external_sshd_config
+
$self->remove_lines_from_file($ext_sshd_config_file_path, 'ListenAddress') ||
return;
+
+ # Add ListenAddress line to the end of the file
+ $self->append_text_file($ext_sshd_config_file_path,
"ListenAddress $computer_public_ip_address\n") || return;
+ }
}
# Delete existing default route
@@ -956,14 +929,6 @@ EOF
notify($ERRORS{'DEBUG'}, 0, "added default route to
$default_gateway on public interface $interface_name on $computer_name,
output:\n" . format_data($route_add_output));
}
- my $ext_sshd_config_file_path = '/etc/ssh/external_sshd_config';
-
- # Remove existing ListenAddress lines from external_sshd_config
- $self->remove_lines_from_file($ext_sshd_config_file_path,
'ListenAddress') || return;
-
- # Add ListenAddress line to the end of the file
- $self->append_text_file($ext_sshd_config_file_path, "ListenAddress
$computer_public_ip_address\n") || return;
-
# Update resolv.conf if DNS server address is configured for the
management node
my $resolv_conf_path = "/etc/resolv.conf";
if (@dns_servers) {
@@ -2401,8 +2366,8 @@ sub get_network_configuration {
elsif (!defined($network_configuration->{$interface_name})) {
notify($ERRORS{'WARNING'}, 0, "found default gateway
for '$interface_name' interface but the network configuration for
'$interface_name' was not previously retrieved, route output:\n" . join("\n",
@$route_output) . "\nnetwork configuation:\n" .
format_data($network_configuration));
}
- elsif
(defined($network_configuration->{$interface_name}{default_gateway})) {
- notify($ERRORS{'WARNING'}, 0, "multiple default gateway
are configured for '$interface_name' interface, route output:\n" . join("\n",
@$route_output));
+ elsif
(defined($network_configuration->{$interface_name}{default_gateway}) &&
$default_gateway ne $network_configuration->{$interface_name}{default_gateway})
{
+ notify($ERRORS{'WARNING'}, 0, "multiple default
gateways are configured for '$interface_name' interface, route output:\n" .
join("\n", @$route_output));
}
else {
$network_configuration->{$interface_name}{default_gateway} = $default_gateway;
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
(original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm Fri
Dec 12 20:17:47 2014
@@ -89,8 +89,8 @@ sub initialize {
notify($ERRORS{'DEBUG'}, 0, "initializing " . ref($self) . " object to
control $computer_name");
- if (!$self->service_exists('iptables')) {
- notify($ERRORS{'DEBUG'}, 0, ref($self) . " object not
initialized to control $computer_name, iptables service does not exist");
+ if (!$self->command_exists('iptables')) {
+ notify($ERRORS{'DEBUG'}, 0, ref($self) . " object not
initialized to control $computer_name, iptables command does not exist");
return 0;
}
@@ -641,6 +641,9 @@ sub configure_nat {
# Figure out the public and internal interface names
my $public_interface_name;
my $internal_interface_name;
+ my $public_subnet_mask;
+ my $internal_subnet_mask;
+
my $network_configuration = $self->get_network_configuration();
for my $interface_name (keys %$network_configuration) {
my @ip_addresses = keys
%{$network_configuration->{$interface_name}{ip_address}};
@@ -648,11 +651,13 @@ sub configure_nat {
# Check if the interface is assigned the nathost.publicIPaddress
if (grep { $_ eq $public_ip_address } @ip_addresses) {
$public_interface_name = $interface_name;
+ $public_subnet_mask =
$network_configuration->{$interface_name}{ip_address}{$public_ip_address};
}
# If nathost.internalIPaddress is set, check if interface is
assigned matching IP address
if (grep { $_ eq $internal_ip_address } @ip_addresses) {
$internal_interface_name = $interface_name;
+ $internal_subnet_mask =
$network_configuration->{$interface_name}{ip_address}{$internal_ip_address};
}
}
if (!$public_interface_name) {
@@ -663,9 +668,11 @@ sub configure_nat {
notify($ERRORS{'WARNING'}, 0, "failed to configure NAT host
$computer_name, no interface is assigned the internal IP address configured in
the nathost table: $internal_ip_address\n" .
format_data($network_configuration));
return;
}
+ my ($public_network_address, $public_network_bits) =
ip_address_to_network_address($public_ip_address, $public_subnet_mask);
+ my ($internal_network_address, $internal_network_bits) =
ip_address_to_network_address($internal_ip_address, $internal_subnet_mask);
notify($ERRORS{'DEBUG'}, 0, "determined NAT host interfaces:\n" .
- "public: $public_interface_name ($public_ip_address)\n" .
- "internal: $internal_interface_name: ($internal_ip_address)"
+ "public - interface: $public_interface_name, IP address:
$public_ip_address/$public_subnet_mask, network:
$public_network_address/$public_network_bits\n" .
+ "internal - interface: $internal_interface_name, IP address:
$internal_ip_address/$internal_subnet_mask, network:
$internal_network_address/$internal_network_bits"
);
my $natport_ranges_variable = get_variable('natport_ranges') ||
'49152-65535';
@@ -685,6 +692,7 @@ sub configure_nat {
'chain' => 'POSTROUTING',
'parameters' => {
'out-interface' => $public_interface_name,
+ '!destination' =>
"$internal_network_address/$internal_network_bits",
'jump' => 'MASQUERADE',
},
'match_extensions' => {
@@ -706,7 +714,7 @@ sub configure_nat {
},
'match_extensions' => {
'state' => {
- 'state' => 'RELATED,ESTABLISHED',
+ 'state' => 'NEW,RELATED,ESTABLISHED',
},
'multiport' => {
'destination-ports' => $destination_ports,
@@ -726,7 +734,7 @@ sub configure_nat {
},
'match_extensions' => {
'state' => {
- 'state' => 'RELATED,ESTABLISHED',
+ 'state' => 'NEW,RELATED,ESTABLISHED',
},
'multiport' => {
'destination-ports' => $destination_ports,
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Fri Dec 12 20:17:47
2014
@@ -1101,6 +1101,10 @@ sub grant_access {
if ($self->process_connect_methods("", 1) ) {
notify($ERRORS{'OK'}, 0, "processed connection methods on
$computer_node_name");
}
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to process connection
methods on $computer_node_name");
+ return;
+ }
# If this is an imaging request, make sure the Administrator account is
enabled
if ($request_forimaging) {
Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Fri Dec 12 20:17:47 2014
@@ -78,7 +78,8 @@ use XML::Simple;
use Time::HiRes qw(gettimeofday tv_interval);
use Crypt::OpenSSL::RSA;
use B qw(svref_2object);
-use Socket qw(inet_ntoa);
+use Socket;
+use Net::Netmask;
BEGIN {
$ENV{PERL_RL} = 'Perl';
@@ -186,6 +187,8 @@ our @EXPORT = qw(
insert_reload_request
insert_request
insertloadlog
+ ip_address_to_hostname
+ ip_address_to_network_address
is_inblockrequest
is_ip_assigned_query
is_management_node_process_running
@@ -3990,8 +3993,11 @@ sub run_ssh_command {
$port = 22 if (!$port);
$timeout_seconds = 0 if (!$timeout_seconds);
$identity_paths = get_management_node_info()->{keys} if (!defined
$identity_paths || length($identity_paths) == 0);
-
-#return VCL::Module::OS::execute_new($node, $command, $output_level,
$timeout_seconds, $max_attempts, $port, $user, '', $identity_paths);
+
+ # TESTING: use the new subroutine if $ENV{execute_new} is set and the
command isn't one that's known to fail with the new subroutine
+ if ($ENV{execute_new} && $command !~
/(vmkfstools|qemu-img|Convert-VHD|scp)/) {
+ return VCL::Module::OS::execute_new($node, $command,
$output_level, $timeout_seconds, $max_attempts, $port, $user, '',
$identity_paths);
+ }
# TODO: Add ssh path to config file and set global variable
# Locate the path to the ssh binary
@@ -12401,6 +12407,33 @@ sub hostname_to_ip_address {
#/////////////////////////////////////////////////////////////////////////////
+=head2 ip_address_to_hostname
+
+ Parameters : $ip_address
+ Returns : string
+ Description : Calls gethostbyaddr on the management node to determine the
+ hostname an IP address resolves to. The hostname is returned. If
+ the IP address cannot be resolved or if an error occurs, null is
+ returned.
+
+=cut
+
+sub ip_address_to_hostname {
+ my ($ip_address) = @_;
+
+ my $hostname = gethostbyaddr(inet_aton($ip_address), AF_INET);
+ if (defined $hostname) {
+ notify($ERRORS{'DEBUG'}, 0, "determined hostname from IP
address $ip_address: $hostname");
+ return $hostname;
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "unable to determine hostname from
IP address: $ip_address");
+ return;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
=head2 update_request_checkuser
Parameters : $request_id, $checkuser
@@ -12540,6 +12573,45 @@ EOF
}
#/////////////////////////////////////////////////////////////////////////////
+
+=head2 ip_address_to_network_address
+
+ Parameters : $ip_address, $subnet_mask
+ Returns : If called in array context: ($network_address, $network_bits)
+ If called in scalar context: $network_address
+ Description : Determines a network address and network bits.
+
+=cut
+
+sub ip_address_to_network_address {
+ my ($ip_address, $subnet_mask) = @_;
+ if (!defined($ip_address)) {
+ notify($ERRORS{'WARNING'}, 0, "$ip_address argument was not
supplied");
+ return;
+ }
+ if (!defined($subnet_mask)) {
+ notify($ERRORS{'WARNING'}, 0, "$subnet_mask argument was not
supplied");
+ return;
+ }
+
+ my $netmask_object = new Net::Netmask("$ip_address/$subnet_mask");
+ if(!$netmask_object) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create Net::Netmask
object, IP address: $ip_address, subnet mask: $subnet_mask");
+ return;
+ }
+
+ my $network_address = $netmask_object->base();
+ my $network_bits = $netmask_object->bits();
+ notify($ERRORS{'DEBUG'}, 0, "$ip_address/$subnet_mask -->
$network_address/$network_bits");
+ if (wantarray) {
+ return ($network_address, $network_bits);
+ }
+ else {
+ return $network_address;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
1;
__END__