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};
}
#/////////////////////////////////////////////////////////////////////////////