Author: arkurth
Date: Wed May 24 22:22:40 2017
New Revision: 1796111
URL: http://svn.apache.org/viewvc?rev=1796111&view=rev
Log:
VCL-1031
Updated Module.pm::create_nathost_os_object to check to make sure various
things were correct before returning true, including:
* public IP and internal IP defined
* firewall object is defined
* firewall object implements nat_configure_reservation and nat_configure_host
Added code to set NAT host public and internal IP addresses in NAT host OS's
DataStructure object. These were available to the OS object of the computer
being loaded but not the NAT host OS or its firewall object.
Moved calls to nat_configure_host and nat_configure_reservation from
OS.pm::process_connect_methods to OS.pm::reserve. process_connect_methods is
called after the user clicks Connect. These NAT steps added time between
clicking Connect and actually being able to connect. These steps can be safely
done earlier in reserve.
Renamed Linux.pm::set_default_gateway and Windows.pm::set_public_default_route
to set_static_default_gateway so they match.
Updated Linux.pm::set_default_gateway to add DEFROUT=no to ifcfg files in order
to completely override a different DHCP-assigned route.
Added call to set_static_default_gateway in OS.pm::update_public_ip_address if
computer is assigned to a NAT host, DHCP is used, and the computer's current
gateway isn't the NAT host's internal IP address. This forces the computer to
use the NAT host's address as its gateway.
Added OS.pm::get_correct_default_gateway to reduce duplicate code. It checks if
NAT is used, or public IP is static/DHCP assigned.
Added OS.pm::set_config_file_parameter to make it easier to add or modify
settings in various types of config files.
Added code to Linux.pm::pre_capture to delete any route files that may have
been added by set_static_default_gateway. Also added lines to clean out
HOSTNAME and GATEWAY lines from network file if they exist.
Improved Linux.pm::enable_ip_forwarding to configure /etc/sysctl.conf rather
than simply calling 'echo 1 > /proc/sys/net/ipv4/ip_forward'. This wasn't
persisting across reboots which is problematic for NAT hosts.
Updated firewalld.pm::delete_chain to accept a chain name pattern argument.
Updated iptables.pm NAT host configuration to use dedicated chains.
Modified:
vcl/trunk/managementnode/lib/VCL/Module.pm
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/Ubuntu.pm
vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/firewalld.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.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module.pm?rev=1796111&r1=1796110&r2=1796111&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module.pm Wed May 24 22:22:40 2017
@@ -725,22 +725,39 @@ my $self = shift;
return;
}
- # Make sure computer is mapped to a NAT host
- my $nathost_id = $self->data->get_nathost_id();
- if (!$nathost_id) {
- notify($ERRORS{'WARNING'}, 0, "NAT host OS object not created,
computer is not mapped to a NAT host");
- return;
- }
-
my $request_data = $self->data->get_request_data();
my $reservation_id = $self->data->get_reservation_id();
+ my $nathost_id = $self->data->get_nathost_id();
my $nathost_hostname = $self->data->get_nathost_hostname();
+ my $nathost_public_ip_address =
$self->data->get_nathost_public_ip_address(0);
+ my $nathost_internal_ip_address =
$self->data->get_nathost_internal_ip_address(0);
my $nathost_resource_subid = $self->data->get_nathost_resource_subid();
my $nathost_resource_type = $self->data->get_nathost_resource_type();
+
+ # Make sure computer is mapped to a NAT host and all the required
variables are set
+ if (!defined($nathost_id)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create NAT host OS
object, NAT host ID is not defined");
+ return;
+ }
+ elsif (!defined($nathost_hostname)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create NAT host OS
object, NAT host hostname is not defined");
+ return;
+ }
+ elsif (!defined($nathost_public_ip_address)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create NAT host OS
object, NAT host public IP address is not defined");
+ return;
+ }
+ elsif (!defined($nathost_internal_ip_address)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create NAT host OS
object, NAT host internal IP address is not defined");
+ return;
+ }
+
+ my $nathost_os;
+
if ($nathost_resource_type eq 'managementnode') {
notify($ERRORS{'DEBUG'}, 0, "NAT host resource type is
$nathost_resource_type, returning management node OS object to control
$nathost_hostname");
- return $self->mn_os();
+ $nathost_os = $self->mn_os();
}
elsif ($nathost_resource_type eq 'computer') {
# Get the computer info in order to determine the OS module to
use
@@ -760,15 +777,12 @@ my $self = shift;
notify($ERRORS{'DEBUG'}, 0, "NAT host resource type is
$nathost_resource_type, creating $computer_os_package OS object to control
$nathost_hostname based its current computer.currentimagerevision value");
}
- my $nathost_os = $self->create_object($computer_os_package, {
+ $nathost_os = $self->create_object($computer_os_package, {
#request_data => $request_data,
reservation_id => $reservation_id,
computer_identifier => $nathost_resource_subid
});
- if ($nathost_os) {
- return $nathost_os;
- }
- else {
+ if (!$nathost_os) {
notify($ERRORS{'WARNING'}, 0, "failed to create NAT
host OS object to control $nathost_hostname");
return;
}
@@ -777,6 +791,29 @@ my $self = shift;
notify($ERRORS{'WARNING'}, 0, "unable to create NAT host OS
object to control $nathost_hostname, NAT host resource type is not supported:
$nathost_resource_type, NAT host info:\n" .
format_data($self->data->get_nathost_info()));
return;
}
+
+ # All of the following should always be configured
+ my $nathost_os_type = ref($nathost_os);
+ if (!$nathost_os->firewall()) {
+ notify($ERRORS{'WARNING'}, 0, "created $nathost_os_type NAT
host OS object but firewall object is not available");
+ return;
+ }
+
+ my $firewall_type = ref($nathost_os->firewall());
+ if (!$nathost_os->firewall->can('nat_configure_host')) {
+ notify($ERRORS{'WARNING'}, 0, "created $nathost_os_type NAT
host OS object but NAT host OS's $firewall_type firewall object does NOT
implement a 'nat_configure_host' method");
+ return;
+ }
+ elsif (!$nathost_os->firewall->can('nat_configure_reservation')) {
+ notify($ERRORS{'WARNING'}, 0, "created $nathost_os_type NAT
host OS object but NAT host OS's $firewall_type firewall object does NOT
implement a 'nat_configure_reservation' method");
+ return;
+ }
+
+ # Set NAT host DataStructure values so they can be accessed from
$self->nathost_os and $self->nathost_os->firewall
+
$nathost_os->data->set_nathost_public_ip_address($nathost_public_ip_address);
+
$nathost_os->data->set_nathost_internal_ip_address($nathost_internal_ip_address);
+
+ return $nathost_os
}
#//////////////////////////////////////////////////////////////////////////////
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1796111&r1=1796110&r2=1796111&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Wed May 24 22:22:40 2017
@@ -193,10 +193,17 @@ sub post_load {
Parameters : none
Returns : boolean
- Description : Performs common OS steps to reserve the computer for a user. The
- public IP address is updated if necessary. User accounts are
- added. The 'reserve' subroutine should never open the firewall
- for a connection. This is done by the 'grant_access' subroutine.
+ Description : Performs common OS steps to reserve the computer for a user:
+ * The public IP address is updated if necessary
+ * If the computer is mapped to a NAT
host:
+ ** General NAT host configuration is
performed if not previously
+ done.
+ ** The NAT host is prepared for the
reservation but specific port
+ forwardings are not added.
+ * User accounts are added
+
+ Note: The 'reserve' subroutine should
never open the firewall for
+ a connection. This is done by the
'grant_access' subroutine.
=cut
@@ -207,12 +214,32 @@ sub reserve {
return;
}
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $nathost_hostname = $self->data->get_nathost_hostname(0);
+
# Make sure the public IP address assigned to the computer matches the
database
if (!$self->update_public_ip_address()) {
notify($ERRORS{'WARNING'}, 0, "unable to reserve computer,
failed to update IP address");
return;
}
+
+ # Check if the computer is mapped to a NAT host
+ if ($nathost_hostname) {
+ # Perform general NAT host configuration - this only needs to
be done once, nat_configure_host checks if it was already done
+ if (!$self->nathost_os->firewall->nat_configure_host()) {
+ notify($ERRORS{'WARNING'}, 0, "unable to reserve
$computer_node_name, failed to configure NAT on $nathost_hostname");
+ return;
+ }
+
+ # Perform reservation-specific NAT configuration
+ if (!$self->nathost_os->firewall->nat_configure_reservation()) {
+ notify($ERRORS{'WARNING'}, 0, "unable to reserve
$computer_node_name, failed to configure NAT on $nathost_hostname for this
reservation");
+ return;
+ }
+ }
+
+
# Add user accounts to the computer
if (!$self->add_user_accounts()) {
notify($ERRORS{'WARNING'}, 0, "unable to reserve computer,
failed add user accounts");
@@ -1441,6 +1468,8 @@ sub update_public_ip_address {
my $image_os_type = $self->data->get_image_os_type() || return;
my $computer_public_ip_address =
$self->data->get_computer_public_ip_address();
my $public_ip_configuration =
$self->data->get_management_node_public_ip_configuration() || return;
+ my $nathost_hostname = $self->data->get_nathost_hostname(0);
+ my $nathost_internal_ip_address =
$self->data->get_nathost_internal_ip_address(0);
if ($public_ip_configuration =~ /dhcp/i) {
notify($ERRORS{'DEBUG'}, 0, "IP configuration is set to
$public_ip_configuration, attempting to retrieve dynamic public IP address from
$computer_node_name");
@@ -1481,6 +1510,19 @@ sub update_public_ip_address {
notify($ERRORS{'DEBUG'}, 0, "public IP address in
computer table is already correct for $computer_node_name:
$computer_public_ip_address");
}
+ # If the computer is assigned to a NAT host, make sure default
gateway is correct
+ if ($nathost_hostname && $nathost_internal_ip_address) {
+ my $current_default_gateway =
$self->get_default_gateway();
+ if ($current_default_gateway) {
+ if ($current_default_gateway eq
$nathost_internal_ip_address) {
+ notify($ERRORS{'DEBUG'}, 0, "static
default gateway does NOT need to be set on $computer_node_name, default gateway
assigned by DHCP matches NAT host internal IP address:
$current_default_gateway");
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "static
default gateway needs to be set on $computer_node_name, default gateway
assigned by DHCP ($current_default_gateway) does NOT match NAT host internal IP
address: $nathost_internal_ip_address");
+ $self->set_static_default_gateway();
+ }
+ }
+ }
}
elsif ($public_ip_configuration =~ /static/i) {
notify($ERRORS{'DEBUG'}, 0, "IP configuration is set to
$public_ip_configuration, attempting to set public IP address");
@@ -1510,6 +1552,68 @@ sub update_public_ip_address {
#//////////////////////////////////////////////////////////////////////////////
+=head2 get_correct_default_gateway
+
+ Parameters : none
+ Returns : boolean
+ Description : Determines which IP address should be used for the computer's
+ default gateway:
+ * If the computer is configured to use a NAT host, the
computer's
+ default gateway should be set to the NAT host's internal IP
+ address
+ * If NAT is not used and the management node profile is
+ configured to use static public IP addresses, the computer's
+ default gateway should be set to the management node profile's
+ "Public Gateway" setting
+ * If NAT is not used and the management node profile is
+ configured to use DHCP-assigned public IP addresses, the
+ computer's current default gateway should continue to be used
+
+=cut
+
+sub get_correct_default_gateway {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return 0;
+ }
+
+ my $computer_name = $self->data->get_computer_short_name();
+ my $nathost_hostname = $self->data->get_nathost_hostname(0);
+ my $nathost_internal_ip_address =
$self->data->get_nathost_internal_ip_address(0);
+ my $management_node_ip_configuration =
$self->data->get_management_node_public_ip_configuration();
+
+ if ($nathost_internal_ip_address) {
+ notify($ERRORS{'DEBUG'}, 0, "$computer_name is configured to
use NAT host $nathost_hostname, default gateway should be set to NAT host's
internal IP address: $nathost_internal_ip_address");
+ return $nathost_internal_ip_address;
+ }
+ elsif ($management_node_ip_configuration =~ /static/i) {
+ my $management_node_public_default_gateway =
$self->data->get_management_node_public_default_gateway();
+ if ($management_node_public_default_gateway) {
+ notify($ERRORS{'DEBUG'}, 0, "management node public IP
mode is set to $management_node_ip_configuration, default gateway should be set
to management node profile's default gateway setting:
$management_node_public_default_gateway");
+ return $management_node_public_default_gateway;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine
correct default gateway to use on $computer_name, management node public IP
mode is set to $management_node_ip_configuration but management node profile's
default gateway setting could not be determined");
+ return;
+ }
+ }
+ else {
+ # Management node configured to use DHCP for public IP addresses
+ # Get default gateway address assigned to computer
+ my $current_default_gateway =
$self->get_public_default_gateway();
+ if ($current_default_gateway) {
+ notify($ERRORS{'DEBUG'}, 0, "management node public IP
mode is set to $management_node_ip_configuration, default gateway currently
configured on $computer_name should be used: $current_default_gateway");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine
correct default gateway to use on $computer_name, management node public IP
mode is set to $management_node_ip_configuration but default gateway currently
configured on $computer_name could not be determined");
+ return;
+ }
+ }
+}
+
+#//////////////////////////////////////////////////////////////////////////////
+
=head2 get_current_image_tag
Parameters : $tag_name
@@ -3013,6 +3117,11 @@ sub remove_lines_from_file {
my @lines_removed;
my @lines_retained;
+ if (!$self->file_exists($file_path)) {
+ notify($ERRORS{'DEBUG'}, 0, "lines containing '$pattern' not
removed because file does NOT exist: $file_path");
+ return 1;
+ }
+
my @lines = $self->get_file_contents($file_path);
for my $line (@lines) {
if ($line =~ /$pattern/) {
@@ -3664,60 +3773,7 @@ sub process_connect_methods {
$overwrite = 0;
}
- # Check if NAT is used
- my $computer_ip_address;
- if ($nathost_hostname) {
- if (!$self->nathost_os(0)) {
- notify($ERRORS{'WARNING'}, 0, "unable to process
connect methods, $computer_node_name is assigned to NAT host $nathost_hostname
but NAT host OS object is not available");
- return;
- }
- elsif (!$self->nathost_os->firewall()) {
- notify($ERRORS{'WARNING'}, 0, "unable to process
connect methods, $computer_node_name is assigned to NAT host $nathost_hostname
but NAT host OS's firewall object is not available");
- return;
- }
- elsif (!$nathost_public_ip_address) {
- notify($ERRORS{'WARNING'}, 0, "unable to process
connect methods, $computer_node_name is assigned to NAT host $nathost_hostname
but NAT host public IP address could not be determined from the nathost table");
- return;
- }
- elsif (!$nathost_internal_ip_address) {
- notify($ERRORS{'WARNING'}, 0, "unable to process
connect methods, $computer_node_name is assigned to NAT host $nathost_hostname
but NAT host internal IP address could not be determined from the nathost
table");
- return;
- }
-
- # Get the IP address used to communicate between the NAT host
and computer
- $computer_ip_address = $self->get_public_ip_address();
- if (!$computer_ip_address) {
- notify($ERRORS{'WARNING'}, 0, "unable to process
connect methods, failed to retrieve public (internal NAT) IP address of
computer $computer_node_name, unable to configure NAT port forwarding");
- return;
- }
-
- # Perform general NAT configuration
- if ($nathost_internal_ip_address) {
- if
($self->nathost_os->firewall->can('nat_configure_host')) {
- if
(!$self->nathost_os->firewall->nat_configure_host($nathost_public_ip_address,
$nathost_internal_ip_address)) {
- notify($ERRORS{'WARNING'}, 0, "unable
to process connect methods, failed to configure NAT on $nathost_hostname");
- return;
- }
- }
- else {
- notify($ERRORS{'DEBUG'}, 0, "NAT not configured
on $nathost_hostname, " . ref($self->nathost_os->firewall) . " does not
implement a 'nat_configure_host' subroutine");
- }
- }
- else {
- notify($ERRORS{'DEBUG'}, 0, "unable to configure NAT,
nathost.publicIPaddress is not set in the database for $nathost_hostname");
- }
-
- # Perform reservation-specific NAT configuration
- if
($self->nathost_os->firewall->can('nat_configure_reservation')) {
- if
(!$self->nathost_os->firewall->nat_configure_reservation()) {
- notify($ERRORS{'WARNING'}, 0, "unable to
process connect methods, failed to configure NAT on $nathost_hostname for this
reservation");
- return;
- }
- }
- else {
- notify($ERRORS{'DEBUG'}, 0, "NAT not configured on
$nathost_hostname for this reservation, " . ref($self->nathost_os->firewall) .
" does not implement a 'nat_configure_reservation' subroutine");
- }
- }
+ my $computer_ip_address = $self->get_public_ip_address();
CONNECT_METHOD: for my $connect_method_id (sort keys
%{$connect_method_info} ) {
my $connect_method = $connect_method_info->{$connect_method_id};
@@ -3805,11 +3861,7 @@ sub process_connect_methods {
notify($ERRORS{'WARNING'}, 0,
"$computer_node_name is assigned to NAT host $nathost_hostname but connect
method info does not contain NAT port information:\n" .
format_data($connect_method));
return;
}
-
- if
($self->nathost_os->firewall->nat_add_port_forward($protocol, $nat_public_port,
$computer_ip_address, $port)) {
- notify($ERRORS{'OK'}, 0, "NAT
port forwarding configured on $nathost_hostname for '$name' connect method:
$nathost_public_ip_address:$nat_public_port --> $computer_ip_address:$port
($protocol)");
- }
- else {
+ elsif
(!$self->nathost_os->firewall->nat_add_port_forward($protocol,
$nat_public_port, $computer_ip_address, $port)) {
notify($ERRORS{'WARNING'}, 0,
"failed to configure NAT port forwarding on $nathost_hostname for '$name'
connect method: $nathost_public_ip_address:$nat_public_port -->
$computer_ip_address:$port ($protocol)");
return;
}
@@ -5261,6 +5313,86 @@ sub unmount_nfs_shares {
}
#//////////////////////////////////////////////////////////////////////////////
+
+=head2 set_config_file_parameter
+
+ Parameters : $file_path, $parameter_name_argument, $delimiter,
$parameter_value_argument
+ Returns : boolean
+ Description : Adds a parameter/value line to a text-based config file. If a
+ line already exists that matches the parameter name, it will be
+ modified if the value is different. If no line already exists
+ that matches the parameter name, a line will be added to the end
+ of the file.
+
+ The $delimiter argument may contain spaces if a line should be
+ formatted such as: myParam = myValue
+
+ For this example, the $delimiter argument should be ' = '.
+
+=cut
+
+sub set_config_file_parameter {
+ my $self = shift;
+ if (ref($self) !~ /linux/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return 0;
+ }
+
+ my ($file_path, $parameter_name_argument, $delimiter,
$parameter_value_argument) = @_;
+ if (!defined($file_path)) {
+ notify($ERRORS{'WARNING'}, 0, "file path argument was not
supplied");
+ return;
+ }
+ elsif (!defined($parameter_name_argument)) {
+ notify($ERRORS{'WARNING'}, 0, "parameter name argument was not
supplied");
+ return;
+ }
+ elsif (!defined($delimiter)) {
+ notify($ERRORS{'WARNING'}, 0, "$delimiter character argument
was not supplied");
+ return;
+ }
+ elsif (!defined($parameter_value_argument)) {
+ notify($ERRORS{'WARNING'}, 0, "parameter value argument was not
supplied");
+ return;
+ }
+
+ (my $delimiter_cleaned = $delimiter) =~ s/(^\s+|\s+$)//g;
+
+ my @original_lines = $self->get_file_contents($file_path);
+ my @updated_lines;
+ my $parameter_found = 0;
+ for my $original_line (@original_lines) {
+ if ($original_line =~
/^\s*$parameter_name_argument\s*$delimiter_cleaned/i) {
+ if (!$parameter_found) {
+ $parameter_found = 1;
+ my $updated_line = $parameter_name_argument .
$delimiter . $parameter_value_argument;
+ if ($original_line ne $updated_line) {
+ notify($ERRORS{'DEBUG'}, 0, "updating
line in $file_path: '$original_line' --> '$updated_line'");
+ push @updated_lines, $updated_line;
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "existing
line in $file_path does not need to be modified: '$original_line'");
+ push @updated_lines, $original_line;
+ }
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "omitting duplicate
'$parameter_name_argument' line in $file_path: '$original_line'");
+ }
+ next;
+ }
+ else {
+ push @updated_lines, $original_line;
+ }
+ }
+
+ if (!$parameter_found) {
+ push @updated_lines, $parameter_name_argument . $delimiter .
$parameter_value_argument;
+ }
+
+ return $self->create_text_file($file_path, join("\n", @updated_lines));
+}
+
+#//////////////////////////////////////////////////////////////////////////////
1;
__END__
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=1796111&r1=1796110&r2=1796111&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Wed May 24 22:22:40 2017
@@ -342,9 +342,11 @@ sub firewall {
notify($ERRORS{'DEBUG'}, 0, "$firewall_perl_package
object could not be initialized");
}
else {
- my $address = sprintf('%x', $firewall_object);
- notify($ERRORS{'DEBUG'}, 0, "$firewall_perl_package
object created, address: $address");
$self->{firewall} = $firewall_object;
+ my $linux_address = sprintf('%x', $self);
+ my $firewall_object_address = sprintf('%x',
$firewall_object);
+ my $self_firewall_address = sprintf('%x',
$self->{firewall});
+ notify($ERRORS{'DEBUG'}, 0, "$firewall_perl_package
object created for $computer_node_name, Linux object address: $linux_address,
firewall object address: $firewall_object_address, \$self->{firewall} address:
$self_firewall_address");
return $firewall_object;
}
}
@@ -433,15 +435,26 @@ sub pre_capture {
}
# Configure the private and public interfaces to use DHCP
- if (!$self->enable_dhcp($self->get_private_interface_name())) {
+ my $private_interface_name = $self->get_private_interface_name();
+ my $public_interface_name = $self->get_public_interface_name();
+
+ if (!$self->enable_dhcp($private_interface_name)) {
notify($ERRORS{'WARNING'}, 0, "failed to enable DHCP on the
private interface");
return;
}
- if (!$self->enable_dhcp($self->get_public_interface_name())) {
+ if (!$self->enable_dhcp($public_interface_name)) {
notify($ERRORS{'WARNING'}, 0, "failed to enable DHCP on the
public interface");
return;
}
+ # Delete route files if they exist for either the private or public
interface
+
$self->delete_file("/etc/sysconfig/network-scripts/route-$private_interface_name");
+
$self->delete_file("/etc/sysconfig/network-scripts/route-$public_interface_name");
+
+ # Remove computer/reservation specific lines from network file
+ $self->remove_lines_from_file('/etc/sysconfig/network', 'HOSTNAME');
+ $self->remove_lines_from_file('/etc/sysconfig/network', 'GATEWAY');
+
# Shut the computer down
if ($self->{end_state} =~ /off/i) {
notify($ERRORS{'DEBUG'}, 0, "shutting down $computer_node_name,
provisioning module specified end state: $self->{end_state}");
@@ -926,7 +939,7 @@ sub set_static_public_address {
}
# Set default gateway
- if (!$self->set_default_gateway($default_gateway,
$public_interface_name)) {
+ if (!$self->set_static_default_gateway($default_gateway,
$public_interface_name)) {
notify($ERRORS{'WARNING'}, 0, "failed to set static public IP
address on $computer_name, default gateway could not be set");
return;
}
@@ -1127,42 +1140,45 @@ sub delete_default_gateway {
#//////////////////////////////////////////////////////////////////////////////
-=head2 set_default_gateway
+=head2 set_static_default_gateway
- Parameters : $default_gateway, $interface_name (optional)
+ Parameters : $default_gateway (optional)
Returns : boolean
Description : Sets the default route. If no interface argument is supplied,
the
public interface is used.
=cut
-sub set_default_gateway {
+sub set_static_default_gateway {
my $self = shift;
if (ref($self) !~ /linux/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return 0;
}
- my $default_gateway = shift;
- if (!defined($default_gateway)) {
- notify($ERRORS{'WARNING'}, 0, "default gateway argument not
supplied");
+ my $computer_name = $self->data->get_computer_short_name();
+
+ my $default_gateway = shift || $self->get_correct_default_gateway();
+ if (!$default_gateway) {
+ notify($ERRORS{'WARNING'}, 0, "unable to set static default
gateway on $computer_name, argument was not supplied and correct default
gateway IP address could not be determined");
return;
}
- my $computer_name = $self->data->get_computer_short_name();
+ my $current_default_gateway = $self->get_public_default_gateway();
+ if ($current_default_gateway eq $default_gateway) {
+ notify($ERRORS{'OK'}, 0, "default gateway on $computer_name is
already set to $current_default_gateway");
+ return 1;
+ }
- my $interface_name = shift;
- if (!defined($interface_name)) {
- $interface_name = $self->get_public_interface_name();
- if (!$interface_name) {
- notify($ERRORS{'WARNING'}, 0, "unable to set static
default gateway on $computer_name, interface name argument was not supplied and
public interface name could not be determined");
- return;
- }
+ my $interface_name = $self->get_public_interface_name();
+ if (!$interface_name) {
+ notify($ERRORS{'WARNING'}, 0, "unable to set static default
gateway on $computer_name, public interface name could not be determined");
+ return;
}
# Delete existing default gateway or else error will occur: SIOCADDRT:
File exists
$self->delete_default_gateway();
-
+
my $command = "/sbin/route add default gw $default_gateway metric 0
$interface_name";
my ($exit_status, $output) = $self->execute($command);
if (!defined($output)) {
@@ -1176,9 +1192,26 @@ sub set_default_gateway {
# Create a route file so default route persists across reboots
my $route_file_path =
"/etc/sysconfig/network-scripts/route-$interface_name";
+ # For testing:
+ #$self->delete_file($route_file_path);
my $route_file_contents = "default via $default_gateway dev
$interface_name";
$self->create_text_file($route_file_path, $route_file_contents);
+ # Adding a route-* file does not prevent computer from obtaining a
default route via DHCP
+ # Add a 'DEFROUTE=no' line to the ifcfg-<interface> file
+ my $interface_file =
"/etc/sysconfig/network-scripts/ifcfg-$interface_name";
+ # For testing:
+ #$self->remove_lines_from_file($interface_file, 'DEFROUTE');
+ if ($self->file_exists($interface_file)) {
+ $self->set_config_file_parameter($interface_file, 'DEFROUTE',
'=', 'no');
+ }
+
+ # Note: leave for future reference, this doesn't seem to work on
CentOS/RHEL 7
+ # Add a 'GATEWAY=' line to /etc/sysconfig/network
+ #my $network_file = "/etc/sysconfig/network";
+ # For testing: $self->remove_lines_from_file($network_file, 'GATEWAY');
+ #$self->set_config_file_parameter($network_file, 'GATEWAY', '=',
$default_gateway);
+
notify($ERRORS{'OK'}, 0, "set default gateway on $computer_name to
$default_gateway, interface: $interface_name");
return 1;
}
@@ -5284,8 +5317,8 @@ sub get_port_connection_info {
Parameters : none
Returns : boolean
- Description : Enables IP forwarding by executing:
- echo 1 > /proc/sys/net/ipv4/ip_forward
+ Description : Adds 'net.ipv4.ip_forward=1' to /etc/sysctl.conf if it doesn't
+ already exist. Executes 'sysctl -p' to apply the setting.
=cut
@@ -5298,19 +5331,25 @@ sub enable_ip_forwarding {
my $computer_node_name = $self->data->get_computer_node_name();
- my $command = "echo 1 > /proc/sys/net/ipv4/ip_forward";
- my ($exit_status, $output) = $self->execute($command, 0);
+ my $sysctl_conf_path = '/etc/sysctl.conf';
+ $self->set_config_file_parameter($sysctl_conf_path,
'net.ipv4.ip_forward', '=', '1');
+
+ my $command = "sysctl -p";
+ my ($exit_status, $output) = $self->execute($command);
if (!defined($output)) {
notify($ERRORS{'WARNING'}, 0, "failed to execute command to
enable IP forwarding on $computer_node_name: $command");
return;
}
- elsif ($exit_status ne '0') {
- notify($ERRORS{'WARNING'}, 0, "failed to enable IP forwarding
on $computer_node_name, command: '$command', exit status: $exit_status,
output:\n" . join("\n", @$output));
- return 0;
+
+ # Output should contain:
+ # net.ipv4.ip_forward = 1
+ if ($exit_status eq '0' || grep(/net.ipv4.ip_forward.*1/, @$output)) {
+ notify($ERRORS{'OK'}, 0, "IP forwarding is enabled on
$computer_node_name:\n" . join("\n", @$output));
+ return 1;
}
else {
- notify($ERRORS{'OK'}, 0, "verified IP forwarding is enabled on
$computer_node_name");
- return 1;
+ notify($ERRORS{'WARNING'}, 0, "failed to enable IP forwarding
on $computer_node_name, command: '$command', exit status: $exit_status,
output:\n" . join("\n", @$output));
+ return 0;
}
}
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm?rev=1796111&r1=1796110&r2=1796111&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm Wed May 24
22:22:40 2017
@@ -534,7 +534,7 @@ sub set_static_public_address {
}
# Set the default gateway
- if (!$self->set_default_gateway($public_default_gateway,
$public_interface_name)) {
+ if (!$self->set_static_default_gateway($public_default_gateway,
$public_interface_name)) {
notify($ERRORS{'WARNING'}, 0, "failed to set static public IP
address to $public_ip_address on $computer_name, failed to set the default
gateway");
return;
}
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/firewalld.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/firewalld.pm?rev=1796111&r1=1796110&r2=1796111&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/firewalld.pm
(original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/firewalld.pm Wed
May 24 22:22:40 2017
@@ -392,50 +392,67 @@ sub delete_chain {
return 0;
}
- my ($table_name, $chain_name) = @_;
+ my ($table_name, $chain_name_argument) = @_;
if (!defined($table_name)) {
notify($ERRORS{'WARNING'}, 0, "table name argument was not
specified");
return;
}
- elsif (!defined($chain_name)) {
+ elsif (!defined($chain_name_argument)) {
notify($ERRORS{'WARNING'}, 0, "chain name argument was not
specified");
return;
}
my $computer_name = $self->data->get_computer_hostname();
- # Delete all rules which reference the chain being deleted or else the
chain can't be deleted
- # Do this BEFORE checking if the chain exists to clean up leftover
references in direct.xml
- if (!$self->delete_chain_references($table_name, $chain_name)) {
- notify($ERRORS{'WARNING'}, 0, "unable to delete '$chain_name'
chain from '$table_name' table on $computer_name, failed to delete all rules
which reference the chain prior to deletion");
- return;
- }
-
- $self->remove_direct_chain_rules($table_name, $chain_name) || return;
+ my @chains_deleted;
+ my @chain_names = $self->get_table_chain_names($table_name);
+ for my $chain_name (@chain_names) {
+ if ($chain_name !~ /^$chain_name_argument$/) {
+ next;
+ }
+
+ # Delete all rules which reference the chain being deleted or
else the chain can't be deleted
+ # Do this BEFORE checking if the chain exists to clean up
leftover references in direct.xml
+ if (!$self->delete_chain_references($table_name, $chain_name)) {
+ notify($ERRORS{'WARNING'}, 0, "unable to delete
'$chain_name' chain from '$table_name' table on $computer_name, failed to
delete all rules which reference the chain prior to deletion");
+ return;
+ }
- my $command = "firewall-cmd --permanent --direct --remove-chain ipv4
$table_name $chain_name";
- my ($exit_status, $output) = $self->os->execute($command, 0);
- if (!defined($output)) {
- notify($ERRORS{'WARNING'}, 0, "failed to execute command
$computer_name: $command");
- return;
- }
- elsif (grep(/NOT_ENABLED/i, @$output)) {
- notify($ERRORS{'OK'}, 0, "'$chain_name' chain in '$table_name'
does not exist on $computer_name");
- }
- elsif ($exit_status ne '0') {
- notify($ERRORS{'WARNING'}, 0, "failed to delete '$chain_name'
chain in '$table_name' table on $computer_name, exit status: $exit_status,
command:\n$command\noutput:\n" . join("\n", @$output));
- return 0;
- }
- elsif (!grep(/success/, @$output)) {
- notify($ERRORS{'WARNING'}, 0, "potentially failed to delete
'$chain_name' chain in '$table_name' table on $computer_name, output does not
contain 'success', exit status: $exit_status, command:\n$command\noutput:\n" .
join("\n", @$output));
- }
- else {
- notify($ERRORS{'OK'}, 0, "deleted '$chain_name' chain in
'$table_name' table on $computer_name");
- #$self->save_configuration();
+ $self->remove_direct_chain_rules($table_name, $chain_name) ||
return;
+
+ my $command = "firewall-cmd --permanent --direct --remove-chain
ipv4 $table_name $chain_name";
+ my ($exit_status, $output) = $self->os->execute($command, 0);
+ if (!defined($output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute
command $computer_name: $command");
+ return;
+ }
+ elsif (grep(/NOT_ENABLED/i, @$output)) {
+ notify($ERRORS{'OK'}, 0, "'$chain_name' chain in
'$table_name' does not exist on $computer_name");
+ }
+ elsif ($exit_status ne '0') {
+ notify($ERRORS{'WARNING'}, 0, "failed to delete
'$chain_name' chain in '$table_name' table on $computer_name, exit status:
$exit_status, command:\n$command\noutput:\n" . join("\n", @$output));
+ return 0;
+ }
+ elsif (!grep(/success/, @$output)) {
+ notify($ERRORS{'WARNING'}, 0, "potentially failed to
delete '$chain_name' chain in '$table_name' table on $computer_name, output
does not contain 'success', exit status: $exit_status,
command:\n$command\noutput:\n" . join("\n", @$output));
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "deleted '$chain_name' chain
in '$table_name' table on $computer_name");
+ #$self->save_configuration();
+ }
+
+ if (!$self->clean_direct_xml($table_name . '.*jump\s+' .
$chain_name)) {
+ return;
+ }
+
+ notify($ERRORS{'OK'}, 0, "deleted '$chain_name' chain from
'$table_name' table on $computer_name");
+ push @chains_deleted, $chain_name;
}
- return $self->clean_direct_xml($table_name . '.*jump\s+' . $chain_name);
- #$self->delete_chain_references($table_name, $chain_name);
+ if (!@chains_deleted) {
+ notify($ERRORS{'DEBUG'}, 0, "no chains exist in '$table_name'
table on $computer_name matching argument: '$chain_name_argument'");
+ }
+ return 1;
}
#//////////////////////////////////////////////////////////////////////////////
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=1796111&r1=1796110&r2=1796111&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 Wed
May 24 22:22:40 2017
@@ -930,10 +930,10 @@ sub get_matching_rules {
return @matching_rules;
}
elsif (!defined($table_info->{$chain_name}{rules})) {
- notify($ERRORS{'DEBUG'}, 0, "no rules match on $computer_name,
$chain_name chain in $table_name table contains no rules");
+ notify($ERRORS{'DEBUG'}, 0, "no rules match on $computer_name,
$chain_name chain in $table_name table contains no rules") if ($self->{debug});
return @matching_rules;
}
-
+
# This sub was designed to accept a hash reference argument to match
other
# parts of this module. However, we need to compare the hash reference
# argument to the hash reference which contains current rule info.
Comparing
@@ -952,7 +952,7 @@ sub get_matching_rules {
notify($ERRORS{'WARNING'}, 0, "failed to determine if any rules
match on $computer_name, attempt to collapse the rule specification hash
reference argument produced a result with no keys:\n" .
format_data($rule_specification_hashref));
return;
}
- #notify($ERRORS{'DEBUG'}, 0, "checking if $chain_name chain in
$table_name table on $computer_name has any rules matching specifications:\n" .
format_data($collapsed_specification));
+ notify($ERRORS{'DEBUG'}, 0, "checking if $chain_name chain in
$table_name table on $computer_name has any rules matching specifications:\n" .
format_data($collapsed_specification)) if ($self->{debug});
# Some iptables options may take multiple forms
# Attempt to try all forms
@@ -962,6 +962,8 @@ sub get_matching_rules {
};
RULE: for my $rule (@{$table_info->{$chain_name}{rules}}) {
+ my $rule_specification = $rule->{rule_specification};
+
for my $specification_key (keys %$collapsed_specification) {
# Ignore comments when comparing
if ($specification_key =~ /(comment)/i) {
@@ -997,17 +999,22 @@ sub get_matching_rules {
return;
}
elsif (!defined($rule_value)) {
- #notify($ERRORS{'DEBUG'}, 0, "ignoring rule on
$computer_name, it does not contain a $specification_key value");
+ notify($ERRORS{'DEBUG'}, 0, "ignoring rule on
$computer_name, it does not contain a $specification_key value, rule
specification: '$rule_specification'") if ($self->{debug});
next RULE;
}
if ($rule_value ne $specification_value && $rule_value
!~ /^$specification_value(\/32)?$/i) {
- #notify($ERRORS{'DEBUG'}, 0, "ignoring rule on
$computer_name, $specification_key value does not match, rule: '$rule_value',
argument:'$specification_value'");
+ #notify($ERRORS{'DEBUG'}, 0, "ignoring rule on
$computer_name:\n" .
+ # "rule_specification :
'$rule_specification'\n" .
+ # "specification key :
'$specification_key'\n" .
+ # "argument value :
'$specification_value'\n" .
+ # "rule value : '$rule_value'"
+ #);
next RULE;
}
}
- notify($ERRORS{'DEBUG'}, 0, "rule matches: " .
$rule->{rule_specification});
+ notify($ERRORS{'DEBUG'}, 0, "rule matches:
$rule_specification");
push @matching_rules, $rule;
}
@@ -1239,56 +1246,63 @@ sub delete_chain {
return 0;
}
- my ($table_name, $chain_name) = @_;
+ my ($table_name, $chain_name_argument) = @_;
if (!defined($table_name)) {
notify($ERRORS{'WARNING'}, 0, "table name argument was not
specified");
return;
}
- elsif (!defined($chain_name)) {
+ elsif (!defined($chain_name_argument)) {
notify($ERRORS{'WARNING'}, 0, "chain name argument was not
specified");
return;
}
my $computer_name = $self->data->get_computer_hostname();
- my $table_info = $self->get_table_info($table_name);
- if (!defined($table_info->{$chain_name})) {
- notify($ERRORS{'DEBUG'}, 0, "'$chain_name' chain in
'$table_name' table does not exist on $computer_name");
- return 1;
- }
-
- # Flush the chain first - delete will fail if the chain still contains
rules
- if (!$self->flush_chain($table_name, $chain_name)) {
- notify($ERRORS{'WARNING'}, 0, "unable to delete '$chain_name'
chain from '$table_name' table on $computer_name, failed to flush chain prior
to deletion");
- return;
- }
-
- # Delete all rules which reference the chain being deleted or else the
chain can't be deleted
- if (!$self->delete_chain_references($table_name, $chain_name)) {
- notify($ERRORS{'WARNING'}, 0, "unable to delete '$chain_name'
chain from '$table_name' table on $computer_name, failed to delete all rules
which reference the chain prior to deletion");
- return;
+ my @chains_deleted;
+ my @chain_names = $self->get_table_chain_names($table_name);
+ for my $chain_name (@chain_names) {
+ if ($chain_name !~ /^$chain_name_argument$/) {
+ next;
+ }
+
+ # Flush the chain first - delete will fail if the chain still
contains rules
+ if (!$self->flush_chain($table_name, $chain_name)) {
+ notify($ERRORS{'WARNING'}, 0, "unable to delete
'$chain_name' chain from '$table_name' table on $computer_name, failed to flush
chain prior to deletion");
+ return;
+ }
+
+ # Delete all rules which reference the chain being deleted or
else the chain can't be deleted
+ if (!$self->delete_chain_references($table_name, $chain_name)) {
+ notify($ERRORS{'WARNING'}, 0, "unable to delete
'$chain_name' chain from '$table_name' table on $computer_name, failed to
delete all rules which reference the chain prior to deletion");
+ return;
+ }
+
+ my $command = "/sbin/iptables --delete-chain $chain_name
--table $table_name";
+
+ my $semaphore = $self->get_iptables_semaphore();
+ my ($exit_status, $output) = $self->os->execute($command, 0);
+ if (!defined($output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute
command $computer_name: $command");
+ return;
+ }
+ elsif (grep(/Too many links/i, @$output)) {
+ notify($ERRORS{'WARNING'}, 0, "unable to delete
'$chain_name' chain from '$table_name' table on $computer_name, the chain is
referenced by another rule");
+ return;
+ }
+ elsif ($exit_status ne '0') {
+ notify($ERRORS{'WARNING'}, 0, "failed to delete
'$chain_name' chain from '$table_name' table on $computer_name, exit status:
$exit_status, command:\n$command\noutput:\n" . join("\n", @$output));
+ return;
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "deleted '$chain_name' chain
from '$table_name' table on $computer_name");
+ push @chains_deleted, $chain_name;
+ }
}
- my $command = "/sbin/iptables --delete-chain $chain_name --table
$table_name";
-
- my $semaphore = $self->get_iptables_semaphore();
- my ($exit_status, $output) = $self->os->execute($command, 0);
- if (!defined($output)) {
- notify($ERRORS{'WARNING'}, 0, "failed to execute command
$computer_name: $command");
- return;
- }
- elsif (grep(/Too many links/i, @$output)) {
- notify($ERRORS{'WARNING'}, 0, "unable to delete '$chain_name'
chain from '$table_name' table on $computer_name, the chain is referenced by
another rule");
- return 0;
- }
- elsif ($exit_status ne '0') {
- notify($ERRORS{'WARNING'}, 0, "failed to delete '$chain_name'
chain from '$table_name' table on $computer_name, exit status: $exit_status,
command:\n$command\noutput:\n" . join("\n", @$output));
- return 0;
- }
- else {
- notify($ERRORS{'OK'}, 0, "deleted '$chain_name' chain from
'$table_name' table on $computer_name");
- return 1;
+ if (!@chains_deleted) {
+ notify($ERRORS{'DEBUG'}, 0, "no chains exist in '$table_name'
table on $computer_name matching argument: '$chain_name_argument'");
}
+ return 1;
}
#//////////////////////////////////////////////////////////////////////////////
@@ -1405,7 +1419,7 @@ sub get_table_chain_names {
my $table_info = $self->get_table_info($table_name, 1) || return;
my @table_chain_names = sort keys %$table_info;
- notify($ERRORS{'DEBUG'}, 0, "retrieved chain names defined in
$table_name table on $computer_name:\n" . join("\n", @table_chain_names));
+ notify($ERRORS{'DEBUG'}, 0, "retrieved chain names defined in
$table_name table on $computer_name: " . join(', ', @table_chain_names)) if
($self->{debug});
return @table_chain_names;
}
@@ -1428,7 +1442,7 @@ sub nat_sanitize_reservation {
}
my $reservation_id = shift || $self->data->get_reservation_id();
- my $reservation_chain_name =
$self->get_reservation_chain_name($reservation_id);
+ my $reservation_chain_name =
$self->get_nat_reservation_chain_name($reservation_id);
if (!$self->delete_chain('nat', $reservation_chain_name)) {
return;
@@ -1908,7 +1922,7 @@ sub get_table_info {
=head2 nat_configure_host
- Parameters : $public_ip_address, $internal_ip_address
+ Parameters : none
Returns : boolean
Description : Configures the iptables firewall to pass NAT traffic.
@@ -1922,16 +1936,10 @@ sub nat_configure_host {
}
my $computer_name = $self->data->get_computer_hostname();
+ my $public_ip_address = $self->data->get_nathost_public_ip_address();
+ my $internal_ip_address =
$self->data->get_nathost_internal_ip_address();
- my ($public_ip_address, $internal_ip_address) = @_;
- if (!$public_ip_address) {
- notify($ERRORS{'WARNING'}, 0, "unable to automatically
configure NAT, nathost public IP address argument was not specified");
- return;
- }
- if (!$internal_ip_address) {
- notify($ERRORS{'WARNING'}, 0, "unable to automatically
configure NAT, nathost internal IP address argument was not specified");
- return;
- }
+ my $nat_host_chain_name = $self->get_nat_host_chain_name();
# Enable IP port forwarding
if (!$self->os->enable_ip_forwarding()) {
@@ -1954,11 +1962,18 @@ sub nat_configure_host {
}
# Check if NAT has previously been configured
- for my $rule (@{$nat_table_info->{POSTROUTING}{rules}}) {
- my $rule_specification_string = $rule->{rule_specification};
- if ($rule_specification_string =~ /MASQUERADE/) {
- notify($ERRORS{'DEBUG'}, 0, "POSTROUTING chain in nat
table contains a MASQUERADE rule, assuming NAT has already been configured:
$rule_specification_string");
- return 1;
+ if (defined($nat_table_info->{$nat_host_chain_name})) {
+ notify($ERRORS{'DEBUG'}, 0, "NAT has already been configured on
$computer_name, '$nat_host_chain_name' chain exists in nat table");
+ return 1;
+ }
+ else {
+ # Before VCL 2.5, dedicated NAT host chain wasn't created,
check if MASQUERADE rule exists
+ for my $rule (@{$nat_table_info->{POSTROUTING}{rules}}) {
+ my $rule_specification_string =
$rule->{rule_specification};
+ if ($rule_specification_string =~ /MASQUERADE/) {
+ notify($ERRORS{'DEBUG'}, 0, "POSTROUTING chain
in nat table contains a MASQUERADE rule, assuming NAT has already been
configured: $rule_specification_string");
+ return 1;
+ }
}
}
@@ -2011,16 +2026,64 @@ sub nat_configure_host {
$destination_ports .= "$start_port:$end_port";
}
+
+ $self->create_chain('filter', $nat_host_chain_name);
+ $self->create_chain('nat', $nat_host_chain_name);
+ if (!$self->insert_rule('filter', 'INPUT',
+ {
+ 'parameters' => {
+ 'jump' => $nat_host_chain_name,
+ },
+ 'match_extensions' => {
+ 'comment' => {
+ 'comment' => "VCL: jump from filter
table INPUT chain to NAT host $nat_host_chain_name chain",
+ },
+ },
+ }
+ )) {
+ return;
+ }
+
+ if (!$self->insert_rule('filter', 'FORWARD',
+ {
+ 'parameters' => {
+ 'jump' => $nat_host_chain_name,
+ },
+ 'match_extensions' => {
+ 'comment' => {
+ 'comment' => "VCL: jump from filter
table FORWARD chain to NAT host $nat_host_chain_name chain",
+ },
+ },
+ }
+ )) {
+ return;
+ }
+
if (!$self->insert_rule('nat', 'POSTROUTING',
{
'parameters' => {
+ 'jump' => $nat_host_chain_name,
+ },
+ 'match_extensions' => {
+ 'comment' => {
+ 'comment' => "VCL: jump from nat table
POSTROUTING chain to to NAT host $nat_host_chain_name chain",
+ },
+ },
+ }
+ )) {
+ return;
+ }
+
+ if (!$self->insert_rule('nat', $nat_host_chain_name,
+ {
+ 'parameters' => {
'out-interface' => $public_interface_name,
'!destination' =>
"$internal_network_address/$internal_network_bits",
'jump' => 'MASQUERADE',
},
'match_extensions' => {
'comment' => {
- 'comment' => "change IP of outbound
$public_interface_name packets to NAT host IP address $public_ip_address",
+ 'comment' => "VCL: change IP of
outbound $public_interface_name packets to NAT host IP address
$public_ip_address",
},
},
}
@@ -2028,7 +2091,7 @@ sub nat_configure_host {
return;
}
- if (!$self->insert_rule('filter', 'INPUT',
+ if (!$self->insert_rule('filter', $nat_host_chain_name,
{
'parameters' => {
'in-interface' => $public_interface_name,
@@ -2049,7 +2112,7 @@ sub nat_configure_host {
return;
}
- if (!$self->insert_rule('filter', 'INPUT',
+ if (!$self->insert_rule('filter', $nat_host_chain_name,
{
'parameters' => {
'in-interface' => $public_interface_name,
@@ -2070,7 +2133,7 @@ sub nat_configure_host {
return;
}
- if (!$self->insert_rule('filter', 'FORWARD',
+ if (!$self->insert_rule('filter', $nat_host_chain_name,
{
'parameters' => {
'in-interface' => $public_interface_name,
@@ -2090,7 +2153,7 @@ sub nat_configure_host {
return;
}
- if (!$self->insert_rule('filter', 'FORWARD',
+ if (!$self->insert_rule('filter', $nat_host_chain_name,
{
'parameters' => {
'in-interface' => $internal_interface_name,
@@ -2109,6 +2172,7 @@ sub nat_configure_host {
)) {
return;
}
+
$self->save_configuration();
notify($ERRORS{'DEBUG'}, 0, "successfully configured NAT on
$computer_name");
@@ -2143,7 +2207,7 @@ sub nat_configure_reservation {
return;
}
- my $chain_name = $self->get_reservation_chain_name();
+ my $chain_name = $self->get_nat_reservation_chain_name();
# Check if chain for reservation has already been created
if (defined($nat_table_info->{$chain_name})) {
@@ -2216,7 +2280,7 @@ sub nat_add_port_forward {
return;
}
- my $chain_name = $self->get_reservation_chain_name();
+ my $chain_name = $self->get_nat_reservation_chain_name();
$protocol = lc($protocol);
@@ -2400,7 +2464,28 @@ sub get_reserved_chain_name {
#//////////////////////////////////////////////////////////////////////////////
-=head2 get_reservation_chain_name
+=head2 get_nat_host_chain_name
+
+ Parameters : none
+ Returns : string
+ Description : Returns the name of the iptables chain on the NAT host
containing
+ rules for NAT to function. Returns 'vcl-nat_host'.
+
+=cut
+
+sub get_nat_host_chain_name {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return 0;
+ }
+
+ return 'vcl-nat_host';
+}
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 get_nat_reservation_chain_name
Parameters : $reservation_id (optional)
Returns : string
@@ -2409,7 +2494,7 @@ sub get_reserved_chain_name {
=cut
-sub get_reservation_chain_name {
+sub get_nat_reservation_chain_name {
my $self = shift;
if (ref($self) !~ /VCL::Module/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
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=1796111&r1=1796110&r2=1796111&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Wed May 24 22:22:40
2017
@@ -851,7 +851,7 @@ sub post_load {
notify($ERRORS{'DEBUG'}, 0, "computer initially
failed to obtain a public IP address from DHCP, executed 'ipconfig /renew',
public IP address could then be determined");
}
}
- else {
+ else {
notify($ERRORS{'WARNING'}, 0, "management node failed
to set a static public IP address on the computer");
return;
}
@@ -863,7 +863,7 @@ sub post_load {
=cut
- if (!$self->set_public_default_route()) {
+ if (!$self->set_static_default_gateway()) {
notify($ERRORS{'WARNING'}, 0, "unable to set persistent public
default route");
}
@@ -8568,7 +8568,7 @@ EOF
notify($ERRORS{'OK'}, 0, "set static public IP address:
$computer_public_ip_address/$subnet_mask, default gateway: $default_gateway");
}
- $self->set_public_default_route() || return;
+ $self->set_static_default_gateway() || return;
$self->set_static_dns_servers() || return;
@@ -8747,42 +8747,27 @@ sub delete_default_routes {
#//////////////////////////////////////////////////////////////////////////////
-=head2 set_public_default_route
+=head2 set_static_default_gateway
- Parameters : None
- Returns : If successful: true
- If failed: false
+ Parameters : $default_gateway (optional)
+ Returns : boolean
Description : Adds a persistent route to the default gateway for the public
network.
=cut
-sub set_public_default_route {
+sub set_static_default_gateway {
my $self = shift;
unless (ref($self) && $self->isa('VCL::Module')) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called
as a VCL::Module module object method");
return;
}
- # Check the management node's DHCP IP configuration mode
- # Get the default gateway address
- my $default_gateway;
- my $ip_configuration =
$self->data->get_management_node_public_ip_configuration();
- if ($ip_configuration && $ip_configuration =~ /static/i) {
- # Static addresses used, get default gateway address configured
for management node
- $default_gateway =
$self->data->get_management_node_public_default_gateway();
- }
- else {
- # Dynamic addresses used, get default gateway address assigned
to computer
- $default_gateway = $self->get_public_default_gateway();
- if (!$default_gateway) {
- $default_gateway =
$self->data->get_management_node_public_default_gateway();
- }
- }
+ my $computer_name = $self->data->get_computer_short_name();
- # Make sure default gateway was retrieved
+ my $default_gateway = shift || $self->get_correct_default_gateway();
if (!$default_gateway) {
- notify($ERRORS{'WARNING'}, 0, "unable to retrieve default
gateway address");
+ notify($ERRORS{'WARNING'}, 0, "unable to set static default
gateway on $computer_name, argument was not supplied and correct default
gateway IP address could not be determined");
return;
}
@@ -8794,7 +8779,7 @@ sub set_public_default_route {
}
# Add a persistent route to the public default gateway
- my $route_add_command = "route -p ADD 0.0.0.0 MASK 0.0.0.0
$default_gateway METRIC 1";
+ my $route_add_command = "route -p ADD 0.0.0.0 MASK 0.0.0.0
$default_gateway METRIC 1";
my ($route_add_exit_status, $route_add_output) =
$self->execute($route_add_command);
if (!defined($route_add_output)) {
notify($ERRORS{'WARNING'}, 0, "failed to execute command to add
persistent route to public default gateway: $default_gateway");
Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1796111&r1=1796110&r2=1796111&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Wed May 24 22:22:40 2017
@@ -1228,7 +1228,7 @@ sub check_time {
}
else {
# End time is now or in the future
- notify($ERRORS{'DEBUG'}, 0, "reservation end time is
either right now or in the future ($end_diff_minutes), returning 0");
+ #notify($ERRORS{'DEBUG'}, 0, "reservation end time is
either right now or in the future ($end_diff_minutes), returning 0");
return "0";
}
} # Close if state is complete or failed