Author: arkurth
Date: Thu Mar  5 19:10:04 2015
New Revision: 1664459

URL: http://svn.apache.org/r1664459
Log:
VCL-174
Renamed utils.pm::get_connect_method_info to 
get_reservation_connect_method_info and changed argument from $imagerevision_id 
to $reservation_id. Updated all calls to this subroutine.

Added iptables.pm::sanitize_reservation. Changed call in reclaim.pm from 
delete_chain to sanitize_reservation to make things more generic and flexible 
for future modules.

Removed required $chain_name argument from iptables.pm::add_nat_port_forward. 
Added get_reservation_chain_name subroutine so that the chain name used for 
individual reservations is only defined in 1 location.

Added iptables.pm::save_configuration subroutine. This gets called from 
sanitize_reservation and configure_nat_reservation.

Other
Updated utils.pm::get_vmhost_info to accept either a VM host computer name or 
ID.

Modified:
    vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
    vcl/trunk/managementnode/lib/VCL/reclaim.pm
    vcl/trunk/managementnode/lib/VCL/utils.pm

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1664459&r1=1664458&r2=1664459&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Thu Mar  5 19:10:04 2015
@@ -2977,7 +2977,7 @@ sub process_connect_methods {
                                                return;
                                        }
                                        
-                                       if 
($self->nathost_os->firewall->add_nat_port_forward($protocol, $nat_public_port, 
$computer_ip_address, $port, "$PROCESSNAME-$reservation_id")) {
+                                       if 
($self->nathost_os->firewall->add_nat_port_forward($protocol, $nat_public_port, 
$computer_ip_address, $port)) {
                                                notify($ERRORS{'OK'}, 0, "NAT 
port forwarding configured on $nathost_hostname for '$name' connect method: 
$nathost_public_ip_address:$nat_public_port --> $computer_ip_address:$port 
($protocol)");
                                        }
                                        else {

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm?rev=1664459&r1=1664458&r2=1664459&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm 
(original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm Thu 
Mar  5 19:10:04 2015
@@ -24,7 +24,7 @@ VCL::Module::OS::Linux::firewall::iptabl
 
 =head1 DESCRIPTION
 
- This module provides VCL support for iptables-based firewalls.
+ This module provides support for configuring iptables-based firewalls.
 
 =cut
 
@@ -64,7 +64,8 @@ use VCL::utils;
 
  Parameters  : none
  Returns     : boolean
- Description : 
+ Description : Returns true if the iptables command exists on the computer.
+               Returns false if the command does not exist.
 
 =cut
 
@@ -94,9 +95,58 @@ sub initialize {
 
 =head2 insert_rule
 
- Parameters  : none
+ Parameters  : hash reference
  Returns     : boolean
- Description : 
+ Description : Inserts an iptables rule. The argument must be a properly
+               constructed hash reference. Supported top-level hash keys are:
+               * {table} => '<string>' (optional)
+                    Specifies the name of the table the rule will be added to.
+                    If ommitted, the rule will be added to the filter table by
+                    default.
+               * {chain} => '<string>' (mandatory)
+                    Specifies the name of the chain the rule will be added to.
+               * {parameters} => {<hash reference>} (optional)
+                    Allows any of the options under the iptables man page
+                    "PARAMETERS" section to be specified. Full parameter names
+                    should be used such as "protocol" instead of "-p".
+                    Parameters can be negated by adding an exclaimation point
+                    before the parameter name.
+               * {match_extensions} => {<hash reference>} (optional)
+                    Allows any of the options under the iptables man page
+                    "MATCH EXTENSIONS" section to be specified. Each key should
+                    be a match extension module name such as "state". The value
+                    should be a hash reference whose key names should be the
+                    names of the supported options for that match extension
+                    module.
+               * {target_extensions} => {<hash reference>} (optional)
+                    Allows any of the options under the iptables man page
+                    "TARGET EXTENSIONS" section to be specified. Each key 
should
+                    be a target extension module name such as "DNAT". The value
+                    should be a hash reference whose key names should be the
+                    names of the supported options for that target extension
+                    module.
+               Example:
+               {
+                  'table' => 'nat',
+                  'chain' => 'PREROUTING',
+                  'parameters' => {
+                     'protocol' => 'tcp',
+                     'in-interface' => 'eth1',
+                  },
+                  'match_extensions' => {
+                     'comment' => {
+                        'comment' => "forward: eth1:50443 --> 10.1.2.3.4:443 
(tcp)",
+                     },
+                     $protocol => {
+                        'destination-port' => 50443,
+                     },
+                  },
+                  'target_extensions' => {
+                     'DNAT' => {
+                        'to-destination' => "10.1.2.3.4:443",
+                     },
+                  },
+               }
 
 =cut
 
@@ -196,7 +246,7 @@ sub insert_rule {
 
  Parameters  : hash reference
                -or-
-                                       $table_name, $chain_name, 
$rule_specification
+               $table_name, $chain_name, $rule_specification
  Returns     : boolean
  Description : Deletes a rule.
 
@@ -413,6 +463,35 @@ sub delete_chain {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 sanitize_reservation
+
+ Parameters  : $reservation_id (optional)
+ Returns     : boolean
+ Description : Deletes the chains created for the reservation. Saves the
+               iptables configuration.
+
+=cut
+
+sub sanitize_reservation {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return 0;
+       }
+       
+       my $reservation_id = shift || $self->data->get_reservation_id();
+       my $reservation_chain_name = 
$self->get_reservation_chain_name($reservation_id);
+       
+       if (!$self->delete_chain('nat', $reservation_chain_name)) {
+               return;
+       }
+       
+       $self->save_configuration();
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 delete_chain_references
 
  Parameters  : $table_name, $referenced_chain_name
@@ -517,7 +596,49 @@ sub flush_chain {
 
  Parameters  : $table_name, $chain_name (optional)
  Returns     : boolean
- Description : 
+ Description : Retrieves the configuration of an iptables table and constructs 
a
+               hash reference. Example:
+               {
+                 "OUTPUT" => {
+                   "policy" => "ACCEPT"
+                 },
+                 "PREROUTING" => {
+                   "policy" => "ACCEPT",
+                   "rules" => [
+                     {
+                       "parameters" => {
+                         "jump" => {
+                           "target" => "vcld-3116"
+                         }
+                       },
+                       "rule_specification" => "-j vcld-3116"
+                     }
+                   ]
+                 },
+                 "vcld-3116" => {
+                   "rules" => [
+                     {
+                       "match_extensions" => {
+                         "comment" => {
+                           "comment" => "forward: eth1:18892 --> 
192.168.110.201:53 (tcp)"
+                         },
+                         "tcp" => {
+                           "dport" => 18892
+                         }
+                       },
+                       "parameters" => {
+                         "in-interface" => "eth1",
+                         "jump" => {
+                           "target" => "DNAT",
+                           "to-destination" => "192.168.110.201:53"
+                         },
+                         "protocol" => "tcp"
+                       },
+                       "rule_specification" => "-i eth1 -p tcp -m comment 
--comment \"forward: eth1:18892 --> 192.168.110.201:53 (tcp)\" -m tcp --dport 
18892 -j DNAT --to-destination 192.168.110.201:53"
+                     }
+                   ]
+                 }
+               }
 
 =cut
 
@@ -534,6 +655,8 @@ sub get_table_info {
                return;
        }
        
+       $ENV{iptables_get_table_info_count}{$table_name}++;
+       
        my $computer_name = $self->data->get_computer_hostname();
        
        my $command = "/sbin/iptables --list-rules";
@@ -599,10 +722,10 @@ sub get_table_info {
                }
                elsif ($iptables_command =~ /^(-A|--append chain)/) {
                        # -A, --append chain rule-specification
-                       notify($ERRORS{'DEBUG'}, 0, "parsing iptables append 
rule command:\n" .
-                               "iptables command: $line\n" .
-                               "iptables rule specification: 
$rule_specification_string"
-                       );
+                       #notify($ERRORS{'DEBUG'}, 0, "parsing iptables append 
rule command:\n" .
+                       #       "iptables command: $line\n" .
+                       #       "iptables rule specification: 
$rule_specification_string"
+                       #);
                        
                        my $rule = {};
                        $rule->{rule_specification} = 
$rule_specification_string;
@@ -662,7 +785,7 @@ sub get_table_info {
                                        # Check if this is the beginning of a 
target extension option
                                        if ($target_extension_option_section =~ 
/^[-]+(\w[\w-]+)/) {
                                                $target_extension_option_name = 
$1;
-                                               notify($ERRORS{'DEBUG'}, 0, 
"located $target_parameter target extension option: 
$target_extension_option_name");
+                                               #notify($ERRORS{'DEBUG'}, 0, 
"located $target_parameter target extension option: 
$target_extension_option_name");
                                                
$rule->{parameters}{$target_parameter}{$target_extension_option_name} = undef;
                                        }
                                        elsif (!$target_extension_option_name) {
@@ -685,13 +808,13 @@ sub get_table_info {
                                
                                my $rule_specification_string_before = 
$rule_specification_string;
                                $rule_specification_string =~ 
s/$target_parameter_regex//g;
-                               notify($ERRORS{'DEBUG'}, 0, "parsed iptables 
target parameter:\n" .
-                                       "target parameter: 
$target_parameter_match\n" .
-                                       "target: $target\n" .
-                                       "target specification removal regex: 
$target_parameter_regex\n" .
-                                       "rule specification before: 
$rule_specification_string_before\n" .
-                                       "rule specification after:  
$rule_specification_string"
-                               );
+                               #notify($ERRORS{'DEBUG'}, 0, "parsed iptables 
target parameter:\n" .
+                               #       "target parameter: 
$target_parameter_match\n" .
+                               #       "target: $target\n" .
+                               #       "target specification removal regex: 
$target_parameter_regex\n" .
+                               #       "rule specification before: 
$rule_specification_string_before\n" .
+                               #       "rule specification after:  
$rule_specification_string"
+                               #);
                        }  # TARGET_PARAMETER
                        
                        
@@ -723,7 +846,7 @@ sub get_table_info {
                                        # If section begins with a letter it 
should be the match extension module name
                                        if ($match_extension_section =~ 
/^[a-z]/i) {
                                                $match_extension_module_name = 
$match_extension_section;
-                                               notify($ERRORS{'DEBUG'}, 0, 
"located match extension module name: $match_extension_module_name");
+                                               #notify($ERRORS{'DEBUG'}, 0, 
"located match extension module name: $match_extension_module_name");
                                                next MATCH_EXTENSION_SECTION;
                                        }
                                        else {
@@ -742,7 +865,7 @@ sub get_table_info {
                                                $match_extension_option = 
"!$match_extension_option";
                                                
$match_extension_option_inverted = 0;
                                        }
-                                       notify($ERRORS{'DEBUG'}, 0, "match 
extension module name: $match_extension_module_name, located match extension 
option: $match_extension_option");
+                                       #notify($ERRORS{'DEBUG'}, 0, "match 
extension module name: $match_extension_module_name, located match extension 
option: $match_extension_option");
                                        next MATCH_EXTENSION_SECTION;
                                }
                                elsif ($match_extension_section =~ /^!/) {
@@ -795,7 +918,7 @@ sub get_table_info {
 
  Parameters  : $public_ip_address, $internal_ip_address
  Returns     : boolean
- Description : 
+ Description : Configures the iptables firewall to pass NAT traffic.
 
 =cut
 
@@ -840,8 +963,9 @@ sub configure_nat {
        
        # Check if NAT has previously been configured
        for my $rule (@{$nat_table_info->{POSTROUTING}{rules}}) {
-               if ($rule =~ /MASQUERADE/) {
-                       notify($ERRORS{'DEBUG'}, 0, "POSTROUTING chain in nat 
table contains a MASQUERADE rule, assuming NAT has already been configured: 
$rule");
+               my $rule_specification = $rule->{rule_specification};
+               if ($rule_specification =~ /MASQUERADE/) {
+                       notify($ERRORS{'DEBUG'}, 0, "POSTROUTING chain in nat 
table contains a MASQUERADE rule, assuming NAT has already been configured: 
$rule_specification");
                        return 1;
                }
        }
@@ -1022,7 +1146,7 @@ sub configure_nat_reservation {
                return;
        }
        
-       my $chain_name = "$PROCESSNAME-$reservation_id";
+       my $chain_name = $self->get_reservation_chain_name();
        
        # Check if chain for reservation has already been created
        if (defined($nat_table_info->{$chain_name})) {
@@ -1035,8 +1159,9 @@ sub configure_nat_reservation {
        
        # Check if rule to jump to reservation's chain already exists in the 
PREROUTING table
        for my $rule (@{$nat_table_info->{PREROUTING}{rules}}) {
-               if ($rule =~ /-j $chain_name(\s|$)/) {
-                       notify($ERRORS{'DEBUG'}, 0, "PREROUTING chain in nat 
table on $computer_name already contains a rule to jump to '$chain_name' chain: 
$rule");
+               my $rule_specification = $rule->{rule_specification};
+               if ($rule_specification =~ /-j $chain_name(\s|$)/) {
+                       notify($ERRORS{'DEBUG'}, 0, "PREROUTING chain in nat 
table on $computer_name already contains a rule to jump to '$chain_name' chain: 
$rule_specification");
                        return 1;;
                }
        }
@@ -1053,6 +1178,7 @@ sub configure_nat_reservation {
                return;
        }
        
+       $self->save_configuration();
        return 1;
 }
 
@@ -1062,7 +1188,7 @@ sub configure_nat_reservation {
 
  Parameters  : $protocol, $source_port, $destination_ip_address, 
$destination_port, $chain_name (optional)
  Returns     : boolean
- Description : 
+ Description : Forwards a port via DNAT.
 
 =cut
 
@@ -1092,12 +1218,48 @@ sub add_nat_port_forward {
                notify($ERRORS{'WARNING'}, 0, "destination port argument was 
not provided");
                return;
        }
-       $chain_name = 'PREROUTING' unless defined $chain_name;
+       $chain_name = $self->get_reservation_chain_name() unless defined 
$chain_name;
        
        $protocol = lc($protocol);
        
        my $public_interface_name = $self->os->get_public_interface_name();
-       my $public_ip_address = $self->os->get_public_ip_address();
+       
+       my $nat_table_info = $self->get_table_info('nat');
+       if (!$nat_table_info) {
+               notify($ERRORS{'WARNING'}, 0, "failed to add NAT port forward 
on $computer_name, nat table information could not be retrieved");
+               return;
+       }
+       
+       # Check if rule has previously been added
+       for my $rule (@{$nat_table_info->{$chain_name}{rules}}) {
+               my $rule_target = $rule->{parameters}{jump}{target} || '<not 
set>';
+               if ($rule_target ne 'DNAT') {
+                       #notify($ERRORS{'DEBUG'}, 0, "ignoring rule, target is 
not DNAT: $rule_target");
+                       next;
+               }
+               
+               my $rule_protocol = $rule->{parameters}{protocol} || '<not 
set>';
+               if (lc($rule_protocol) ne $protocol) {
+                       #notify($ERRORS{'DEBUG'}, 0, "ignoring rule, protocol 
'$rule_protocol' does not match protocol argument: '$protocol'");
+                       next;
+               }
+               
+               my $rule_source_port = 
$rule->{match_extensions}{$protocol}{dport} || '<not set>';
+               if ($rule_source_port ne $source_port) {
+                       #notify($ERRORS{'DEBUG'}, 0, "ignoring rule, source 
port $rule_source_port does not match argument: $source_port");
+                       next;
+               }
+               
+               my $rule_destination = 
$rule->{parameters}{jump}{'to-destination'} || '<not set>';
+               if ($rule_destination ne 
"$destination_ip_address:$destination_port") {
+                       #notify($ERRORS{'DEBUG'}, 0, "ignoring rule, 
destination $rule_destination does not match argument: 
$destination_ip_address:$destination_port");
+                       next;
+               }
+               
+               my $rule_specification = $rule->{'rule_specification'};
+               notify($ERRORS{'DEBUG'}, 0, "NAT port forwared rule already 
exists, chain: $chain_name, protocol: $protocol, source port: $source_port, 
destination: $destination_ip_address:$destination_port\nrule 
specification:\n$rule_specification");
+               return 1;
+       }
        
        if ($self->insert_rule({
                'table' => 'nat',
@@ -1105,11 +1267,10 @@ sub add_nat_port_forward {
                'parameters' => {
                        'protocol' => $protocol,
                        'in-interface' => $public_interface_name,
-                       #'destination' => $public_ip_address,
                },
                'match_extensions' => {
                        'comment' => {
-                               'comment' => "forward: 
$public_ip_address:$source_port --> $destination_ip_address:$destination_port 
($protocol)",
+                               'comment' => "forward: 
$public_interface_name:$source_port --> 
$destination_ip_address:$destination_port ($protocol)",
                        },
                        $protocol => {
                                'destination-port' => $source_port,
@@ -1131,6 +1292,129 @@ sub add_nat_port_forward {
 }
 
 #/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_reservation_chain_name
+
+ Parameters  : $reservation_id (optional)
+ Returns     : string
+ Description : Returns the name of the iptables chain containing rules for a
+               single VCL reservation.
+
+=cut
+
+sub get_reservation_chain_name {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return 0;
+       }
+       
+       my $reservation_id = shift || $self->data->get_reservation_id();
+       return "$PROCESSNAME-$reservation_id";
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 save_configuration
+
+ Parameters  : $file_path (optional)
+ Returns     : boolean
+ Description : Saves the current iptables configuration by running
+               iptables-save. If no file path argument is provided, the output
+               is saved to /etc/sysconfig/iptables.
+
+=cut
+
+sub save_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 0;
+       }
+       
+       my $file_path = shift || '/etc/sysconfig/iptables';
+       
+       my $computer_id = $self->data->get_computer_id();
+       my $computer_name = $self->data->get_computer_hostname();
+       
+       # Get the output of iptables-save
+       # IMPORTANT: don't simply redirect the output to the file
+       # If iptables is stopped or else the previously saved configuration 
will be overwritten
+       my $command = '/sbin/iptables-save';
+       my ($exit_status, $output) = $self->os->execute($command, 0);
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command to 
save iptables configuration on $computer_name");
+               return;
+       }
+       elsif ($exit_status ne 0) {
+               notify($ERRORS{'WARNING'}, 0, "failed to save iptables 
configuration on $computer_name, exit status: $exit_status, 
command:\n$command\noutput:\n" . join("\n", @$output));
+               return 0;
+       }
+       
+       my $file_exists = $self->os->file_exists($file_path);
+       
+       # Make sure output contains at least 1 line beginning with "-A"
+       # If the iptables service is stopped the output will be blank
+       # If the iptables service is stopped but "iptables -L" is executed the 
output may contain something like:
+       # #Generated by iptables-save v1.4.7 on Thu Mar  5 13:36:51 2015
+       # *filter
+       # :INPUT ACCEPT [40:4736]
+       # :FORWARD ACCEPT [0:0]
+       # :OUTPUT ACCEPT [8:1200]
+       # COMMIT
+       # #Completed on Thu Mar  5 13:36:51 2015
+       if (!grep(/\w/, @$output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to save iptables 
configuration on $computer_name, iptables service may not be running, no output 
was returned from $command");
+               return 0;
+       }
+       elsif (!grep(/^-A/, @$output) && ($file_exists || $file_path eq 
'/etc/sysconfig/iptables')) {
+               notify($ERRORS{'WARNING'}, 0, "iptables configuration not saved 
to $file_path on $computer_name for safety, iptables service may not be 
running, output of $command does not contain any lines beginning with '-A':\n" 
. join("\n", @$output));
+               return 0;
+       }
+       
+       # Attempt to get a semaphore if the file already exists
+       my $semaphore;
+       if ($file_exists) {
+               $semaphore = 
$self->get_semaphore("iptables-save_configuration-$computer_id", (30 * 1));
+               if (!$semaphore) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to save iptables 
configuration on $computer_name, $file_path already exists and semaphore could 
not be obtained to avoid multiple processes writing to the file at the same 
time");
+                       return;
+               }
+       }
+       
+       return $self->os->create_text_file($file_path, join("\n", @$output));
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 DESTROY
+
+ Parameters  : none
+ Returns     : true
+ Description : 
+
+=cut
+
+sub DESTROY {
+       my $self = shift || return;
+       
+       my $address = sprintf('%x', $self);
+       my $table_count_string;
+       if ($ENV{iptables_get_table_info_count}) {
+               for my $table_name (keys $ENV{iptables_get_table_info_count}) {
+                       my $table_count = 
$ENV{iptables_get_table_info_count}{$table_name};
+                       $table_count_string .= "$table_name: $table_count\n";
+               }
+               notify($ERRORS{'DEBUG'}, 0, "get_table_info 
calls:\n$table_count_string");
+       }
+       
+       # Check for an overridden destructor
+       $self->SUPER::DESTROY if $self->can("SUPER::DESTROY");
+       
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
 
 1;
 __END__

Modified: vcl/trunk/managementnode/lib/VCL/reclaim.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/reclaim.pm?rev=1664459&r1=1664458&r2=1664459&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/reclaim.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/reclaim.pm Thu Mar  5 19:10:04 2015
@@ -131,12 +131,18 @@ sub process {
        if ($self->nathost_os(0)) {
                my $nathost_hostname = $self->data->get_nathost_hostname();
                if ($self->nathost_os->firewall()) {
-                       if (!$self->nathost_os->firewall->delete_chain('nat', 
$reservation_id)) {
-                               notify($ERRORS{'CRITICAL'}, 0, "failed to 
delete '$reservation_id' chain from the nat table on NAT host 
$nathost_hostname");
+                       if 
($self->nathost_os->firewall->can('sanitize_reservation')) {
+                               if 
(!$self->nathost_os->firewall->sanitize_reservation()) {
+                                       notify($ERRORS{'CRITICAL'}, 0, "failed 
to sanitize firewall for reservation on NAT host $nathost_hostname");
+                               }
                        }
+                       else {
+                               notify($ERRORS{'WARNING'}, 0, "unable to 
sanitize firewall for reservation on NAT host $nathost_hostname, " . 
ref($self->nathost_os->firewall) . " does not implement a 
'sanitize_reservation' subroutine");
+                       }
+                       
                }
                else {
-                       notify($ERRORS{'CRITICAL'}, 0, "failed to delete 
'$reservation_id' chain from the nat table on NAT host $nathost_hostname, NAT 
host OS object is not available");
+                       notify($ERRORS{'WARNING'}, 0, "unable to sanitize 
firewall for reservation on NAT host $nathost_hostname, NAT host OS firewall 
object is not available");
                }
        }
        

Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1664459&r1=1664458&r2=1664459&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Thu Mar  5 19:10:04 2015
@@ -134,7 +134,6 @@ our @EXPORT = qw(
        get_computer_nathost_info
        get_computer_private_ip_address_info
        get_computers_controlled_by_mn
-       get_connect_method_info
        get_connectlog_info
        get_connectlog_remote_ip_address_info
        get_copy_speed_info_string
@@ -178,6 +177,7 @@ our @EXPORT = qw(
        get_reservation_accounts
        get_reservation_computerloadlog_entries
        get_reservation_computerloadlog_time
+       get_reservation_connect_method_info
        get_reservation_management_node_hostname
        get_reservation_vcld_process_name_regex
        get_request_loadstate_names
@@ -3053,7 +3053,7 @@ EOF
                }
                
                # Add the connect method info to the hash
-               my $connect_method_info = 
get_connect_method_info($imagerevision_id, 0);
+               my $connect_method_info = 
get_reservation_connect_method_info($reservation_id, 0);
                $request_info->{reservation}{$reservation_id}{connect_methods} 
= $connect_method_info;
                
                # Add the managementnode info to the hash
@@ -3314,9 +3314,9 @@ sub set_managementnode_state {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 get_requests
+=head2 get_management_node_requests
 
- Parameters  : management node id
+ Parameters  : $management_node_id
  Returns     : hash
  Description : gets request information for a particular management node
 
@@ -3835,7 +3835,7 @@ sub get_default_imagemeta_info {
 
 =head2  get_vmhost_info
 
- Parameters  : $vmhost_id, $no_cache (optional)
+ Parameters  : $vmhost_identifier, $no_cache (optional)
  Returns     : Hash reference
  Description : Retrieves info from the database for the vmhost, vmprofile, and
                repository and datastore imagetypes.
@@ -3844,15 +3844,15 @@ sub get_default_imagemeta_info {
 
 
 sub get_vmhost_info {
-       my ($vmhost_id, $no_cache) = @_;
+       my ($vmhost_identifier, $no_cache) = @_;
        
        # Check the passed parameter
-       if (!defined($vmhost_id)) {
-               notify($ERRORS{'WARNING'}, 0, "vmhost ID argument was not 
specified");
+       if (!defined($vmhost_identifier)) {
+               notify($ERRORS{'WARNING'}, 0, "VM host identifier argument was 
not specified");
                return;
        }
        
-       return $ENV{vmhost_info}{$vmhost_id} if (!$no_cache && 
$ENV{vmhost_info}{$vmhost_id});
+       return $ENV{vmhost_info}{$vmhost_identifier} if (!$no_cache && 
$ENV{vmhost_info}{$vmhost_identifier});
        
        # Get a hash ref containing the database column names
        my $database_table_columns = get_database_table_columns();
@@ -3885,15 +3885,24 @@ FROM
 vmhost,
 vmprofile,
 imagetype repositoryimagetype,
-imagetype datastoreimagetype
+imagetype datastoreimagetype,
+computer
 
 WHERE
-vmhost.id = '$vmhost_id'
-AND vmprofile.id = vmhost.vmprofileid
+vmprofile.id = vmhost.vmprofileid
 AND vmprofile.repositoryimagetypeid = repositoryimagetype.id
 AND vmprofile.datastoreimagetypeid = datastoreimagetype.id
+AND vmhost.computerid = computer.id
+AND 
 EOF
-
+       
+       if ($vmhost_identifier =~ /^\d+$/) {
+               $select_statement .= "vmhost.id = '$vmhost_identifier'";
+       }
+       else {
+               $select_statement .= "computer.hostname REGEXP 
'$vmhost_identifier(\\\\.|\$)'";
+       }
+       
        # Call the database select subroutine
        my @selected_rows = database_select($select_statement);
 
@@ -3985,9 +3994,15 @@ EOF
        $vmhost_info->{vmprofile}{vmpath} = 
$vmhost_info->{vmprofile}{datastorepath} if !$vmhost_info->{vmprofile}{vmpath};
        $vmhost_info->{vmprofile}{virtualdiskpath} = 
$vmhost_info->{vmprofile}{vmpath} if 
!$vmhost_info->{vmprofile}{virtualdiskpath};
 
-       notify($ERRORS{'DEBUG'}, 0, "retrieved VM host $vmhost_id info, 
computer: $vmhost_info->{computer}{hostname}");
-       $ENV{vmhost_info}{$vmhost_id} = $vmhost_info;
-       return $ENV{vmhost_info}{$vmhost_id};
+       notify($ERRORS{'DEBUG'}, 0, "retrieved VM host $vmhost_identifier info, 
computer: $vmhost_info->{computer}{hostname}");
+       $ENV{vmhost_info}{$vmhost_identifier} = $vmhost_info;
+       
+       my $vmhost_id = $vmhost_info->{id};
+       if ($vmhost_identifier ne $vmhost_id) {
+               $ENV{vmhost_info}{$vmhost_id} = $vmhost_info;
+       }
+       
+       return $ENV{vmhost_info}{$vmhost_identifier};
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -7141,7 +7156,7 @@ EOF
                }
        }
        
-       notify($ERRORS{'DEBUG'}, 0, "retrieved info for computer: 
$computer_identifier");
+       notify($ERRORS{'DEBUG'}, 0, "retrieved info for computer: 
$computer_hostname ($computer_id)");
        $ENV{computer_info}{$computer_identifier} = $computer_info;
        $ENV{computer_info}{$computer_identifier}{RETRIEVAL_TIME} = time;
        return $ENV{computer_info}{$computer_identifier};
@@ -7378,7 +7393,7 @@ sub get_natport_ranges {
                push @natport_ranges, [$start_port, $end_port];
        }
        
-       notify($ERRORS{'DEBUG'}, 0, "parsed natport_ranges variable:\n" . 
format_data(\@natport_ranges));
+       notify($ERRORS{'DEBUG'}, 0, "parsed natport_ranges variable: " . 
join(', ', @natport_ranges));
        $ENV{natport_ranges} = \@natport_ranges;
        return @natport_ranges;
 }
@@ -7421,7 +7436,7 @@ sub populate_reservation_natport {
        notify($ERRORS{'DEBUG'}, 0, "computer $computer_id is mapped to NAT 
host $nathost_hostname ($nathost_hostname)");
        
        # Retrieve the connect method info - do not use cached info
-       my $connect_method_info = get_connect_method_info($imagerevision_id, 1);
+       my $connect_method_info = 
get_reservation_connect_method_info($reservation_id, 1);
        
        # Retrieve the ports already assigned to the nathost
        my @assigned_ports = get_nathost_assigned_public_ports($nathost_id);
@@ -7497,7 +7512,7 @@ sub populate_reservation_natport {
        
        # Get the connect method info again to verify all ports are assigned a 
NAT public port
        my $info_string = "";
-       $connect_method_info = get_connect_method_info($imagerevision_id, 1);
+       $connect_method_info = 
get_reservation_connect_method_info($reservation_id, 1);
        for my $connect_method_id (sort keys %$connect_method_info) {
                my $connect_method = $connect_method_info->{$connect_method_id};
                my $connect_method_name = $connect_method->{name};
@@ -10695,12 +10710,11 @@ sub kill_child_processes {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 get_connect_method_info
+=head2 get_reservation_connect_method_info
 
  Parameters  : $imagerevision_id, $no_cache (optional)
  Returns     : hash reference
- Description : Returns the connect methods for the image revision specified as
-               the argument. Example:
+ Description : Returns the connect methods for the reservation. Example:
                {
                 4 => {
                   "RETRIEVAL_TIME" => "1417709281",
@@ -10748,30 +10762,28 @@ sub kill_child_processes {
 
 =cut
 
-sub get_connect_method_info {
-       my ($imagerevision_id, $no_cache) = @_;
-       if (!defined($imagerevision_id)) {
-               notify($ERRORS{'WARNING'}, 0, "imagerevision ID argument was 
not supplied");
+sub get_reservation_connect_method_info {
+       my ($reservation_id, $no_cache) = @_;
+       if (!defined($reservation_id)) {
+               notify($ERRORS{'WARNING'}, 0, "reservation ID argument was not 
supplied");
                return;
        }
        
-       # Check if cached image info exists
-       if (!$no_cache && 
defined($ENV{connect_method_info}{$imagerevision_id})) {
-               my $connect_method_id = 
(keys(%{$ENV{connect_method_info}{$imagerevision_id}}))[0];
+       # Check if cached info exists
+       if (!$no_cache && defined($ENV{connect_method_info}{$reservation_id})) {
+               my $connect_method_id = 
(keys(%{$ENV{connect_method_info}{$reservation_id}}))[0];
                if ($connect_method_id) {
                        # Check the time the info was last retrieved
-                       my $data_age_seconds = (time - 
$ENV{connect_method_info}{$imagerevision_id}{$connect_method_id}{RETRIEVAL_TIME});
+                       my $data_age_seconds = (time - 
$ENV{connect_method_info}{$reservation_id}{$connect_method_id}{RETRIEVAL_TIME});
                        if ($data_age_seconds < 600) {
-                               return 
$ENV{connect_method_info}{$imagerevision_id};
+                               return 
$ENV{connect_method_info}{$reservation_id};
                        }
                        else {
-                               notify($ERRORS{'DEBUG'}, 0, "retrieving current 
connect method info for imagerevision $imagerevision_id from database, cached 
data is stale: $data_age_seconds seconds old");
+                               notify($ERRORS{'DEBUG'}, 0, "retrieving current 
connect method info for reservation $reservation_id from database, cached data 
is stale: $data_age_seconds seconds old");
                        }
                }
        }
        
-       notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve connect method info 
for image revision $imagerevision_id");
-       
        # Get a hash ref containing the database column names
        my $database_table_columns = get_database_table_columns();
        
@@ -10800,26 +10812,25 @@ sub get_connect_method_info {
        $select_statement .= <<EOF;
 FROM
 connectmethod,
-
-connectmethodport
-LEFT JOIN natport ON (natport.connectmethodportid = connectmethodport.id),
-
 connectmethodmap,
 
-imagerevision
-LEFT JOIN image ON (image.id = imagerevision.imageid)
+reservation
+LEFT JOIN image ON (image.id = reservation.imageid)
 LEFT JOIN OS ON (OS.id = image.OSid)
-LEFT JOIN OStype ON (OStype.name = OS.type)
+LEFT JOIN OStype ON (OStype.name = OS.type),
+
+connectmethodport
+LEFT JOIN natport ON (natport.connectmethodportid = connectmethodport.id AND 
natport.reservationid = $reservation_id)
 
 WHERE
-connectmethodport.connectmethodid = connectmethod.id
+reservation.id = $reservation_id
+AND connectmethodport.connectmethodid = connectmethod.id
 AND connectmethodmap.connectmethodid = connectmethod.id
-AND imagerevision.id = $imagerevision_id
 AND connectmethodmap.autoprovisioned IS NULL
 AND (
        connectmethodmap.OStypeid = OStype.id
        OR connectmethodmap.OSid = OS.id 
-       OR connectmethodmap.imagerevisionid = imagerevision.id
+       OR connectmethodmap.imagerevisionid = reservation.imagerevisionid
 )
 
 ORDER BY
@@ -10869,9 +10880,9 @@ EOF
                $connect_method_info->{$connectmethod_id}{RETRIEVAL_TIME} = 
$timestamp;
        }
 
-       #notify($ERRORS{'DEBUG'}, 0, "retrieved connect method info:\n" . 
format_data($connect_method_info));
-       $ENV{connect_method_info}{$imagerevision_id} = $connect_method_info;
-       return $ENV{connect_method_info}{$imagerevision_id};
+       notify($ERRORS{'DEBUG'}, 0, "retrieved connect method info for 
reservation $reservation_id:\n" . format_data($connect_method_info));
+       $ENV{connect_method_info}{$reservation_id} = $connect_method_info;
+       return $ENV{connect_method_info}{$reservation_id};
 }
 
 #/////////////////////////////////////////////////////////////////////////////


Reply via email to