You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2011/06/14 21:58:53 UTC

svn commit: r1135767 - in /incubator/vcl/trunk/managementnode/lib/VCL/Module: OS.pm OS/Linux.pm OS/Windows.pm

Author: arkurth
Date: Tue Jun 14 19:58:52 2011
New Revision: 1135767

URL: http://svn.apache.org/viewvc?rev=1135767&view=rev
Log:
VCL-465
Moved various get_* subroutines from Windows.pm and Linux.pm to OS.pm and updated the code so it can be used by all OS's.  Updated get_network_configuration in Windows.pm and Linux.pm so that returned hash reference format is identical.

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

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=1135767&r1=1135766&r2=1135767&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Tue Jun 14 19:58:52 2011
@@ -880,6 +880,8 @@ sub get_private_interface_name {
 		return;
 	}
 	
+	return $self->{private_interface_name} if defined $self->{private_interface_name};
+	
 	# Get the network configuration hash reference
 	my $network_configuration = $self->get_network_configuration();
 	if (!$network_configuration) {
@@ -905,12 +907,13 @@ sub get_private_interface_name {
 		
 		# Check if interface has the private IP address assigned to it
 		if (grep { $_ eq $computer_private_ip_address } @ip_addresses) {
-			notify($ERRORS{'DEBUG'}, 0, "determined private interface name: $interface_name (" . join (", ", @ip_addresses) . ")");
-			return $interface_name;
+			$self->{private_interface_name} = $interface_name;
+			notify($ERRORS{'DEBUG'}, 0, "determined private interface name: $self->{private_interface_name} (" . join (", ", @ip_addresses) . ")");
+			return $self->{private_interface_name};
 		}
 	}
 
-	notify($ERRORS{'WARNING'}, 0, "failed to determined private interface name, no interface is assigned the private IP address for the reservation: $computer_private_ip_address\n" . format_data($network_configuration));
+	notify($ERRORS{'WARNING'}, 0, "failed to determine private interface name, no interface is assigned the private IP address for the reservation: $computer_private_ip_address\n" . format_data($network_configuration));
 	return;
 }
 
@@ -933,6 +936,8 @@ sub get_public_interface_name {
 		return;
 	}
 	
+	return $self->{public_interface_name} if defined $self->{public_interface_name};
+	
 	# Get the network configuration hash reference
 	my $network_configuration = $self->get_network_configuration();
 	if (!$network_configuration) {
@@ -949,93 +954,563 @@ sub get_public_interface_name {
 	
 	my $public_interface_name;
 	
-	# Store the name of an interface found without any bound IP addresses
-	# This interface will be returned if no others are found with an IP address
-	my $addressless_interface_name;
-	
 	# Loop through all of the network interfaces found
-	INTERFACE_NAME: foreach my $interface_name (sort keys %$network_configuration) {
-		# Get the interface IP addresses and make sure an IP address was found
-		my @ip_addresses  = keys %{$network_configuration->{$interface_name}{ip_address}};
+	INTERFACE: for my $check_interface_name (sort keys %$network_configuration) {
 		
-		# Check if the interface does not have any bound IP addresses
-		# Store the interface name if another has not already been found
-		# This will be returned if no others are found with a bound IP address
-		# This may occur if the public interface is present but down
-		if (!@ip_addresses && !defined($addressless_interface_name)) {
-			if (!defined($addressless_interface_name)) {
-				notify($ERRORS{'DEBUG'}, 0, "found interface without a bound IP address: $interface_name, this name will be returned if no other valid interface is found with a bound IP address");
-				$addressless_interface_name = $interface_name;
-			}
-			else {
-				notify($ERRORS{'DEBUG'}, 0, "found another interface without a bound IP address: $interface_name, the first interface found without a bound IP address will be returned if no other valid interface is found with a bound IP address: $addressless_interface_name");
-			}
-			next INTERFACE_NAME;
+		my $description = $network_configuration->{$check_interface_name}{description} || '';
+		
+		# Check if the interface should be ignored based on the name or description
+		if ($check_interface_name =~ /(loopback|vmnet|afs|tunnel|6to4|isatap|teredo)/i) {
+			notify($ERRORS{'DEBUG'}, 0, "interface '$check_interface_name' ignored because its name contains '$1'");
+			next INTERFACE;
+		}
+		elsif ($description =~ /(loopback|virtual|afs|tunnel|pseudo|6to4|isatap)/i) {
+			notify($ERRORS{'DEBUG'}, 0, "interface '$check_interface_name' ignored because its description contains '$1'");
+			next INTERFACE;
 		}
 		
-		# Check if interface has private IP address assigned to it
-		if (grep { $_ eq $computer_private_ip_address } @ip_addresses) {
-			notify($ERRORS{'DEBUG'}, 0, "ignoring private interface: $interface_name (" . join (", ", @ip_addresses) . ")");
-			next;
+		# Get the IP addresses assigned to the interface
+		my @check_ip_addresses  = keys %{$network_configuration->{$check_interface_name}{ip_address}};
+		
+		# Ignore interface if it doesn't have an IP address
+		if (!@check_ip_addresses) {
+			notify($ERRORS{'DEBUG'}, 0, "interface '$check_interface_name' ignored because it is not assigned an IP address");
+			next INTERFACE;
 		}
 		
-		my $description = $network_configuration->{$interface_name}{description} || '';
+		# If $public_interface_name hasn't been set yet, set it and continue checking the next interface
+		if (!$public_interface_name) {
+			$public_interface_name = $check_interface_name;
+			next INTERFACE;
+		}
 		
-		# Check if the interface should be ignored based on the name or description
-		if ($interface_name =~ /(^lo|loopback|vmnet|afs|tunnel|6to4|isatap|teredo)/i) {
-			notify($ERRORS{'DEBUG'}, 0, "interface ignored because of name: $interface_name (" . join (", ", @ip_addresses) . ")");
-			next;
+		# Call the helper subroutine
+		# It uses recursion to avoid large/duplicated if-else blocks
+		$public_interface_name = $self->_get_public_interface_name_helper($check_interface_name, $public_interface_name);
+		if (!$public_interface_name) {
+			notify($ERRORS{'WARNING'}, 0, "failed to determine if '$check_interface_name' or '$public_interface_name' is more likely the public interface");
+			next INTERFACE;
+		}
+	}
+	
+	if ($public_interface_name) {
+		$self->{public_interface_name} = $public_interface_name;
+		notify($ERRORS{'OK'}, 0, "determined the public interface name: '$self->{public_interface_name}'\n" . format_data($network_configuration->{$self->{public_interface_name}}));
+		return $self->{public_interface_name};
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to determine the public interface name:\n" . format_data($network_configuration));
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_public_interface_name_helper
+
+ Parameters  : $interface_name_1, $interface_name_2
+ Returns     : string
+ Description : Compares the network configuration of the interfaces passed as
+               the arguments. Returns the name of the interface more likely to
+               be the public interface. It checks the following:
+               1. Is either interface assigned a public IP address?
+                  - If only 1 interface is assigned a public IP address then that interface name is returned.
+                  - If neither or both are assigned a public IP address:
+               2. Is either interface assigned a default gateway?
+                  - If only 1 interface is assigned a default gateway then that interface name is returned.
+                  - If neither or both are assigned a default gateway:
+               3. Is either interface assigned the private IP address?
+                  - If only 1 interface is assigned the private IP address, then the other interface name is returned.
+                  - If neither or both are assigned the private IP address, the first interface argument is returned
+
+=cut
+
+sub _get_public_interface_name_helper {
+	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;
+	}
+	
+print "\n\n" . '.' x 100 . "\n\n";
+	
+	my ($interface_name_1, $interface_name_2, $condition) = @_;
+	
+	if (!$interface_name_1 || !$interface_name_2) {
+		notify($ERRORS{'WARNING'}, 0, "\$network_configuration, \$interface_name_1, and \$interface_name_2 arguments were not specified");
+		return;
+	}
+	
+	my $network_configuration = $self->get_network_configuration();
+	my @ip_addresses_1 = keys %{$network_configuration->{$interface_name_1}{ip_address}};
+	my @ip_addresses_2 = keys %{$network_configuration->{$interface_name_2}{ip_address}};
+	
+	if (!$condition || $condition eq 'assigned_public') {
+		my $assigned_public_1 = (grep { is_public_ip_address($_) } @ip_addresses_1) ? 1 : 0;
+		my $assigned_public_2 = (grep { is_public_ip_address($_) } @ip_addresses_2) ? 1 : 0;
+		
+		if ($assigned_public_1 eq $assigned_public_2) {
+			notify($ERRORS{'DEBUG'}, 0, "tie: both interfaces are/are not assigned public IP addresses, proceeding to check default gateways");
+			return $self->_get_public_interface_name_helper($interface_name_1, $interface_name_2, 'assigned_gateway');
+		}
+		elsif ($assigned_public_1) {
+			notify($ERRORS{'DEBUG'}, 0, "'$interface_name_1' is more likely the public interface, it is assigned a public IP address, '$interface_name_2' is not");
+			return $interface_name_1;
+		}
+		else {
+			notify($ERRORS{'DEBUG'}, 0, "'$interface_name_2' is more likely the public interface, it is assigned a public IP address, '$interface_name_1' is not");
+			return $interface_name_2;
+		}
+	}
+	elsif ($condition eq 'assigned_gateway') {
+		my $assigned_default_gateway_1 = defined($network_configuration->{$interface_name_1}{default_gateway}) ? 1 : 0;
+		my $assigned_default_gateway_2 = defined($network_configuration->{$interface_name_2}{default_gateway}) ? 1 : 0;
+		
+		if ($assigned_default_gateway_1 eq $assigned_default_gateway_2) {
+			notify($ERRORS{'DEBUG'}, 0, "tie: both interfaces are/are not assigned a default gateway, proceeding to check if either is assigned the private IP address");
+			return $self->_get_public_interface_name_helper($interface_name_1, $interface_name_2, 'matches_private');
+		}
+		elsif ($assigned_default_gateway_1) {
+			notify($ERRORS{'DEBUG'}, 0, "'$interface_name_1' is more likely the public interface, it is assigned a default gateway, '$interface_name_2' is not");
+			return $interface_name_1;
+		}
+		else {
+			notify($ERRORS{'DEBUG'}, 0, "'$interface_name_2' is more likely the public interface, it is assigned a default gateway, '$interface_name_1' is not");
+			return $interface_name_2;
+		}
+	}
+	elsif ($condition eq 'matches_private') {
+		# Get the computer private IP address
+		my $computer_private_ip_address = $self->data->get_computer_private_ip_address();
+		if (!$computer_private_ip_address) {
+			notify($ERRORS{'DEBUG'}, 0, "unable to retrieve computer private IP address from reservation data");
+			return;
+		}
+		
+		my $matches_private_1 = (grep { $_ eq $computer_private_ip_address } @ip_addresses_1) ? 1 : 0;
+		my $matches_private_2 = (grep { $_ eq $computer_private_ip_address } @ip_addresses_2) ? 1 : 0;
+		
+		if ($matches_private_1 eq $matches_private_2) {
+			notify($ERRORS{'DEBUG'}, 0, "tie: both interfaces are/are not assigned the private IP address: $computer_private_ip_address, returning '$interface_name_1'");
+			return $interface_name_1;
 		}
-		elsif ($description =~ /loopback|virtual|afs|tunnel|pseudo|6to4|isatap/i) {
-			notify($ERRORS{'DEBUG'}, 0, "interface ignored because of description: $interface_name, description: $description (" . join (", ", @ip_addresses) . ")");
+		elsif ($matches_private_1) {
+			notify($ERRORS{'DEBUG'}, 0, "'$interface_name_2' is more likely the public interface, it is NOT assigned the private IP address: $computer_private_ip_address");
+			return $interface_name_2;
+		}
+		else {
+			notify($ERRORS{'DEBUG'}, 0, "'$interface_name_1' is more likely the public interface, it is NOT assigned the private IP address: $computer_private_ip_address");
+			return $interface_name_1;
+		}
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine which interface is more likely the public interface, invalid \$condition argument: '$condition'");
+		return;
+	}
+	
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_private_network_configuration
+
+ Parameters  : none
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_private_network_configuration {
+	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;
+	}
+	
+	return $self->get_network_configuration()->{$self->get_private_interface_name()};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_public_network_configuration
+
+ Parameters  : none
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_public_network_configuration {
+	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;
+	}
+	
+	return $self->get_network_configuration()->{$self->get_public_interface_name()};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_mac_address
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_mac_address {
+	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;
+	}
+	
+	# Check if a 'public' or 'private' network type argument was specified
+	# Assume 'public' if not specified
+	my $network_type = lc(shift()) || 'public';
+	if ($network_type && $network_type !~ /(public|private)/i) {
+		notify($ERRORS{'WARNING'}, 0, "network type argument can only be 'public' or 'private'");
+		return;
+	}
+
+	# Get the public or private network configuration
+	# Use 'eval' to construct the appropriate subroutine name
+	my $network_configuration = eval "\$self->get_$network_type\_network_configuration()";
+	if ($EVAL_ERROR || !$network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "unable to retrieve $network_type network configuration");
+		return;
+	}
+
+	my $mac_address = $network_configuration->{physical_address};
+	if ($mac_address) {
+		notify($ERRORS{'DEBUG'}, 0, "returning $network_type MAC address: $mac_address");
+		return $mac_address;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine $network_type MAC address, 'physical_address' key does not exist in the network configuration info: \n" . format_data($network_configuration));
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_private_mac_address
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_private_mac_address {
+	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;
+	}
+	
+	return $self->get_mac_address('private');
+}
+
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_public_mac_address
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_public_mac_address {
+	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;
+	}
+	
+	return $self->get_mac_address('public');
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_ip_address
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_ip_address {
+	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;
+	}
+	
+	# Check if a 'public' or 'private' network type argument was specified
+	# Assume 'public' if not specified
+	my $network_type = lc(shift()) || 'public';
+	if ($network_type && $network_type !~ /(public|private)/i) {
+		notify($ERRORS{'WARNING'}, 0, "network type argument can only be 'public' or 'private'");
+		return;
+	}
+
+	# Get the public or private network configuration
+	# Use 'eval' to construct the appropriate subroutine name
+	my $network_configuration = eval "\$self->get_$network_type\_network_configuration()";
+	if ($EVAL_ERROR || !$network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "unable to retrieve $network_type network configuration");
+		return;
+	}
+	
+	my $ip_address_info = $network_configuration->{ip_address};
+	if (!defined($ip_address_info)) {
+		notify($ERRORS{'WARNING'}, 0, "$network_type network configuration info does not contain an 'ip_address' key");
+		return;
+	}
+	
+	# Return the first IP address listed
+	my $ip_address = (sort keys(%$ip_address_info))[0];
+	if ($ip_address) {
+		notify($ERRORS{'DEBUG'}, 0, "returning $network_type IP address: $ip_address");
+		return $ip_address;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine $network_type IP address, 'ip_address' value is not set in the network configuration info: \n" . format_data($network_configuration));
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_private_ip_address
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_private_ip_address {
+	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;
+	}
+	
+	return $self->get_ip_address('private');
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_public_ip_address
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_public_ip_address {
+	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;
+	}
+	
+	return $self->get_ip_address('public');
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_subnet_mask
+
+ Parameters  : 
+ Returns     : $ip_address
+ Description : 
+
+=cut
+
+sub get_subnet_mask {
+	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;
+	}
+	
+	# Get the IP address argument
+	my $ip_address = shift;
+	if (!$ip_address) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine subnet mask, IP address argument was not specified");
+		return;
+	}
+
+	# Make sure network configuration was retrieved
+	my $network_configuration = $self->get_network_configuration();
+	if (!$network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "unable to retrieve network configuration");
+		return;
+	}
+	
+	for my $interface_name (keys(%$network_configuration)) {
+		my $ip_address_info = $network_configuration->{$interface_name}{ip_address};
+		
+		if (!defined($ip_address_info->{$ip_address})) {
 			next;
 		}
 		
-		# Loop through the IP addresses for the interface
-		# Try to find a public address
-		for my $ip_address (@ip_addresses) {
-			
-			if (is_public_ip_address($ip_address)) {
-				notify($ERRORS{'DEBUG'}, 0, "determined public interface name: $interface_name (" . join (", ", @ip_addresses) . ")");
-				return $interface_name;
-			}
-			else {
-				notify($ERRORS{'DEBUG'}, 0, "found interface assigned a private address not matching private address for reservation: $interface_name (" . join(", ", @ip_addresses) . ")");
-				
-				if ($public_interface_name) {
-					notify($ERRORS{'DEBUG'}, 0, "already found another interface with a private address not matching private address for reservation: $public_interface_name, the first one found will be used if an interface with a public address isn't found");
-				}
-				else {
-					$public_interface_name = $interface_name;
-					notify($ERRORS{'DEBUG'}, 0, "assuming interface is public if another interface with a public address isn't found: $public_interface_name");
-				}
-			}
+		my $subnet_mask = $ip_address_info->{$ip_address};
+		if ($subnet_mask) {
+			return $subnet_mask;
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "subnet mask is not set for interface '$interface_name' IP address $ip_address in network configuration:\n" . format_data($network_configuration));
+			return;
 		}
 	}
+	
+	notify($ERRORS{'WARNING'}, 0, "interface with IP address $ip_address does not exist in the network configuration:\n" . format_data($network_configuration));
+	return;
+}
 
-	if ($public_interface_name) {
-		notify($ERRORS{'DEBUG'}, 0, "did not find any interfaces assigned a public IP address, returning interface assigned a private IP address not matching the private IP address assigned to the reservation computer: $public_interface_name");
-		return $public_interface_name;
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_private_subnet_mask
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_private_subnet_mask {
+	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;
 	}
-	elsif ($addressless_interface_name) {
-		notify($ERRORS{'DEBUG'}, 0, "did not find any interfaces assigned a public IP address, returning interface found with no bound IP addresses: $addressless_interface_name");
-		return $addressless_interface_name;
+	
+	return $self->get_subnet_mask($self->get_private_ip_address());
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_public_subnet_mask
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_public_subnet_mask {
+	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;
+	}
+	
+	return $self->get_subnet_mask($self->get_public_ip_address());
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_default_gateway
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_default_gateway {
+	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;
+	}
+	
+	# Check if a 'public' or 'private' network type argument was specified
+	# Assume 'public' if not specified
+	my $network_type = lc(shift()) || 'public';
+	if ($network_type && $network_type !~ /(public|private)/i) {
+		notify($ERRORS{'WARNING'}, 0, "network type argument can only be 'public' or 'private'");
+		return;
+	}
+
+	# Get the public or private network configuration
+	# Use 'eval' to construct the appropriate subroutine name
+	my $network_configuration = eval "\$self->get_$network_type\_network_configuration()";
+	if ($EVAL_ERROR || !$network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "unable to retrieve $network_type network configuration");
+		return;
+	}
+	
+	my $default_gateway = $network_configuration->{default_gateway};
+	if ($default_gateway) {
+		notify($ERRORS{'DEBUG'}, 0, "returning $network_type default gateway: $default_gateway");
+		return $default_gateway;
 	}
 	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to determine the public interface from the network configuration:\n" . format_data($network_configuration));
+		notify($ERRORS{'WARNING'}, 0, "unable to determine $network_type default gateway, 'default_gateway' key does not exist in the network configuration info: \n" . format_data($network_configuration));
 		return;
 	}
 }
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_private_default_gateway
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_private_default_gateway {
+	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;
+	}
+	
+	return $self->get_default_gateway('private');
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_public_default_gateway
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub get_public_default_gateway {
+	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;
+	}
+	
+	return $self->get_default_gateway('public');
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 create_text_file
 
  Parameters  : $file_path, $file_contents
  Returns     : boolean
  Description : Creates a text file on the computer. The $file_contents
                string argument is converted to ASCII hex values. These values
-               are echo'd on the Windows host which avoids problems with special
+               are echo'd on the computer which avoids problems with special
                characters and escaping. If the file already exists it is
                overwritten.
 

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=1135767&r1=1135766&r2=1135767&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Tue Jun 14 19:58:52 2011
@@ -2559,40 +2559,17 @@ EOF
 
 =head2 get_network_configuration
 
- Parameters  : $network_type (optional)
+ Parameters  : 
  Returns     : hash reference
  Description : Retrieves the network configuration on the Linux computer and
-					constructs a hash. A $network_type argument can be supplied
-					containing either 'private' or 'public'. If the $network_type
-					argument is not supplied, the hash keys are the network interface
-					names and the hash reference returned is formatted as follows:
-					|--%{eth0}
-					   |--%{eth0}{ip_address}
-					      |--{eth0}{ip_address}{10.10.4.35} = '255.255.240.0'
-					   |--{eth0}{name} = 'eth0'
-					   |--{eth0}{physical_address} = '00:50:56:08:00:f8'
-					|--%{eth1}
-					   |--%{eth1}{ip_address}
-					      |--{eth1}{ip_address}{152.1.14.200} = '255.255.255.0'
-					   |--{eth1}{name} = 'eth1'
-					   |--{eth1}{physical_address} = '00:50:56:08:00:f9'
-					|--%{eth2}
-					   |--%{eth2}{ip_address}
-					      |--{eth2}{ip_address}{10.1.2.33} = '255.255.240.0'
-					   |--{eth2}{name} = 'eth2'
-					   |--{eth2}{physical_address} = '00:0c:29:ba:c1:77'
-					|--%{lo}
-					   |--%{lo}{ip_address}
-					      |--{lo}{ip_address}{127.0.0.1} = '255.0.0.0'
-					   |--{lo}{name} = 'lo'
-						
-					If the $network_type argument is supplied, a hash reference is
-					returned containing only the configuration for the specified
-					interface:
-					|--%{ip_address}
-						|--{ip_address}{10.1.2.33} = '255.255.240.0'
-					|--{name} = 'eth2'
-					|--{physical_address} = '00:0c:29:ba:c1:77'
+               constructs a hash. The hash reference returned is formatted as
+               follows:
+               |--%{eth0}
+					   |--%{eth0}{default_gateway} '10.10.4.1'
+                  |--%{eth0}{ip_address}
+                     |--{eth0}{ip_address}{10.10.4.3} = '255.255.240.0'
+                  |--{eth0}{name} = 'eth0'
+                  |--{eth0}{physical_address} = '00:50:56:08:00:f8'
 
 =cut
 
@@ -2603,186 +2580,75 @@ sub get_network_configuration {
 		return;
 	}
 	
-	# Check if a 'public' or 'private' network type argument was specified
-	my $network_type = lc(shift());
-	if ($network_type && $network_type !~ /(public|private)/i) {
-		notify($ERRORS{'WARNING'}, 0, "network type argument can only be 'public' or 'private'");
+	# Check if the network configuration has already been retrieved and saved in this object
+	return $self->{network_configuration} if ($self->{network_configuration});
+	
+	# Run ipconfig
+	my $ifconfig_command = "/sbin/ifconfig -a";
+	my ($ifconfig_exit_status, $ifconfig_output) = $self->execute($ifconfig_command);
+	if (!defined($ifconfig_output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command to retrieve network configuration: $ifconfig_command");
 		return;
 	}
 	
-	my %network_configuration;
-	
-	# Check if the network configuration has already been retrieved and saved in this object
-	if (!$self->{network_configuration}) {
-		# Run ipconfig
-		my $command = "ifconfig -a";
-		my ($exit_status, $output) = $self->execute($command);
-		if (!defined($output)) {
-			notify($ERRORS{'WARNING'}, 0, "failed to run command to retrieve network configuration: $command");
-			return;
+	# Loop through the ifconfig output lines
+	my $network_configuration;
+	my $interface_name;
+	for my $ifconfig_line (@$ifconfig_output) {
+		# Extract the interface name from the Link line:
+		# eth2      Link encap:Ethernet  HWaddr 00:0C:29:78:77:AB
+		if ($ifconfig_line =~ /^([^\s]+).*Link/) {
+			$interface_name = $1;
+			$network_configuration->{$interface_name}{name} = $interface_name;
 		}
 		
-		# Loop through the ifconfig output lines
-		my $interface_name;
-		for my $line (@$output) {
-			# Extract the interface name from the Link line:
-			# eth2      Link encap:Ethernet  HWaddr 00:0C:29:78:77:AB
-			if ($line =~ /^([^\s]+).*Link/) {
-				$interface_name = $1;
-				$network_configuration{$interface_name}{name} = $interface_name;
-			}
-			
-			# Skip to the next line if the interface name has not been determined yet
-			next if !$interface_name;
-			
-			# Parse the HWaddr line:
-			# eth2      Link encap:Ethernet  HWaddr 00:0C:29:78:77:AB
-			if ($line =~ /HWaddr\s+([\w:]+)/) {
-				$network_configuration{$interface_name}{physical_address} = lc($1);
-			}
-			
-			# Parse the IP address line:
-			# inet addr:10.10.4.35  Bcast:10.10.15.255  Mask:255.255.240.0
-			if ($line =~ /inet addr:([\d\.]+).*Mask:([\d\.]+)/) {
-				$network_configuration{$interface_name}{ip_address}{$1} = $2;
-			}
+		# Skip to the next line if the interface name has not been determined yet
+		next if !$interface_name;
+		
+		# Parse the HWaddr line:
+		# eth2      Link encap:Ethernet  HWaddr 00:0C:29:78:77:AB
+		if ($ifconfig_line =~ /HWaddr\s+([\w:]+)/) {
+			$network_configuration->{$interface_name}{physical_address} = lc($1);
 		}
 		
-		$self->{network_configuration} = \%network_configuration;
-		notify($ERRORS{'DEBUG'}, 0, "retrieved network configuration:\n" . format_data(\%network_configuration));
-	}
-	else {
-		notify($ERRORS{'DEBUG'}, 0, "network configuration has already been retrieved");
-		%network_configuration = %{$self->{network_configuration}};
-	}
-	
-	# 'public' or 'private' wasn't specified, return all network interface information
-	if (!$network_type) {
-		return \%network_configuration;
-	}
-	
-	# Determine either the private or public interface name based on the $network_type argument
-	my $interface_name;
-	if ($network_type =~ /private/i) {
-		$interface_name = $self->get_private_interface_name();
-	}
-	else {
-		$interface_name = $self->get_public_interface_name();
-	}
-	if (!$interface_name) {
-		notify($ERRORS{'WARNING'}, 0, "failed to determine the $network_type interface name");
-		return;
-	}
-	
-	# Extract the network configuration specific to the public or private interface
-	my $return_network_configuration = $network_configuration{$interface_name};
-	if (!$return_network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "network configuration does not exist for interface: $interface_name, network configuration:\n" . format_data(\%network_configuration));
-		return;
-	}
-	notify($ERRORS{'DEBUG'}, 0, "returning $network_type network configuration");
-	return $return_network_configuration;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_private_mac_address
-
- Parameters  : none
- Returns     : string
- Description : Returns the MAC address of the interface assigned the private IP
-               address.
-
-=cut
-
-sub get_private_mac_address {
-	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 $private_network_configuration = $self->get_network_configuration('private');
-	if (!$private_network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "failed to retrieve private network configuration");
-		return;
-	}
-
-	my $private_mac_address = $private_network_configuration->{physical_address};
-	if (!$private_mac_address) {
-		notify($ERRORS{'WARNING'}, 0, "'physical_address' key is not set in the private network configuration hash:\n" . format_data($private_network_configuration));
-		return;
-	}
-	
-	notify($ERRORS{'DEBUG'}, 0, "retrieved private MAC address: $private_mac_address");
-	return $private_mac_address;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_public_mac_address
-
- Parameters  : none
- Returns     : string
- Description : Returns the MAC address of the interface assigned the public IP
-               address.
-
-=cut
-
-sub get_public_mac_address {
-	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 $public_network_configuration = $self->get_network_configuration('public');
-	if (!$public_network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "failed to retrieve public network configuration");
-		return;
-	}
-
-	my $public_mac_address = $public_network_configuration->{physical_address};
-	if (!$public_mac_address) {
-		notify($ERRORS{'WARNING'}, 0, "'physical_address' key is not set in the public network configuration hash:\n" . format_data($public_network_configuration));
-		return;
-	}
-	
-	notify($ERRORS{'DEBUG'}, 0, "retrieved public MAC address: $public_mac_address");
-	return $public_mac_address;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_public_ip_address
-
- Parameters  : none
- Returns     : string
- Description : Returns the public IP address assigned to the computer.
-
-=cut
-
-sub get_public_ip_address {
-	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;
+		# Parse the IP address line:
+		# inet addr:10.10.4.35  Bcast:10.10.15.255  Mask:255.255.240.0
+		if ($ifconfig_line =~ /inet addr:([\d\.]+)\s+Bcast:([\d\.]+)\s+Mask:([\d\.]+)/) {
+			$network_configuration->{$interface_name}{ip_address}{$1} = $3;
+			$network_configuration->{$interface_name}{broadcast_address} = $2;
+		}
 	}
 	
-	my $public_network_configuration = $self->get_network_configuration('public');
-	if (!$public_network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "failed to retrieve public network configuration");
+	# Run route
+	my $route_command = "/sbin/route -n";
+	my ($route_exit_status, $route_output) = $self->execute($route_command);
+	if (!defined($route_output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command to retrieve routing configuration: $route_command");
 		return;
 	}
 	
-	my $public_ip_address = (keys %{$public_network_configuration->{ip_address}})[0];
-	if (!$public_ip_address) {
-		notify($ERRORS{'WARNING'}, 0, "'ip_address' key is not set in the public network configuration hash:\n" . format_data($public_network_configuration));
-		return;
+	# Loop through the route output lines
+	for my $route_line (@$route_output) {
+		my ($default_gateway, $interface_name) = $route_line =~ /^0\.0\.0\.0\s+([\d\.]+).*\s([^\s]+)$/g;
+		
+		if (!defined($interface_name) || !defined($default_gateway)) {
+			notify($ERRORS{'DEBUG'}, 0, "route output line does not contain a default gateway: '$route_line'");
+		}
+		elsif (!defined($network_configuration->{$interface_name})) {
+			notify($ERRORS{'WARNING'}, 0, "found default gateway for '$interface_name' interface but the network configuration for '$interface_name' was not previously retrieved, route output:\n" . join("\n", @$route_output) . "\nnetwork configuation:\n" . format_data($network_configuration));
+		}
+		elsif (defined($network_configuration->{$interface_name}{default_gateway})) {
+			notify($ERRORS{'WARNING'}, 0, "multiple default gateway are configured for '$interface_name' interface, route output:\n" . join("\n", @$route_output));
+		}
+		else {
+			$network_configuration->{$interface_name}{default_gateway} = $default_gateway;
+			notify($ERRORS{'DEBUG'}, 0, "found default route configured for '$interface_name' interface: $default_gateway");
+		}
 	}
 	
-	notify($ERRORS{'DEBUG'}, 0, "retrieved public IP address: $public_ip_address");
-	return $public_ip_address;
+	$self->{network_configuration} = $network_configuration;
+	notify($ERRORS{'DEBUG'}, 0, "retrieved network configuration:\n" . format_data($self->{network_configuration}));
+	return $self->{network_configuration};
 }
 
 #/////////////////////////////////////////////////////////////////////////////

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=1135767&r1=1135766&r2=1135767&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Tue Jun 14 19:58:52 2011
@@ -4904,16 +4904,12 @@ sub get_network_configuration {
 		return;
 	}
 	
-	# Check if a 'public' or 'private' network type argument was specified
-	my $network_type = lc(shift());
-	if ($network_type && $network_type !~ /(public|private)/i) {
-		notify($ERRORS{'WARNING'}, 0, "network type argument can only be 'public' or 'private'");
-		return;
-	}
-
+	# Check if the network configuration has already been retrieved and saved in this object
+	return $self->{network_configuration} if ($self->{network_configuration});
+	
+	my $system32_path = $self->get_system32_path();
 	my $management_node_keys = $self->data->get_management_node_keys();
 	my $computer_node_name   = $self->data->get_computer_node_name();
-	my $system32_path        = $self->get_system32_path() || return;
 	
 	# Get the computer private IP address
 	my $computer_private_ip_address = $self->data->get_computer_private_ip_address();
@@ -4922,542 +4918,106 @@ sub get_network_configuration {
 		return;
 	}
 	
-	
-	
-	my %network_configuration;
-	if (!$self->{network_configuration}) {
-		notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve network configuration information from $computer_node_name");
-		
-		# Run ipconfig /all, try twice in case it fails the first time
-		my $ipconfig_attempt = 0;
-		my $ipconfig_attempt_limit = 2;
-		my ($ipconfig_exit_status, $ipconfig_output);
-		while (++$ipconfig_attempt) {
-			($ipconfig_exit_status, $ipconfig_output) = run_ssh_command($computer_node_name, $management_node_keys, $system32_path . '/ipconfig.exe /all', '', '', 1);
-			if (defined($ipconfig_exit_status) && $ipconfig_exit_status == 0) {
-				last;
-			}
-			elsif (defined($ipconfig_exit_status)) {
-				notify($ERRORS{'WARNING'}, 0, "attempt $ipconfig_attempt: failed to run ipconfig, exit status: $ipconfig_exit_status, output:\n@{$ipconfig_output}");
-			}
-			else {
-				notify($ERRORS{'WARNING'}, 0, "attempt $ipconfig_attempt: failed to run the SSH command to run ipconfig");
-			}
-			
-			if ($ipconfig_attempt >= $ipconfig_attempt_limit) {
-				notify($ERRORS{'WARNING'}, 0, "failed to get network configuration, made $ipconfig_attempt attempts to run ipconfig");
-				return;
-			}
-			
-			sleep 2;
-		}
-	
-		my $interface_name;
-		my $previous_ip = 0;
-		my $setting;
-		
-		for my $line (@{$ipconfig_output}) {
-			# Find beginning of interface section
-			if ($line =~ /\A[^\s].*adapter (.*):\s*\Z/i) {
-				# Get the interface name
-				$interface_name = $1;
-				notify($ERRORS{'DEBUG'}, 0, "found interface: $interface_name");
-				next;
-			}
-			
-			# Skip line if interface hasn't been found yet
-			next if !$interface_name;
-			
-			# Check if the interface should be ignored based on the name or description
-			if ($interface_name =~ /loopback|vmnet|afs|tunnel|6to4|isatap|teredo/i) {
-				next;
-			}
-			
-			# Take apart the line finding the setting name and value with a hideous regex
-			my ($line_setting, $value) = $line =~ /^[ ]{1,8}(\w[^\.]*\w)?[ \.:]+([^\r\n]*)/i;
-			
-			# If the setting was found in the line, use it
-			# Otherwise, use the last found setting
-			$setting = $line_setting if $line_setting;
-			
-			# Skip line if value wasn't found
-			next if !$value;
-			
-			# Normalize the setting format, make it lowercase, convert dashes and spaces to underscores
-			$setting = lc($setting);
-			$setting =~ s/[ -]/_/g;
-			
-			# Windows 6.x includes a version indicator in IP address lines such as IPv4, remove this
-			$setting =~ s/ip(v\d)?_address/ip_address/;
-			
-			# Autoconfiguration ip address will be displayed as "Autoconfiguration IP Address. . . : 169.x.x.x"
-			$setting =~ s/autoconfiguration_ip/ip/;
-			
-			# Remove the trailing s from dns_servers
-			$setting =~ s/dns_servers/dns_server/;
-			
-			# Check which setting was found and add to hash
-			if ($setting =~ /dns_servers/) {
-				push(@{$network_configuration{$interface_name}{$setting}}, $value);
-				#notify($ERRORS{'OK'}, 0, "$interface_name:$setting = @{$network_configuration{$interface_name}{$setting}}");
-			}
-			elsif ($setting =~ /ip_address/) {
-				$value =~ s/[^\.\d]//g;
-				$network_configuration{$interface_name}{$setting}{$value} = '';
-				$previous_ip = $value;
-			}
-			elsif ($setting =~ /subnet_mask/) {
-				$network_configuration{$interface_name}{ip_address}{$previous_ip} = $value;
-			}
-			elsif ($setting) {
-				$network_configuration{$interface_name}{$setting} = $value;
-			}
-		}
-		notify($ERRORS{'DEBUG'}, 0, 'saving network configuration in $self->{network_configuration}');
-		$self->{network_configuration} = \%network_configuration;
-	}
-	else {
-		#notify($ERRORS{'DEBUG'}, 0, "network configuration has already been retrieved");
-		%network_configuration = %{$self->{network_configuration}};
-	}
-	
-	# 'public' or 'private' wasn't specified, return all network interface information
-	if (!$network_type) {
-		notify($ERRORS{'DEBUG'}, 0, "retrieved network configuration:\n" . format_data(\%network_configuration));
-		return \%network_configuration;
-	}
-	
-	my $private_is_public = is_public_ip_address($computer_private_ip_address);
-	
-	my $public_interface_name;
-	my $private_interface_name;
-	
-	# Loop through all of the network interfaces found
-	INTERFACE: foreach my $interface_name (sort keys %network_configuration) {
-		my @ip_addresses  = keys %{$network_configuration{$interface_name}{ip_address}};
-		my $description = $network_configuration{$interface_name}{description};
-		$description = '' if !$description;
+	my $network_configuration;
 
-		# Make sure an IP address was found
-		if (!@ip_addresses) {
-			notify($ERRORS{'DEBUG'}, 0, "interface does not have an ip address: $interface_name");
-			next;
-		}
-		
-		# Check if interface has private IP address assigned to it
-		if (grep { $_ eq $computer_private_ip_address } @ip_addresses) {
-			# If private interface information was requested, return a hash containing only this interface
-			notify($ERRORS{'DEBUG'}, 0, "private interface found: $interface_name, description: $description, address(es): " . join (", ", @ip_addresses));
-			$private_interface_name = $interface_name;
-			if ($network_type =~ /private/i) {
-				last INTERFACE;
-			}
-			else {
-				next INTERFACE;
-			}
-		}
-		elsif ($network_type =~ /private/i) {
-			notify($ERRORS{'DEBUG'}, 0, "interface is not assigned the private IP address: $interface_name (" . join (", ", @ip_addresses) . ")");
-			next INTERFACE;
-		}
-		
-		# Check if the interface should be ignored based on the name or description
-		if ($interface_name =~ /(loopback|vmnet|afs|tunnel|6to4|isatap|teredo)/i) {
-			notify($ERRORS{'DEBUG'}, 0, "interface '$interface_name' ignored because name contains '$1', address(es): " . join (", ", @ip_addresses));
-			next INTERFACE;
-		}
-		elsif ($description =~ /(loopback|virtual|afs|tunnel|pseudo|6to4|isatap)/i) {
-			notify($ERRORS{'DEBUG'}, 0, "interface '$interface_name' ignored because description contains '$1': '$description', address(es): " . join (", ", @ip_addresses));
-			next INTERFACE;
-		}
-		
-		# Loop through the IP addresses for the interface
-		# Once a public address is found, return the data for that interface
-		IP_ADDRESS: for my $ip_address (@ip_addresses) {
-			my $is_public = is_public_ip_address($ip_address);
-			my $default_gateway = $network_configuration{$interface_name}{default_gateway};
-			
-			if ($is_public) {
-				if ($default_gateway) {
-					notify($ERRORS{'DEBUG'}, 0, "public interface found with default gateway: $interface_name, address(es): " . join (", ", @ip_addresses) . ", default gateway: $default_gateway");
-					$public_interface_name = $interface_name;
-					last INTERFACE;
-				}
-				else {
-					notify($ERRORS{'DEBUG'}, 0, "interface found with public address but default gateway is not set: $interface_name, address(es): " . join (", ", @ip_addresses));
-					$public_interface_name = $interface_name;
-				}
-			}
-			else {
-				notify($ERRORS{'DEBUG'}, 0, "interface found with non-public address not matching private address for reservation: $interface_name, address(es): " . join (", ", @ip_addresses));
-				
-				if ($private_is_public) {
-					notify($ERRORS{'DEBUG'}, 0, "private interface IP address is public, this will be returned unless another interface with a public IP address is found");
-					next;
-				}
-				elsif ($public_interface_name) {
-					notify($ERRORS{'DEBUG'}, 0, "already found another interface with a non-public address not matching private address for reservation, the one previously found will be used if a public address isn't found");
-					next;
-				}
-				else {
-					notify($ERRORS{'DEBUG'}, 0, "interface will be returned if another with a public address isn't found");
-					$public_interface_name = $interface_name;
-				}
-			}
-			
-		}
-	}
+	notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve network configuration information from $computer_node_name");
 	
-	if ($network_type =~ /private/i) {
-		if ($private_interface_name) {
-			return {$private_interface_name => $network_configuration{$private_interface_name}};
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "did not find an interface using the private IP address for the reservation: $computer_private_ip_address\n" . format_data(\%network_configuration));
-			return;
-		}
-	}
-	else {
-		if ($public_interface_name) {
-			return {$public_interface_name => $network_configuration{$public_interface_name}};
+	# Run ipconfig /all, try twice in case it fails the first time
+	my $ipconfig_attempt = 0;
+	my $ipconfig_attempt_limit = 2;
+	
+	my $ipconfig_command = $system32_path . '/ipconfig.exe /all';
+	my ($ipconfig_exit_status, $ipconfig_output);
+	while (++$ipconfig_attempt) {
+		($ipconfig_exit_status, $ipconfig_output) = $self->execute($ipconfig_command);
+		if (defined($ipconfig_exit_status) && $ipconfig_exit_status == 0) {
+			last;
 		}
-		elsif ($private_interface_name) {
-			notify($ERRORS{'DEBUG'}, 0, "did not find a separate public interface, assuming a single interface is being used, returning private interface configuration: '$private_interface_name'");
-			return {$private_interface_name => $network_configuration{$private_interface_name}};
+		elsif (defined($ipconfig_exit_status)) {
+			notify($ERRORS{'WARNING'}, 0, "attempt $ipconfig_attempt: failed to run ipconfig, exit status: $ipconfig_exit_status, output:\n@{$ipconfig_output}");
 		}
 		else {
-			notify($ERRORS{'WARNING'}, 0, "failed to find a public interface:\n" . format_data(\%network_configuration));
+			notify($ERRORS{'WARNING'}, 0, "attempt $ipconfig_attempt: failed to run the SSH command to run ipconfig");
+		}
+		
+		if ($ipconfig_attempt >= $ipconfig_attempt_limit) {
+			notify($ERRORS{'WARNING'}, 0, "failed to get network configuration, made $ipconfig_attempt attempts to run ipconfig");
 			return;
 		}
+		
+		sleep 2;
 	}
-} ## end sub get_network_configuration
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_private_interface_name
-
- Parameters  : 
- Returns     : 
- Description : 
-
-=cut
-
-sub get_private_interface_name {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-
-	# Make sure network configuration was retrieved
-	my $network_configuration = $self->get_network_configuration('private');
-	if (!$network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "unable to retrieve network configuration");
-		return;
-	}
-	
-	my $interface_name = (keys(%{$network_configuration}))[0];
-	notify($ERRORS{'DEBUG'}, 0, "returning private interface name: $interface_name");
-	
-	return $interface_name;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_public_interface_name
-
- Parameters  : 
- Returns     : 
- Description : 
-
-=cut
-
-sub get_public_interface_name {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-
-	# Make sure network configuration was retrieved
-	my $network_configuration = $self->get_network_configuration('public');
-	if (!$network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "unable to retrieve network configuration");
-		return;
-	}
-	
-	my $interface_name = (keys(%{$network_configuration}))[0];
-	notify($ERRORS{'DEBUG'}, 0, "returning public interface name: $interface_name");
-	
-	return $interface_name;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_private_mac_address
-
- Parameters  : 
- Returns     : 
- Description : 
-
-=cut
-
-sub get_private_mac_address {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-
-	# Make sure network configuration was retrieved
-	my $network_configuration = $self->get_network_configuration('private');
-	if (!$network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "unable to retrieve network configuration");
-		return;
-	}
-
-	my $interface_name = (keys(%{$network_configuration}))[0];
-	my $mac_address = $network_configuration->{$interface_name}{physical_address};
-	notify($ERRORS{'DEBUG'}, 0, "returning private MAC address: $mac_address");
-	return $mac_address;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_public_mac_address
-
- Parameters  : 
- Returns     : 
- Description : 
-
-=cut
-
-sub get_public_mac_address {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-
-	# Make sure network configuration was retrieved
-	my $network_configuration = $self->get_network_configuration('public');
-	if (!$network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "unable to retrieve network configuration");
-		return;
-	}
-
-	my $interface_name = (keys(%{$network_configuration}))[0];
-	my $mac_address = $network_configuration->{$interface_name}{physical_address};
-	notify($ERRORS{'DEBUG'}, 0, "returning public MAC address: $mac_address");
-	return $mac_address;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_private_ip_address
-
- Parameters  : 
- Returns     : 
- Description : 
-
-=cut
-
-sub get_private_ip_address {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-
-	# Make sure network configuration was retrieved
-	my $network_configuration = $self->get_network_configuration('private');
-	if (!$network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "unable to retrieve network configuration");
-		return;
-	}
-
-	my $interface_name = (keys(%{$network_configuration}))[0];
-	my $ip_address_config = $network_configuration->{$interface_name}{ip_address};
-	my $ip_address = (keys(%$ip_address_config))[0];
-	notify($ERRORS{'DEBUG'}, 0, "returning private IP address: $ip_address");
-	return $ip_address;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_public_ip_address
 
- Parameters  : none
- Returns     : string
- Description : Retrieves the public IP address assigned to the computer. If an
-					auto-generated public IP address is detected (169.254.x.x or
-					0.0.0.0), the public interface is using DHCP, and the management
-					node is configured to use DHCP, an attempt will be made to call
-					'ipconfig /renew' to obtain a valid public IP address.
-
-=cut
-
-sub get_public_ip_address {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	my $argument = shift;
-	
-	# Make sure network configuration was retrieved
-	my $network_configuration = $self->get_network_configuration('public');
-	if (!$network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "unable to retrieve network configuration");
-		return;
-	}
-	
-	my $public_ip_configuration = $self->data->get_management_node_public_ip_configuration();
-	
-	my $interface_name = (keys(%{$network_configuration}))[0];
-	
-	my $ip_address_config = $network_configuration->{$interface_name}{ip_address};
-	
-	my $ip_address;
-	
-	# If multiple IP addresses were found, loop through them until a public IP address was found
-	# If none of the addresses are public, use the first one found
-	for my $ip_address_check (keys(%$ip_address_config)) {
-		if (is_public_ip_address($ip_address_check)) {
-			$ip_address = $ip_address_check;
-			last;
-		}
-		elsif (!$ip_address) {
-			# Only set $ip_address for the first non-public address found
-			$ip_address = $ip_address_check;
-		}
-	}
-	
-	my $dhcp_enabled = $network_configuration->{$interface_name}{dhcp_enabled};
-	
-	# Check if DHCP is to be used and an auto-generated IP address is detected
-	if ($public_ip_configuration =~ /dhcp/i && $dhcp_enabled =~ /yes/i && $ip_address =~ /^(169\.254\.|0\.0\.0\.0)/) {
-		# Check if this is the 2nd attempt to retrieve the public IP address
-		# This subroutine calls itself with a 'renewed' argument if an auto-generated IP address was detected and 'ipconfig /renew' was called
-		if ($argument && $argument eq 'renewed') {
-			notify($ERRORS{'WARNING'}, 0, "unable to retrieve public IP address, public interface '$interface_name' is still assigned an auto-generated IP address after attempting 'ipconfig /renew \"$interface_name\"'");
-			return;
+	my $interface_name;
+	my $previous_ip = 0;
+	my $setting;
+	
+	for my $line (@{$ipconfig_output}) {
+		# Find beginning of interface section
+		if ($line =~ /\A[^\s].*adapter (.*):\s*\Z/i) {
+			# Get the interface name
+			$interface_name = $1;
+			notify($ERRORS{'DEBUG'}, 0, "found interface: $interface_name");
+			next;
 		}
 		
-		notify($ERRORS{'WARNING'}, 0, "public interface '$interface_name' has DHCP enabled and is assigned an auto-generated IP address: $ip_address, management node DHCP configuration: '$public_ip_configuration'");
+		# Skip line if interface hasn't been found yet
+		next if !$interface_name;
 		
-		# Attempt to renew the IP address
-		if (!$self->ipconfig_renew($interface_name)) {
-			notify($ERRORS{'WARNING'}, 0, "unable to retrieve public IP address, failed to renew the IP address for the public interface '$interface_name'");
-			return;
-		}
+		## Check if the interface should be ignored based on the name or description
+		#if ($interface_name =~ /loopback|vmnet|afs|tunnel|6to4|isatap|teredo/i) {
+		#	next;
+		#}
 		
-		# Call this subroutine again, pass the 'renewed' argument so that 'ipconfig /renew' isn't called again (prevent infinite loop)
-		return $self->get_public_ip_address('renewed');
-	}
-	
-	notify($ERRORS{'DEBUG'}, 0, "returning public IP address: $ip_address");
-	return $ip_address;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_public_default_gateway
-
- Parameters  : None
- Returns     : If successful: string containing IP address
-               If failed: false
- Description : Returns the default gateway currently configured for the
-               computer's public interface.
-
-=cut
-
-sub get_public_default_gateway {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	my $computer_nodename = $self->data->get_computer_node_name() || 'node';
-	
-	my $default_gateway;
-	
-	# Check the management node's DHCP IP configuration mode (static or dynamic)
-	my $ip_configuration = $self->data->get_management_node_public_ip_configuration();
-	notify($ERRORS{'DEBUG'}, 0, "IP configuration mode in use: $ip_configuration");
-	if ($ip_configuration !~ /static/i) {
-		# Management node is using dynamic public IP addresses
-		# Retrieve public network configuration currently in use on computer
-		my $network_configuration = $self->get_network_configuration('public');
-		if ($network_configuration) {
-			# Get the default gateway out of the network configuration currently being used
-			my $interface_name = (keys(%{$network_configuration}))[0];
-			$default_gateway = $network_configuration->{$interface_name}{default_gateway};
-			if ($default_gateway) {
-				notify($ERRORS{'DEBUG'}, 0, "returning default gateway currently in use on $computer_nodename: $default_gateway");
-				return $default_gateway;
-			}
-			else {
-				notify($ERRORS{'WARNING'}, 0, "unable to determine default gateway currently in use on $computer_nodename");
-			}
+		# Take apart the line finding the setting name and value with a hideous regex
+		my ($line_setting, $value) = $line =~ /^[ ]{1,8}(\w[^\.]*\w)?[ \.:]+([^\r\n]*)/i;
+		
+		# If the setting was found in the line, use it
+		# Otherwise, use the last found setting
+		$setting = $line_setting if $line_setting;
+		
+		# Skip line if value wasn't found
+		next if !$value;
+		
+		# Normalize the setting format, make it lowercase, convert dashes and spaces to underscores
+		$setting = lc($setting);
+		$setting =~ s/[ -]/_/g;
+		
+		# Windows 6.x includes a version indicator in IP address lines such as IPv4, remove this
+		$setting =~ s/ip(v\d)?_address/ip_address/;
+		
+		# Autoconfiguration ip address will be displayed as "Autoconfiguration IP Address. . . : 169.x.x.x"
+		$setting =~ s/autoconfiguration_ip/ip/;
+		
+		# Remove the trailing s from dns_servers
+		$setting =~ s/dns_servers/dns_server/;
+		
+		# Check which setting was found and add to hash
+		if ($setting =~ /dns_servers/) {
+			push(@{$network_configuration->{$interface_name}{$setting}}, $value);
+			#notify($ERRORS{'OK'}, 0, "$interface_name:$setting = @{$network_configuration->{$interface_name}{$setting}}");
 		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "unable to retrieve public network configuration currently in use on $computer_nodename");
+		elsif ($setting =~ /ip_address/) {
+			$value =~ s/[^\.\d]//g;
+			$network_configuration->{$interface_name}{$setting}{$value} = '';
+			$previous_ip = $value;
+		}
+		elsif ($setting =~ /subnet_mask/) {
+			$network_configuration->{$interface_name}{ip_address}{$previous_ip} = $value;
+		}
+		elsif ($setting =~ /physical_address/) {
+			# Change '-' characters in MAC address to ':' to be consistent with Linux
+			$value =~ s/-/:/g;
+			$network_configuration->{$interface_name}{physical_address} = $value;
+		}
+		elsif ($setting) {
+			$network_configuration->{$interface_name}{$setting} = $value;
 		}
 	}
 	
-	# Static addresses used, get default gateway address configured for management node
-	$default_gateway = $self->data->get_management_node_public_default_gateway();
-	
-	# Make sure default gateway was retrieved
-	if ($default_gateway) {
-		notify($ERRORS{'DEBUG'}, 0, "returning management node's default gateway address: $default_gateway");
-		return $default_gateway;
-	}
-	else {
-		notify($ERRORS{'WARNING'}, 0, "unable to retrieve management node's default gateway address");
-		return;
-	}
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_private_subnet_mask
-
- Parameters  : 
- Returns     : 
- Description : 
-
-=cut
-
-sub get_private_subnet_mask {
-	my $self = shift;
-	if (ref($self) !~ /windows/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-		
-	# Get private network configuration
-	my $network_configuration = $self->get_network_configuration('private');
-	if (!$network_configuration) {
-		notify($ERRORS{'WARNING'}, 0, "unable to retrieve network configuration");
-		return;
-	}
-	
-	my $interface_name = (keys(%{$network_configuration}))[0];	
-	my $ip_addresses = $network_configuration->{$interface_name}{ip_address};
-	my $ip_address = (keys(%$ip_addresses))[0];
-	my $subnet_mask = $ip_addresses->{$ip_address};
-	
-	if (!$subnet_mask) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine private subnet mask, network configuration:\n" . format_data($network_configuration));
-		return;
-	}
-	
-	notify($ERRORS{'DEBUG'}, 0, "returning private subnet mask: $subnet_mask");
-	return $subnet_mask;
+	$self->{network_configuration} = $network_configuration;
+	notify($ERRORS{'DEBUG'}, 0, "retrieved network configuration:\n" . format_data($self->{network_configuration}));
+	return $self->{network_configuration};
 }
 
 #/////////////////////////////////////////////////////////////////////////////