vcl-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fapee...@apache.org
Subject svn commit: r1201909 - in /incubator/vcl/trunk/managementnode/lib/VCL: Module/OS.pm Module/OS/Linux.pm Module/OS/Windows.pm inuse.pm reserved.pm
Date Mon, 14 Nov 2011 21:15:17 GMT
Author: fapeeler
Date: Mon Nov 14 21:15:16 2011
New Revision: 1201909

URL: http://svn.apache.org/viewvc?rev=1201909&view=rev
Log:
VCL-30

rework of the process connect methods routine
-- added support to Linux.pm for collect firewall configuration
-- added support for better manipulation of iptables if it exists


Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
    incubator/vcl/trunk/managementnode/lib/VCL/inuse.pm
    incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1201909&r1=1201908&r2=1201909&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Mon Nov 14 21:15:16 2011
@@ -2046,14 +2046,32 @@ sub process_connect_methods {
 	my $connect_method_info = get_connect_method_info($imagerevision_id);
 	if (!$connect_method_info) {
 		notify($ERRORS{'WARNING'}, 0, "no connect methods are configured for image revision $imagerevision_id");
+		return;
 	}
 	
-	my $remote_ip = $self->data->get_reservation_remote_ip();
+	my $remote_ip = shift;
 	if (!$remote_ip) {
-		notify($ERRORS{'WARNING'}, 0, "reservation remote IP address is not defined, connect methods
will be available from any IP address");
-		$remote_ip = '0.0.0.0/0.0.0.0';
+		notify($ERRORS{'OK'}, 0, "reservation remote IP address is not defined, connect methods
will be available from any IP address");
+		$remote_ip = '0.0.0.0/0';
+	}
+	elsif ($remote_ip =~ /any/i){
+		notify($ERRORS{'OK'}, 0, "reservation remote IP address is set to ANY, connect methods
will be available from any IP address");
+		$remote_ip = '0.0.0.0/0';
+	}
+	else {
+		$remote_ip .= "/24";
 	}
 	
+	my $overwrite = shift;
+	if (!$overwrite) {
+		notify($ERRORS{'DEBUG'}, 0, "overwrite value was not passed as an argument setting to 0");
+		$overwrite = 0;
+	}
+	
+	my $state = $self->data->get_request_state_name();
+	notify($ERRORS{'DEBUG'}, 0, "state = $state");
+	
+	
 	CONNECT_METHOD: for my $connect_method_id (sort keys %{$connect_method_info} ) {
 		notify($ERRORS{'DEBUG'}, 0, "processing connect method:\n" . format_data($connect_method_info->{$connect_method_id}));
 		
@@ -2065,10 +2083,33 @@ sub process_connect_methods {
 		my $startup_script  = $connect_method_info->{$connect_method_id}{startupscript};
 		my $install_script  = $connect_method_info->{$connect_method_id}{installscript};
 		my $disabled        = $connect_method_info->{$connect_method_id}{connectmethodmap}{disabled};
+
+		if( $state =~ /deleted|timeout/) {
+			$disabled = 1;
+		}
 		
 		if ($disabled) {
-			# TODO: Add code to disable the service, close the firewall port, etc
-			notify($ERRORS{'OK'}, 0, "skipping '$name' connect method configuration, it should be
disabled on $computer_node_name");
+			if ($self->service_exists($service_name)) {
+               notify($ERRORS{'DEBUG'}, 0, "attempting to stop '$service_name' service for
'$name' connect method on $computer_node_name");
+               if ($self->stop_service($service_name)) {
+                  notify($ERRORS{'OK'}, 0, "'$service_name' stop on $computer_node_name");
+               }
+               else {
+                  notify($ERRORS{'WARNING'}, 0, "failed to stop '$service_name' service for
'$name' connect method on $computer_node_name");
+               }
+         }
+			
+			#Disable firewall port
+			if (defined($port)) {
+            notify($ERRORS{'DEBUG'}, 0, "attempting to open firewall port $port on $computer_node_name
for '$name' connect method");
+            if ($self->disable_firewall_port($protocol, $port, $remote_ip, 1)) {
+               notify($ERRORS{'OK'}, 0, "closing firewall port $port on $computer_node_name
for $remote_ip $name connect method");
+            }
+            else {
+               notify($ERRORS{'WARNING'}, 0, "failed to close firewall port $port on $computer_node_name
for $remote_ip $name connect method");
+            }
+         }
+			
 		}
 		else {
 			# Attempt to start and configure the connect method
@@ -2088,29 +2129,6 @@ sub process_connect_methods {
 						notify($ERRORS{'WARNING'}, 0, "failed to start '$service_name' service for '$name'
connect method on $computer_node_name");
 					}
 				}
-				#elsif ($install_script) {
-				#	notify($ERRORS{'DEBUG'}, 0, "'$service_name' service for '$name' connect method does
not exist on $computer_node_name, attempting to execute connect method install script");
-				#	my ($install_exit_status, $install_output) = $self->execute($install_script, 1,
600, 1);
-				#	if (!defined($install_output)) {
-				#		notify($ERRORS{'WARNING'}, 0, "failed to run command to execute install script for
'$name' connect method on $computer_node_name, command: '$install_script'");
-				#	}
-				#	else {
-				#		notify($ERRORS{'OK'}, 0, "executed install script for '$name' connect method on $computer_node_name,
command: '$install_script', exit status: $install_exit_status, output:\n" . join("\n", @$install_output));
-				#		
-				#		if ($self->service_exists($service_name)) {
-				#			if ($self->start_service($service_name)) {
-				#				notify($ERRORS{'OK'}, 0, "'$service_name' started on $computer_node_name");
-				#				$service_started = 1;
-				#			}
-				#			else {
-				#				notify($ERRORS{'WARNING'}, 0, "failed to start '$service_name' service after executing
install script for '$name' connect method on $computer_node_name");
-				#			}
-				#		}
-				#		else {
-				#			notify($ERRORS{'WARNING'}, 0, "'$service_name' service does NOT exist after executing
install script for '$name' connect method on $computer_node_name");
-				#		}
-				#	}
-				#}
 				else {
 					notify($ERRORS{'WARNING'}, 0, "'$service_name' service for '$name' connect method does
NOT exist on $computer_node_name, connect method install script is not defined");
 				}
@@ -2134,11 +2152,11 @@ sub process_connect_methods {
 			# Open the firewall port
 			if (defined($port)) {
 				notify($ERRORS{'DEBUG'}, 0, "attempting to open firewall port $port on $computer_node_name
for '$name' connect method");
-				if ($self->enable_firewall_port($protocol, $port, "$remote_ip/24", 1)) {
-					notify($ERRORS{'OK'}, 0, "opened firewall port $port on $computer_node_name for '$name'
connect method");
+				if ($self->enable_firewall_port($protocol, $port, $remote_ip, 1)) {
+					notify($ERRORS{'OK'}, 0, "opened firewall port $port on $computer_node_name for $remote_ip
$name connect method");
 				}
 				else {
-					notify($ERRORS{'WARNING'}, 0, "failed to open firewall port $port on $computer_node_name
for '$name' connect method");
+					notify($ERRORS{'WARNING'}, 0, "failed to open firewall port $port on $computer_node_name
for $remote_ip $name connect method");
 				}
 			}
 		}

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1201909&r1=1201908&r2=1201909&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Mon Nov 14 21:15:16 2011
@@ -54,6 +54,7 @@ use diagnostics;
 no warnings 'redefine';
 
 use VCL::utils;
+use Net::Netmask;
 
 ##############################################################################
 
@@ -112,6 +113,7 @@ sub pre_capture {
 	
 	my $computer_node_name       = $self->data->get_computer_node_name();
 	notify($ERRORS{'OK'}, 0, "beginning Linux-specific image capture preparation tasks");
+	
 
 	if (!$self->file_exists("/root/.vclcontrol/vcl_exclude_list.sample")) {
       notify($ERRORS{'DEBUG'}, 0, "/root/.vclcontrol/vcl_exclude_list.sample does not exists");
@@ -131,9 +133,13 @@ sub pre_capture {
 	}
 
 	#Clean up connection methods
-	if($self->process_connect_methods() ){
+	if($self->process_connect_methods("any", 1) ){
 		notify($ERRORS{'OK'}, 0, "processed connection methods on $computer_node_name");
 	}
+	
+	if(!$self->clean_iptables()) {
+		return 0;
+	}
 
 	# Try to clear /tmp
 	if ($self->execute("/usr/sbin/tmpwatch -f 0 /tmp; /bin/cp /dev/null /var/log/wtmp"))
{
@@ -233,6 +239,8 @@ sub post_load {
 	my $computer_short_name   = $self->data->get_computer_short_name();
 	my $computer_node_name    = $self->data->get_computer_node_name();
 	my $image_os_install_type = $self->data->get_image_os_install_type();
+	my $management_node_ip	  = $self->data->get_management_node_ipaddress();
+	my $mn_private_ip 		  = $self->mn_os->get_private_ip_address();
 	
 	notify($ERRORS{'OK'}, 0, "initiating Linux post_load: $image_name on $computer_short_name");
 
@@ -303,6 +311,10 @@ sub post_load {
 		notify($ERRORS{'DEBUG'}, 0, "ran $script_path");
 	}
 	
+	if($self->enable_firewall_port("tcp", "any", $mn_private_ip, 1) ){
+      notify($ERRORS{'OK'}, 0, "added MN_Priv_IP $mn_private_ip to firewall on $computer_short_name");
+   }
+	
 	# Attempt to generate ifcfg-eth* files and ifup any interfaces which the file does not exist
 	$self->activate_interfaces();
 	
@@ -960,8 +972,8 @@ sub grant_access {
 	}    #foreach
 	notify($ERRORS{'OK'}, 0, "started ext_sshd on $computer_node_name");
 
-	if($self->process_connect_methods('start') ){
-		notify($ERRORS{'OK'}, 0, "processed connection methods on $computer_node_name");
+	if($self->process_connect_methods("", 1) ){
+		notify($ERRORS{'OK'}, 0, "processed connection methods on $computer_node_name setting 0.0.0.0
for all allowed ports");
 	}
 
 	
@@ -1024,6 +1036,7 @@ sub sanitize {
 	}
 
 	my $computer_node_name = $self->data->get_computer_node_name();
+	my $mn_private_ip         = $self->mn_os->get_private_ip_address();
 
 	# Make sure user is not connected
 	if ($self->is_connected()) {
@@ -1040,7 +1053,7 @@ sub sanitize {
 	}
 	
 	#Clean up connection methods
-   if($self->process_connect_methods() ){
+   if($self->process_connect_methods($mn_private_ip, 1) ){
       notify($ERRORS{'OK'}, 0, "processed connection methods on $computer_node_name");
    }
 
@@ -3038,10 +3051,14 @@ sub service_exists {
 		notify($ERRORS{'DEBUG'}, 0, "'$service_name' service does not exist on $computer_node_name");
 		return 0;
 	}
-	elsif ($exit_status == 0 || grep(/not referenced in any runlevel/i, @$output)) {
+	elsif (defined($exit_status) && $exit_status == 0 ) {
+		notify($ERRORS{'DEBUG'}, 0, "'$service_name' service exists");
+		return 1;
+	}
+	elsif (defined($exit_status) && grep(/not referenced in any runlevel/i, @$output))
{
 		# chkconfig may display the following if the service exists but has not been added:
 		# service ext_sshd supports chkconfig, but is not referenced in any runlevel (run 'chkconfig
--add ext_sshd')
-		notify($ERRORS{'DEBUG'}, 0, "'$service_name' service exists but is not referenced in any
runlevel");
+		notify($ERRORS{'DEBUG'}, 0, "'$service_name' service exists but is not referenced in any
runlevel: output:\n" . join("\n", @$output));
 	}
 	else {
 		notify($ERRORS{'WARNING'}, 0, "unable to determine if '$service_name' service exists, exit
status: $exit_status, output:\n" . join("\n", @$output));
@@ -3349,6 +3366,45 @@ sub get_total_memory {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 sanitize_firewall
+ 
+  Parameters  : $scope (optional), 
+  Returns     : boolean
+  Description : Removes all entries for INUPT chain and Sets iptables firewall for private
management node IP
+ 
+=cut
+
+sub sanitize_firewall {
+   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;
+   }
+
+	my $scope = shift;
+	if(!defined($scope)) {
+		notify($ERRORS{'CRITICAL'}, 0, "scope variable was not passed in as an arguement");
+      return;
+	}
+	
+	my $computer_node_name = $self->data->get_computer_node_name();
+   my $mn_private_ip = $self->mn_os->get_private_ip_address();
+	
+	my $firewall_configuration = $self->get_firewall_configuration() || return;
+   my $chain;
+   my $iptables_del_cmd;
+	my $INPUT_CHAIN = "INPUT";
+
+   for my $num (sort keys %{$firewall_configuration->{$INPUT_CHAIN}} ) {
+
+	
+	}
+
+
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 enable_firewall_port
  
   Parameters  : $protocol, $port, $scope (optional), $overwrite_existing (optional), $name
(optional), $description (optional)
@@ -3364,6 +3420,13 @@ sub enable_firewall_port {
       return;
    }
 	
+	# Check to see if this distro has iptables
+	# If not return 1 so it does not fail
+	if (!($self->service_exists("iptables"))) {
+		notify($ERRORS{'WARNING'}, 0, "iptables does not exist on this OS");	
+		return 1;
+	}
+	
 	my ($protocol, $port, $scope_argument, $overwrite_existing, $name, $description) = @_;
 	if (!defined($protocol) || !defined($port)) {
 		notify($ERRORS{'WARNING'}, 0, "protocol and port arguments were not supplied");
@@ -3371,12 +3434,114 @@ sub enable_firewall_port {
 	}
 	
    my $computer_node_name = $self->data->get_computer_node_name();
+	my $mn_private_ip = $self->mn_os->get_private_ip_address();
 	
 	$protocol = lc($protocol);
 	
-	my $command = "/sbin/iptables -I INPUT 1 -m state --state NEW,RELATED,ESTABLISHED -m $protocol
-p $protocol --dport $port -j ACCEPT";
+	$scope_argument = '' if (!defined($scope_argument));
+
+   $name = '' if !$name;
+   $description = '' if !$description;
+
+   my $scope;
+
+	my $INPUT_CHAIN = "INPUT";
+
+	
+	my $firewall_configuration = $self->get_firewall_configuration() || return;
+	my $chain;
+	my $iptables_del_cmd;
+
+	for my $num (sort keys %{$firewall_configuration->{$INPUT_CHAIN}} ) {
+   	my $existing_scope = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{scope}
|| '';
+   	my $existing_name = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{name}
|| '';
+   	my $existing_description = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{name}
|| '';
+	
+   	if ($existing_scope) {
+			notify($ERRORS{'DEBUG'}, 0, " num= $num protocol= $protocol port= $port existing_scope=
$existing_scope existing_name= $existing_name existing_description= $existing_description
");
+
+			if ($overwrite_existing) {
+         	$scope = $self->parse_firewall_scope($scope_argument);
+				$iptables_del_cmd = "iptables -D $INPUT_CHAIN $num";
+         	if (!$scope) {
+            	notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument: '$scope_argument'");
+            	return;
+         	}
+
+         	notify($ERRORS{'DEBUG'}, 0, "existing firewall opening on $computer_node_name will
be replaced:\n" .
+            "name: '$existing_name'\n" .
+				"num: '$num'\n" .
+            "protocol: $protocol\n" .
+				"port/type: $port\n" .
+            "existing scope: '$existing_scope'\n" .
+            "new scope: $scope\n" .
+            "overwrite existing rule: " . ($overwrite_existing ? 'yes' : 'no')
+         	);
+      	}
+			else {
+         	my $parsed_existing_scope = $self->parse_firewall_scope($existing_scope);
+         	if (!$parsed_existing_scope) {
+            	notify($ERRORS{'WARNING'}, 0, "failed to parse existing firewall scope: '$existing_scope'");
+           	 return;
+         	}
+
+         	$scope = $self->parse_firewall_scope("$scope_argument,$existing_scope");
+         	if (!$scope) {
+            	notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument appended
with existing scope: '$scope_argument,$existing_scope'");
+            	return;
+         	}
+
+         	if ($scope eq $parsed_existing_scope) {
+            	notify($ERRORS{'DEBUG'}, 0, "firewall is already open on $computer_node_name,
existing scope matches scope argument:\n" .
+               "name: '$existing_name'\n" .
+               "protocol: $protocol\n" .
+               "port/type: $port\n" .
+               "scope: $scope\n" .
+               "overwrite existing rule: " . ($overwrite_existing ? 'yes' : 'no')
+            	);
+            	return 1;
+         	}
+      	}
+		}
+		else {
+			next;
+   	}
+	}
+
+     	if(!$scope) {
+			$scope = $self->parse_firewall_scope($scope_argument);
+     		if (!$scope) {
+        		notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument: '$scope_argument'");
+        		return;
+     		}
+		}
+
+  
+   	$name = "VCL: allow $protocol/$port from $scope" if !$name;
+
+   	$name = substr($name, 0, 60) . "..." if length($name) > 60;
+
+		my $command;
+
+		if ($iptables_del_cmd ){
+			$command = "$iptables_del_cmd ; ";
+		
+		}
+
+		$command .= "/sbin/iptables -I INPUT 1 -m state --state NEW,RELATED,ESTABLISHED -m $protocol
-p $protocol -j ACCEPT";
+	
+		if ($port =~ /\d+/){
+			$command .= " --dport $port";
+		}
+
+		if ($scope_argument) {
+		#	if($scope_argument eq '0.0.0.0') {
+		#		$scope_argument .= "/0";
+		#	}
+		#	else {
+		#		$scope_argument .= "/24";	
+		#	}	
 	
-	if ($scope_argument) {
 		$command .= " -s $scope_argument";
 	}
 
@@ -3426,36 +3591,61 @@ sub disable_firewall_port {
       return;
    }
 
-   my $port = shift;
-   if(!$port) {
-      notify($ERRORS{'CRITICAL'}, 0, "Input variable port was not passed in as an argument");
-      return 0;
+	# Check to see if this distro has iptables
+   # If not return 1 so it does not fail
+   if (!($self->service_exists("iptables"))) {
+      notify($ERRORS{'WARNING'}, 0, "iptables does not exist on this OS");
+      return 1;
    }
+	
+	my ($protocol, $port, $scope_argument, $overwrite_existing, $name, $description) = @_;
+	if (!defined($protocol) || !defined($port)) {
+     notify($ERRORS{'WARNING'}, 0, "protocol and port arguments were not supplied");
+     return;
+	}
 
    my $computer_node_name = $self->data->get_computer_node_name();
-   my $remote_ip = $self->data->get_reservation_remote_ip();
+	my $mn_private_ip = $self->mn_os->get_private_ip_address();
 
-	my $command = "sed -i -e '/.*-p tcp --dport $port -j ACCEPT$/d' /etc/sysconfig/iptables";
-	my ($status, $output) = $self->execute($command);
+   $protocol = lc($protocol);
 
-	if (defined $status && $status == 0) {
-      notify($ERRORS{'DEBUG'}, 0, "executed command $command on $computer_node_name");
-   }
-   else {
-      notify($ERRORS{'WARNING'}, 0, "output from iptables:" . join("\n", @$output));
-   }
-	
-	#restart iptables
-	$command = "/etc/init.d/iptables restart";
-	my ($status_iptables,$output_iptables) = $self->execute($command);
-	if (defined $status_iptables && $status_iptables == 0) {
-      notify($ERRORS{'DEBUG'}, 0, "executed command $command on $computer_node_name");
-	}
-	else {
-      notify($ERRORS{'WARNING'}, 0, "output from iptables:" . join("\n", @$output_iptables));
-	}
+   $scope_argument = '' if (!defined($scope_argument));
 
-	return 1;
+   $name = '' if !$name;
+   $description = '' if !$description;
+
+   my $scope;
+
+   my $INPUT_CHAIN = "INPUT";
+
+   my $firewall_configuration = $self->get_firewall_configuration() || return;
+   my $chain;
+   my $command;
+
+   for my $num (sort keys %{$firewall_configuration->{$INPUT_CHAIN}} ) {
+		my $existing_scope = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{scope}
|| '';
+		my $existing_name = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{name}
|| '';
+		if($existing_scope) {
+			$command = "iptables -D $INPUT_CHAIN $num";
+
+			notify($ERRORS{'DEBUG'}, 0, "attempting to execute command on $computer_node_name: '$command'");
+   		my ($status, $output) = $self->execute($command);
+   		if (defined $status && $status == 0) {
+       		notify($ERRORS{'DEBUG'}, 0, "executed command on $computer_node_name: '$command'");
+   		}
+   		else {
+       		notify($ERRORS{'WARNING'}, 0, "output from iptables:\n" . join("\n", @$output));
+   		}
+
+   		# Save rules to sysconfig/iptables -- incase of reboot
+   		my $iptables_save_cmd = "/sbin/iptables-save > /etc/sysconfig/iptables";
+   		my ($status_save, $output_save) = $self->execute($iptables_save_cmd);
+   		if (defined $status_save && $status_save == 0) {
+       		notify($ERRORS{'DEBUG'}, 0, "executed command $iptables_save_cmd on $computer_node_name");
+   		}
+		}
+	}
+   return 1;
 
 }
 
@@ -3557,9 +3747,486 @@ sub generate_vclcontrol_sample_files {
 	return 1;	
 
 }
-##/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_firewall_configuration
+
+ Parameters  : none
+ Returns     : hash reference
+ Description : Retrieves information about the open firewall ports on the
+               computer and constructs a hash. The hash keys are protocol names.
+               Each protocol key contains a hash reference. The keys are either
+               port numbers or ICMP types.
+               Example:
+               
+                  "ICMP" => {
+                    8 => {
+                      "description" => "Allow inbound echo request"
+                    }
+                  },
+                  "TCP" => {
+                    22 => {
+                      "interface_names" => [
+                        "Local Area Connection 3"
+                      ],
+                      "name" => "sshd"
+                    },
+                    3389 => {
+                      "name" => "Remote Desktop",
+                      "scope" => "192.168.53.54/255.255.255.255"
+                    },
+
+=cut
+
+sub get_firewall_configuration {
+   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;
+   }
+
+	my $computer_node_name = $self->data->get_computer_node_name();	
+	my $firewall_configuration = {};
+
+	# Check to see if this distro has iptables
+   # If not return 1 so it does not fail
+   if (!($self->service_exists("iptables"))) {
+      notify($ERRORS{'WARNING'}, 0, "iptables does not exist on this OS");
+      return 1;
+   }
+	
+	my $port_command = "iptables -L --line-number -n";
+	my ($iptables_exit_status, $output_iptables) = $self->execute($port_command);
+   if (!defined($output_iptables)) {
+      notify($ERRORS{'WARNING'}, 0, "failed to run command to show open firewall ports on
$computer_node_name");
+      return;
+   }
+
+	#notify($ERRORS{'DEBUG'}, 0, "output from iptables:\n" . join("\n", @$output_iptables));
+	
+
+	# Execute the iptables -L --line-number -n command to retrieve firewall port openings
+   # Expected output:
+	#Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
+	#num  target     prot opt source               destination         
+	#1    RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0           
+
+	#Chain FORWARD (policy ACCEPT)
+	#num  target     prot opt source               destination         
+	#1    RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0           
+
+	#Chain OUTPUT (policy ACCEPT)
+	#num  target     prot opt source               destination         
+
+	#Chain RH-Firewall-1-INPUT (2 references)
+	#num  target     prot opt source               destination         
+	#1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
+	#2    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
+	#3    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 255 
+	#4    ACCEPT     esp  --  0.0.0.0/0            0.0.0.0/0           
+	#5    ACCEPT     ah   --  0.0.0.0/0            0.0.0.0/0           
+	#6    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED

+	#7    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22

+	#8    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:3389

+	#9    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited
+
+
+   my $chain;
+   my $previous_protocol;
+   my $previous_port;
+
+	for my $line (@$output_iptables) {
+		if ($line =~ /^Chain\s+(\S+)\s+(.*)/ig) {
+         $chain = $1;
+			notify($ERRORS{'DEBUG'}, 0, "output Chain = $chain");
+      }
+		elsif($line =~ /^(\d+)\s+([A-Z]*)\s+([a-z]*)\s+(--)\s+(\S+)\s+(\S+)\s+(.*)/ig ) {
+		
+			my $num = $1;
+			my $target = $2;
+			my $protocol = $3;
+			my $scope = $5;
+			my $destination =$6;
+			my $port_string = $7 if (defined($7));
+			my $port = ''; 
+			my $name;
+		
+		
+			if (defined($port_string) && ($port_string =~ /([\s(a-zA-Z)]*)(dpt:)(\d+)/ig )){
+				$port = $3;	
+				notify($ERRORS{'DEBUG'}, 0, "output rule: $num, $target, $protocol, $scope, $destination,
$port ");
+			}
+
+			if (!$port) {
+				$port = "any";
+			}
+			
+			my $services_cmd = "cat /etc/services";
+			my ($services_status, $service_output) = $self->execute($services_cmd);
+			if (!defined($service_output)) {
+      		notify($ERRORS{'DEBUG'}, 0, "failed to get /etc/services");
+   		}
+   		else {
+				for my $sline (@$service_output) {
+					if ( $sline =~ /(^[_-a-zA-Z1-9]+)\s+($port\/$protocol)\s+(.*) /ig ){
+						$name = $1;
+					} 
+				}
+				
+			}		
+			
+			$name = $port if (!$name);
+
+			$firewall_configuration->{$chain}->{$num}{$protocol}{$port}{name}= $name;
+			$firewall_configuration->{$chain}->{$num}{$protocol}{$port}{number}= $num;
+			$firewall_configuration->{$chain}->{$num}{$protocol}{$port}{scope}= $scope;
+			$firewall_configuration->{$chain}->{$num}{$protocol}{$port}{target}= $target;
+			$firewall_configuration->{$chain}->{$num}{$protocol}{$port}{destination}= $destination;
+			
+
+			if (!defined($previous_protocol) ||
+             !defined($previous_port) ||
+             !defined($firewall_configuration->{$previous_protocol}) ||
+             !defined($firewall_configuration->{$previous_protocol}{$previous_port})
+             ) {
+         	next;
+      	}
+			elsif ($scope !~ /0.0.0.0\/0/) {
+				$firewall_configuration->{$previous_protocol}{$previous_port}{scope} = $scope;
+			}
+		}
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "retrieved firewall configuration from $computer_node_name:\n"
. format_data($firewall_configuration));
+   return $firewall_configuration;
+	
+	
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 parse_firewall_scope
+
+ Parameters  : @scope_strings
+ Returns     : string
+ Description : Parses an array of firewall scope strings and collpases them into
+               a simplified scope if possible. A comma-separated string is
+               returned. The scope string argument may be in the form:
+                  -192.168.53.54/255.255.255.192
+                  -192.168.53.54/24
+                  -192.168.53.54
+                  -*
+                  -Any
+                  -LocalSubnet
+
+=cut
+
+sub parse_firewall_scope {
+   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;
+   }
+
+   my @scope_strings = @_;
+   if (!@scope_strings) {
+      notify($ERRORS{'WARNING'}, 0, "scope array argument was not supplied");
+      return;
+   }
+
+   my @netmask_objects;
+
+   for my $scope_string (@scope_strings) {
+      if ($scope_string =~ /(\*|Any)/i) {
+         my $netmask_object = new Net::Netmask('any');
+         push @netmask_objects, $netmask_object;
+      }
+
+      elsif ($scope_string =~ /LocalSubnet/i) {
+         my $network_configuration = $self->get_network_configuration() || return;
+
+         for my $interface_name (sort keys %$network_configuration) {
+            for my $ip_address (keys %{$network_configuration->{$interface_name}{ip_address}})
{
+               my $subnet_mask = $network_configuration->{$interface_name}{ip_address}{$ip_address};
+
+               my $netmask_object_1 = new Net::Netmask("$ip_address/$subnet_mask");
+               if ($netmask_object_1) {
+                  push @netmask_objects, $netmask_object_1;
+               }
+               else {
+                  notify($ERRORS{'WARNING'}, 0, "failed to create Net::Netmask object, IP
address: $ip_address, subnet mask: $subnet_mask");
+                  return;
+               }
+            }
+         }
+      }
+
+      elsif (my @scope_sections = split(/,/, $scope_string)) {
+         for my $scope_section (@scope_sections) {
+
+            if (my ($start_address, $end_address) = $scope_section =~ /^([\d\.]+)-([\d\.]+)$/)
{
+               my @netmask_range_objects = Net::Netmask::range2cidrlist($start_address, $end_address);
+               if (@netmask_range_objects) {
+                  push @netmask_objects, @netmask_range_objects;
+               }
+               else {
+                  notify($ERRORS{'WARNING'}, 0, "failed to call Net::Netmask::range2cidrlist
to create an array of objects covering IP range: $start_address-$end_address");
+                  return;
+               }
+            }
+
+            elsif (my ($ip_address, $subnet_mask) = $scope_section =~ /^([\d\.]+)\/([\d\.]+)$/)
{
+               my $netmask_object = new Net::Netmask("$ip_address/$subnet_mask");
+               if ($netmask_object) {
+                  push @netmask_objects, $netmask_object;
+               }
+               else {
+                  notify($ERRORS{'WARNING'}, 0, "failed to create Net::Netmask object, IP
address: $ip_address, subnet mask: $subnet_mask");
+                  return;
+               }
+            }
+
+            elsif (($ip_address) = $scope_section =~ /^([\d\.]+)$/) {
+               my $netmask_object = new Net::Netmask("$ip_address");
+               if ($netmask_object) {
+                  push @netmask_objects, $netmask_object;
+               }
+               else {
+                  notify($ERRORS{'WARNING'}, 0, "failed to create Net::Netmask object, IP
address: $ip_address");
+                  return;
+               }
+            }
+
+            else {
+               notify($ERRORS{'WARNING'}, 0, "unable to parse '$scope_section' section of
scope: '$scope_string'");
+               return;
+            }
+         }
+      }
+
+      else {
+         notify($ERRORS{'WARNING'}, 0, "unexpected scope format: '$scope_string'");
+         return
+      }
+   }
+
+   my @netmask_objects_collapsed = cidrs2cidrs(@netmask_objects);
+   if (@netmask_objects_collapsed) {
+      my $scope_result_string;
+      my @ip_address_ranges;
+      for my $netmask_object (@netmask_objects_collapsed) {
+
+         if ($netmask_object->first() eq $netmask_object->last()) {
+            push @ip_address_ranges, $netmask_object->first();
+            $scope_result_string .= $netmask_object->base() . ",";
+         }
+         else {
+            push @ip_address_ranges, $netmask_object->first() . "-" . $netmask_object->last();
+            $scope_result_string .= $netmask_object->base() . "/" . $netmask_object->mask()
. ",";
+         }
+      }
+
+      $scope_result_string =~ s/,+$//;
+      my $argument_string = join(",", @scope_strings);
+      if ($argument_string ne $scope_result_string) {
+         notify($ERRORS{'DEBUG'}, 0, "parsed firewall scope:\n" .
+            "argument: '$argument_string'\n" .
+            "result: '$scope_result_string'\n" .
+            "IP address ranges:\n" . join(", ", @ip_address_ranges)
+         );
+      }
+      return $scope_result_string;
+   }
+   else {
+      notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope: '" . join(",", @scope_strings)
. "', no Net::Netmask objects were created");
+      return;
+   }
+}
+
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_compare_update
+
+ Parameters  : @scope_strings
+ Returns     : 0 , 1
+ Description : Compare iptables for listed remote IP address in reservation
+
+=cut
+
+sub firewall_compare_update  {
+	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;
+   }
+	
+	# Check to see if this distro has iptables
+   # If not return 1 so it does not fail
+   if (!($self->service_exists("iptables"))) {
+      notify($ERRORS{'WARNING'}, 0, "iptables does not exist on this OS");
+      return 1;
+   }
+	
+	my $computer_node_name = $self->data->get_computer_node_name();
+   my $imagerevision_id   = $self->data->get_imagerevision_id();
+	my $remote_ip 			  = $self->data->get_reservation_remote_ip();
+	
+	#collect connection_methods
+	#collect firewall_config
+	#For each port defined in connection_methods
+	#compare rule source address with remote_IP address
+	
+   # Retrieve the connect method info hash
+   my $connect_method_info = get_connect_method_info($imagerevision_id);
+   if (!$connect_method_info) {
+      notify($ERRORS{'WARNING'}, 0, "no connect methods are configured for image revision
$imagerevision_id");
+      return;
+   }
+
+	# Retrieve the firewall configuration
+   my $INPUT_CHAIN = "INPUT";
+   my $firewall_configuration = $self->get_firewall_configuration() || return;	
+		
+	for my $connect_method_id (sort keys %{$connect_method_info} ) {
+             
+      my $name            = $connect_method_info->{$connect_method_id}{name};
+      my $description     = $connect_method_info->{$connect_method_id}{description};
+      my $protocol        = $connect_method_info->{$connect_method_id}{protocol} || 'TCP';
+      my $port            = $connect_method_info->{$connect_method_id}{port};
+		my $scope;
+	
+		$protocol = lc($protocol);
+		
+		for my $num (sort keys %{$firewall_configuration->{$INPUT_CHAIN}} ) {
+			my $existing_scope = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{scope}
|| '';
+			if(!$existing_scope ) {
 
+			}
+			else {
+				my $parsed_existing_scope = $self->parse_firewall_scope($existing_scope);
+				if (!$parsed_existing_scope) {
+                notify($ERRORS{'WARNING'}, 0, "failed to parse existing firewall scope: '$existing_scope'");
+                return;
+            }	
+				$scope = $self->parse_firewall_scope("$remote_ip,$existing_scope");
+            if (!$scope) {
+                notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument appended
with existing scope: '$remote_ip,$existing_scope'");
+                return;
+            }
+			
+				if ($scope eq $parsed_existing_scope) {
+                notify($ERRORS{'DEBUG'}, 0, "firewall is already open on $computer_node_name,
existing scope matches scope argument:\n" .
+               "name: '$name'\n" .
+               "protocol: $protocol\n" .
+               "port/type: $port\n" .
+               "scope: $scope\n");
+                return 1;
+            }
+				else {
+					if ($self->enable_firewall_port($protocol, $port, "$remote_ip/24", 0)) {
+                   notify($ERRORS{'OK'}, 0, "opened firewall port $port on $computer_node_name
for $remote_ip $name connect method");
+               }
+				}
+				
+
+			}			
+		}
+	}
+
+	return 1;	
+
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 clean_iptables
+
+ Parameters  : 
+ Returns     : 0 , 1
+ Description : Deletes rules with any leftover -s addresses 
+
+=cut
+
+sub clean_iptables {
+	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;
+   }
+	
+	# Check to see if this distro has iptables
+   # If not return 1 so it does not fail
+   if (!($self->service_exists("iptables"))) {
+      notify($ERRORS{'WARNING'}, 0, "iptables does not exist on this OS");
+      return 1;
+   }
+	
+	my $computer_node_name = $self->data->get_computer_node_name();
+	my $reservation_id                  = $self->data->get_reservation_id();
+	my $management_node_keys  = $self->data->get_management_node_keys();
+
+   # Retrieve the firewall configuration
+   my $INPUT_CHAIN = "INPUT";
+	
+	# Retrieve the iptables file to work on locally	
+	my $tmpfile = "/tmp/" . $reservation_id . "_iptables";
+	my $source_file_path = "/etc/sysconfig/iptables";
+	if (run_scp_command("$computer_node_name:\"$source_file_path\"", $tmpfile, $management_node_keys))
{
+		my @lines;
+		if(open(IPTAB_TMPFILE, $tmpfile)){
+			@lines = <IPTAB_TMPFILE>;
+			close(IPTAB_TMPFILE);	
+		}
+		foreach my $line (@lines){
+			if ($line =~ s/-A INPUT -s .*\n//) {
+         }
+		}
+	
+		#Rewrite array to tmpfile
+		if(open(IPTAB_TMPFILE, ">$tmpfile")){
+			print IPTAB_TMPFILE @lines;
+			close (IPTAB_TMPFILE);
+		}
+	
+		# Copy iptables file back to node
+		if (run_scp_command($tmpfile, "$computer_node_name:\"$source_file_path\"", $management_node_keys))
{
+			notify($ERRORS{'DEBUG'}, 0, "copied $tmpfile to $computer_node_name $source_file_path");
+		}
+	}	
+	
+
+	#my $command = "sed -i -e '/-A INPUT -s */d' /etc/sysconfig/iptables";
+   #my ($status, $output) = $self->execute($command);	
+	
+	#if (defined $status && $status == 0) {
+   #   notify($ERRORS{'DEBUG'}, 0, "executed command $command on $computer_node_name");
+   #}
+   #else {
+   #   notify($ERRORS{'WARNING'}, 0, "output from iptables:" . join("\n", @$output));
+   #}
+        
+	#restart iptables
+   my $command = "/etc/init.d/iptables restart";
+   my ($status_iptables,$output_iptables) = $self->execute($command);
+   if (defined $status_iptables && $status_iptables == 0) {
+		notify($ERRORS{'DEBUG'}, 0, "executed command $command on $computer_node_name");
+   }
+   else {
+      notify($ERRORS{'WARNING'}, 0, "output from iptables:" . join("\n", @$output_iptables));
+   }
+	
+	if ($self->wait_for_ssh(0)) {
+   	return 1;
+	}
+	else { 
+		notify($ERRORS{'CRITICAL'}, 0, "not able to login via ssh after cleaning_iptables");
+		return 0;
+	}
+
+}
+
+
+##/////////////////////////////////////////////////////////////////////////////
 1;
 __END__
 

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1201909&r1=1201908&r2=1201909&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Mon Nov 14 21:15:16 2011
@@ -947,7 +947,7 @@ sub grant_access {
 	# Set the $remote_ip_range variable to the string 'all' if it isn't already set (for display
purposes)
 	$remote_ip_range = 'all' if !$remote_ip_range;
 	
-	if($self->process_connect_methods('start') ){
+	if($self->process_connect_methods("0.0.0.0", 1) ){
 		notify($ERRORS{'OK'}, 0, "processed connection methods on $computer_node_name");
 	}
 

Modified: incubator/vcl/trunk/managementnode/lib/VCL/inuse.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/inuse.pm?rev=1201909&r1=1201908&r2=1201909&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/inuse.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/inuse.pm Mon Nov 14 21:15:16 2011
@@ -187,6 +187,12 @@ sub process {
 	# Is this a poll or end time
 	if ($request_checktime eq "poll") {
 		notify($ERRORS{'OK'}, 0, "beginning to poll");
+
+		if ($self->os->can('firewall_compare_update')) {
+         if ($self->os->firewall_compare_update()) {
+				notify($ERRORS{'OK'}, 0, "confirmed firewall scope has been updated");
+			}
+		}	
 		
 		if ($image_os_type =~ /windows/) {
 			if (firewall_compare_update($computer_nodename, $reservation_remoteip, $identity_key,
$image_os_type)) {

Modified: incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm?rev=1201909&r1=1201908&r2=1201909&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm Mon Nov 14 21:15:16 2011
@@ -336,6 +336,10 @@ sub process {
 		notify($ERRORS{'OK'}, 0, "$remote_ip connected to $nodename");
 
 		insertloadlog($reservation_id, $computer_id, "connected", "reserved: user connected to
remote machine");
+		
+		if($self->os->process_connect_methods($remote_ip, 1)) {
+			notify($ERRORS{'OK'}, 0, "process_connect_methods return successfully  $remote_ip $nodename");
+		}
 
 		# Update the request state to either inuse or imageinuse
 		if (update_request_state($request_id, "inuse", "reserved")) {
@@ -368,6 +372,10 @@ sub process {
 	elsif ($retval_conn eq "conn_wrong_ip") {
 		# does the same as above, until we make a firm decision as to how to handle this
 
+		if($self->os->process_connect_methods($remote_ip, 1)) {
+         notify($ERRORS{'OK'}, 0, "process_connect_methods return successfully  $remote_ip
$nodename");
+      }
+
 		# Update the request state to inuse
 		if (update_request_state($request_id, "inuse", "reserved")) {
 			notify($ERRORS{'OK'}, 0, "setting request into inuse state");
@@ -391,6 +399,7 @@ sub process {
 		else {
 			notify($ERRORS{'CRITICAL'}, 0, "unable to update lastcheck time for reservation $reservation_id");
 		}
+	
 
 		notify($ERRORS{'OK'}, 0, "exiting");
 		exit;



Mime
View raw message