in managementnode/lib/VCL/Module/OS.pm [3753:3891]
sub process_connect_methods {
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 $reservation_id = $self->data->get_reservation_id();
my $request_state = $self->data->get_request_state_name();
my $computer_node_name = $self->data->get_computer_node_name();
my $nathost_hostname = $self->data->get_nathost_hostname(0);
my $nathost_public_ip_address = $self->data->get_nathost_public_ip_address(0);
my $nathost_internal_ip_address = $self->data->get_nathost_internal_ip_address(0);
# Retrieve the connect method info hash
my $connect_method_info = $self->data->get_connect_methods();
if (!$connect_method_info) {
notify($ERRORS{'WARNING'}, 0, "failed to retrieve connect method info");
return;
}
my $remote_ip = shift;
if (!$remote_ip) {
notify($ERRORS{'OK'}, 0, "reservation remote IP address is not defined, connect methods will be available from any IP address");
$remote_ip = '0.0.0.0/0';
}
elsif ($remote_ip =~ /any/i) {
notify($ERRORS{'OK'}, 0, "reservation remote IP address is set to ANY, connect methods will be available from any IP address");
$remote_ip = '0.0.0.0/0';
}
else {
$remote_ip .= "/24";
}
my $overwrite = shift;
if (!$overwrite) {
notify($ERRORS{'DEBUG'}, 0, "overwrite value was not passed as an argument setting to 0");
$overwrite = 0;
}
my $computer_ip_address = $self->get_public_ip_address();
CONNECT_METHOD: for my $connect_method_id (sort keys %{$connect_method_info} ) {
my $connect_method = $connect_method_info->{$connect_method_id};
my $name = $connect_method->{name};
my $description = $connect_method->{description};
my $service_name = $connect_method->{servicename};
my $startup_script = $connect_method->{startupscript};
my $install_script = $connect_method->{installscript};
my $disabled = $connect_method->{connectmethodmap}{disabled};
if ($disabled || $request_state =~ /deleted|timeout/) {
if ($self->service_exists($service_name)) {
if (!$self->stop_service($service_name)) {
notify($ERRORS{'WARNING'}, 0, "failed to stop '$service_name' service for '$name' connect method on $computer_node_name");
}
}
# Close the firewall ports
if ($self->can('disable_firewall_port')) {
for my $connect_method_port_id (keys %{$connect_method->{connectmethodport}}) {
my $protocol = $connect_method->{connectmethodport}{$connect_method_port_id}{protocol};
my $port = $connect_method->{connectmethodport}{$connect_method_port_id}{port};
if (!$self->disable_firewall_port($protocol, $port, $remote_ip, 1)) {
notify($ERRORS{'WARNING'}, 0, "failed to close firewall port $protocol/$port on $computer_node_name for $remote_ip $name connect method");
return;
}
}
}
}
else {
# Attempt to start and configure the connect method
my $service_started = 0;
# Attempt to start the service if the service name has been defined for the connect method
if ($service_name) {
if ($self->service_exists($service_name)) {
if ($self->start_service($service_name)) {
$service_started = 1;
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to start '$service_name' service for '$name' connect method on $computer_node_name");
}
}
else {
notify($ERRORS{'OK'}, 0, "'$service_name' service for '$name' connect method does NOT exist on $computer_node_name, connect method install script is not defined");
}
}
# Run the startup script if the service is not started
if (!$service_started && defined($startup_script)) {
if (!$self->file_exists($startup_script)) {
notify($ERRORS{'OK'}, 0, "'$service_name' service startup script for '$name' connect method does not exist on $computer_node_name: $startup_script");
}
else {
notify($ERRORS{'DEBUG'}, 0, "attempting to run startup script '$startup_script' for '$name' connect method on $computer_node_name");
my ($startup_exit_status, $startup_output) = $self->execute($startup_script, 1);
if (!defined($startup_output)) {
notify($ERRORS{'WARNING'}, 0, "failed to run command to execute startup script '$startup_script' for '$name' connect method on $computer_node_name, command: '$startup_script'");
}
elsif ($startup_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "executed startup script '$startup_script' for '$name' connect method on $computer_node_name, command: '$startup_script', exit status: $startup_exit_status, output:\n" . join("\n", @$startup_output));
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to execute startup script '$startup_script' for '$name' connect method on $computer_node_name, command: '$startup_script', exit status: $startup_exit_status, output:\n" . join("\n", @$startup_output));
}
}
}
for my $connect_method_port_id (keys %{$connect_method->{connectmethodport}}) {
my $protocol = $connect_method->{connectmethodport}{$connect_method_port_id}{protocol};
my $port = $connect_method->{connectmethodport}{$connect_method_port_id}{port};
# Open the firewall port
if ($self->can('enable_firewall_port')) {
if (!$self->enable_firewall_port($protocol, $port, $remote_ip, 1)) {
notify($ERRORS{'WARNING'}, 0, "failed to open firewall port $protocol/$port on $computer_node_name for $remote_ip $name connect method");
}
}
# Configure NAT port forwarding if NAT is being used
if ($nathost_hostname) {
my $nat_public_port = $connect_method->{connectmethodport}{$connect_method_port_id}{natport}{publicport};
if (!defined($nat_public_port)) {
notify($ERRORS{'WARNING'}, 0, "$computer_node_name is assigned to NAT host $nathost_hostname but connect method info does not contain NAT port information:\n" . format_data($connect_method));
return;
}
elsif (!$self->nathost_os->firewall->nat_add_port_forward($protocol, $nat_public_port, $computer_ip_address, $port)) {
notify($ERRORS{'WARNING'}, 0, "failed to configure NAT port forwarding on $nathost_hostname for '$name' connect method: $nathost_public_ip_address:$nat_public_port --> $computer_ip_address:$port ($protocol)");
return;
}
}
}
}
}
return 1;
}