Author: arkurth
Date: Thu Feb  5 20:04:44 2015
New Revision: 1657678

URL: http://svn.apache.org/r1657678
Log:
VCL-174
Added sublog.id column to vcl.sql and update-vcl.sql, which is referenced by 
the natlog table.

Updated natlog table in vcl.sql and update-vcl.sql to reference sublog.id 
instead of containing a computer ID value.

Updated DataStructure.pm to reflect the schema changes.

Added utils.pm::get_request_log_info. This is called from 
DataStructure.pm::get_log_data. I reworked get_log_data because it was only 
retrieving data for a single sublog entry.

Added utils.pm::update_reservation_natlog. This is called from get_request_info 
when the NAT ports are determined.

Added checks to OS.pm::process_connect_methods to ensure that the NAT host 
firewall object implements the 'configure_nat' and 'configure_nat_reservation' 
subroutines before attempting to call them.

Modified:
    vcl/trunk/managementnode/lib/VCL/DataStructure.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    vcl/trunk/managementnode/lib/VCL/utils.pm
    vcl/trunk/mysql/update-vcl.sql
    vcl/trunk/mysql/vcl.sql

Modified: vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=1657678&r1=1657677&r2=1657678&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/DataStructure.pm Thu Feb  5 20:04:44 2015
@@ -167,12 +167,7 @@ $SUBROUTINE_MAPPINGS{log_remote_ip} = '$
 $SUBROUTINE_MAPPINGS{log_imageid} = '$self->request_data->{log}{imageid}';
 $SUBROUTINE_MAPPINGS{log_size} = '$self->request_data->{log}{size}';
 
-$SUBROUTINE_MAPPINGS{sublog_imageid} = '$self->request_data->{log}{imageid}';
-$SUBROUTINE_MAPPINGS{sublog_imagerevisionid} = 
'$self->request_data->{log}{imagerevisionid}';
-$SUBROUTINE_MAPPINGS{sublog_computerid} = 
'$self->request_data->{log}{computerid}';
-$SUBROUTINE_MAPPINGS{sublog_ip_address} = 
'$self->request_data->{log}{IPaddress}';
-$SUBROUTINE_MAPPINGS{sublog_managementnodeid} = 
'$self->request_data->{log}{managementnodeid}';
-$SUBROUTINE_MAPPINGS{sublog_predictivemoduleid} = 
'$self->request_data->{log}{predictivemoduleid}';
+$SUBROUTINE_MAPPINGS{sublog_id} = 
'$self->request_data->{reservation}{RESERVATION_ID}{SUBLOG_ID}';
 
 #$SUBROUTINE_MAPPINGS{request_reservationid} = 
'$self->request_data->{RESERVATIONID}';
 $SUBROUTINE_MAPPINGS{reservation_id} = '$self->request_data->{RESERVATIONID}';
@@ -852,7 +847,11 @@ sub _automethod : Automethod {
                        
                        if ($self->get_log_data()) {
                                # Log data was retrieved, check if requested 
data is now populated
-                               if (!eval "defined $hash_path") {
+                               if (eval "defined $hash_path") {
+                                       $return_value = eval $hash_path;
+                                       notify($ERRORS{'DEBUG'}, 0, "log data 
was retrieved and corresponding data has been initialized for $method_name: 
$return_value");
+                               }
+                               else {
                                        notify($ERRORS{'WARNING'}, 0, "log data 
was retrieved but corresponding data has not been initialized for $method_name: 
$hash_path", $self->request_data) if $show_warnings;
                                        return sub { };
                                }
@@ -1398,88 +1397,73 @@ sub print_subroutines {
 
 =head2 get_log_data
 
- Parameters  : log ID (optional)
+ Parameters  : none
  Returns     : hash reference
  Description : Retrieves data from the log and sublog tables for the log ID
                either specified via an argument or the log ID for the
-                                       reservation represented by the 
DataStructure object.
+               reservation represented by the DataStructure object.
 
 =cut
 
 sub get_log_data {
-       my $self;
-       my $argument = shift;
-       my $request_log_id;
-       
-       # Check if subroutine was called as an object method
-       if (ref($argument) =~ /DataStructure/) {
-               # Subroutine was called as an object method, get next argument
-               $self = $argument;
-               $argument = shift;
-               
-               # If argument wasn't passed, attempt to get the log id from 
this DataStructure object
-               if (!$argument) {
-                       # Get the log id and make sure it is set
-                       $request_log_id = $self->get_request_log_id();
-                       if (!$request_log_id) {
-                               notify($ERRORS{'WARNING'}, 0, "log id was not 
passed as an argument and could not be retrieved from the existing 
DataStructure object");
-                               return;
-                       }
+       my $self = shift;
+       unless (ref($self) && $self->isa('VCL::DataStructure')) {
+               notify($ERRORS{'WARNING'}, 0, "subroutine can only be called as 
a VCL::DataStructure module object method");
+               return;
+       }
+       
+       my $current_reservation_id = $self->get_reservation_id();
+       my $request_id = $self->get_request_id();
+       my @reservation_ids = $self->get_reservation_ids();
+       
+       # Retrieve log info for all reservations
+       my $log_info = get_request_log_info($request_id) || return;
+       
+       $self->request_data->{log} = $log_info;
+       
+       # Get a mapping between computer to reservation IDs
+       # TODO: add sublog.reservationid column, this will no longer be 
necessary
+       my $computer_reservation_ids = {};
+       for my $reservation_id (@reservation_ids) {
+               my $reservation_data;
+               if ($reservation_id eq $current_reservation_id) {
+                       $reservation_data = $self;
                }
                else {
-                       $request_log_id = $argument;
+                       $reservation_data = 
$self->get_reservation_data($reservation_id);
+               }       
+               if (!$reservation_data) {
+                       notify($ERRORS{'WARNING'}, 0, "DataStructure object 
could not be retrieved for reservation $reservation_id");
+                       next;
                }
-       }
-       else {
-               $request_log_id = $argument;
                
-               # Make sure log id was determined and is valid
-               if (!$request_log_id) {
-                       notify($ERRORS{'WARNING'}, 0, "log id was not passed as 
an argument and subroutine was not called as an object method");
-                       return;
+               my $reservation_computer_id = 
$reservation_data->get_computer_id();
+               if (!$reservation_computer_id) {
+                       notify($ERRORS{'WARNING'}, 0, "computer ID could not be 
determined for reservation $reservation_id");
+                       next;
                }
+               
+               $computer_reservation_ids->{$reservation_computer_id} = 
$reservation_id;
        }
        
-       # Make sure log id was determined and is valid
-       if (!$request_log_id) {
-               notify($ERRORS{'WARNING'}, 0, "log id could not be determined");
-               return;
-       }
-       elsif ($request_log_id !~ /^\d+$/) {
-               notify($ERRORS{'WARNING'}, 0, "log id is not valid: 
$request_log_id");
-               return;
-       }
-       
-       # Construct a select statement 
-       my $sql_select_statement = "
-       SELECT
-       *
-       FROM
-       log
-       LEFT JOIN sublog ON sublog.logid = log.id
-       WHERE
-       log.id = $request_log_id
-       ";
-       
-       # Call database_select() to execute the select statement and make sure 
1 row was returned
-       my @select_rows = VCL::utils::database_select($sql_select_statement);
-       if (!scalar @select_rows == 1) {
-               notify($ERRORS{'WARNING'}, 0, "select statement returned " . 
scalar @select_rows . " rows:\n" . join("\n", $sql_select_statement));
-               return;
-       }
-       
-       # $select_rows[0] is a hash reference, the keys are the column names
-       # Loop through the column names and add the data to $self->request_data
-       my $row = $select_rows[0];
-       
-       my %data_hash;
-       foreach my $column_name (sort keys(%{$row})) {
-               # Get the data value for the column
-               my $data_value = $row->{$column_name};
-               $self->request_data->{log}{$column_name} = $data_value if 
!defined($self->request_data->{log}{$column_name});
+       for my $sublog_id (keys %{$log_info->{sublog}}) {
+               my $sublog_computer_id = 
$log_info->{sublog}{$sublog_id}{computerid};
+               if (!$sublog_computer_id) {
+                       notify($ERRORS{'WARNING'}, 0, "computer ID is not 
defined for sublog $sublog_id:\n" . format_data($log_info));
+                       next;
+               }
+               
+               my $reservation_id = 
$computer_reservation_ids->{$sublog_computer_id};
+               if (!$reservation_id) {
+                       notify($ERRORS{'WARNING'}, 0, "computer ID is set to 
$sublog_computer_id for sublog ID $sublog_id, no reservation assigned to this 
request is assigned that computer ID");
+                       next;
+               }
+               
+               $self->request_data->{reservation}{$reservation_id}{SUBLOG_ID} 
= $sublog_id;
+               $self->request_data->{reservation}{$reservation_id}{sublog} = 
$log_info->{sublog}{$sublog_id};
        }
        
-       notify($ERRORS{'DEBUG'}, 0, "retrieved log data for log id: 
$request_log_id");
+       notify($ERRORS{'DEBUG'}, 0, "updated DataStructure object with log and 
sublog data");
        return $self->request_data->{log};
 }
 

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1657678&r1=1657677&r2=1657678&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Thu Feb  5 20:04:44 2015
@@ -2852,14 +2852,26 @@ sub process_connect_methods {
                }
                
                # Perform general NAT configuration
-               if (!$self->nathost_os->firewall->configure_nat()) {
-                       notify($ERRORS{'WARNING'}, 0, "unable to process 
connect methods, failed to configure NAT on $nathost_hostname");
+               if ($self->nathost_os->firewall->can('configure_nat')) {
+                       if (!$self->nathost_os->firewall->configure_nat()) {
+                               notify($ERRORS{'WARNING'}, 0, "unable to 
process connect methods, failed to configure NAT on $nathost_hostname");
+                               return;
+                       }
+               }
+               else {
+                       notify($ERRORS{'CRITICAL'}, 0, "NAT not configured on 
$nathost_hostname, " . ref($self->nathost_os->firewall) . " does not implement 
a 'configure_nat' subroutine");
                        return;
                }
                
                # Perform reservation-specific NAT configuration
-               if (!$self->nathost_os->firewall->configure_nat_reservation()) {
-                       notify($ERRORS{'WARNING'}, 0, "unable to process 
connect methods, failed to configure NAT on $nathost_hostname for this 
reservation");
+               if 
($self->nathost_os->firewall->can('configure_nat_reservation')) {
+                       if 
(!$self->nathost_os->firewall->configure_nat_reservation()) {
+                               notify($ERRORS{'WARNING'}, 0, "unable to 
process connect methods, failed to configure NAT on $nathost_hostname for this 
reservation");
+                               return;
+                       }
+               }
+               else {
+                       notify($ERRORS{'CRITICAL'}, 0, "NAT not configured on 
$nathost_hostname for this reservation, " . ref($self->nathost_os->firewall) . 
" does not implement a 'configure_nat_reservation' subroutine");
                        return;
                }
        }
@@ -3897,7 +3909,7 @@ sub update_cluster {
                        push(@cluster_string, "child= 
$request_data->{reservation}{$rid}{computer}{IPaddress}" . "\n");
                        notify($ERRORS{'DEBUG'}, 0, "writing child=  
$request_data->{reservation}{$rid}{computer}{IPaddress}");
                }
-
+               
                #Create iptables rule for each node in cluster on the node 
being processed
                # Could slow things down for large clusters, but they can 
communicate with each other
                if ($self->can('enable_firewall_port')) {

Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1657678&r1=1657677&r2=1657678&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Thu Feb  5 20:04:44 2015
@@ -173,6 +173,7 @@ our @EXPORT = qw(
        get_request_current_state_name
        get_request_end
        get_request_info
+       get_request_log_info
        get_reservation_accounts
        get_reservation_computerloadlog_entries
        get_reservation_computerloadlog_time
@@ -272,6 +273,7 @@ our @EXPORT = qw(
        update_request_checkuser
        update_request_state
        update_reservation_lastcheck
+       update_reservation_natlog
        update_reservation_password
        update_sublog_ipaddress
        xml_string_to_hash
@@ -3093,11 +3095,14 @@ EOF
                                if 
(!populate_reservation_natport($reservation_id)) {
                                        notify($ERRORS{'CRITICAL'}, 0, "failed 
to populate natport table for reservation");
                                }
+                               if 
(!update_reservation_natlog($reservation_id)) {
+                                       notify($ERRORS{'CRITICAL'}, 0, "failed 
to populate natlog table for reservation");
+                               }
                        }
                }
                
                # Add the connect method info to the hash
-               my $connect_method_info = 
get_connect_method_info($imagerevision_id, $no_cache);
+               my $connect_method_info = 
get_connect_method_info($imagerevision_id, 0);
                $request_info->{reservation}{$reservation_id}{connect_methods} 
= $connect_method_info;
                
                # Add the managementnode info to the hash
@@ -3177,6 +3182,133 @@ EOF
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2  get_request_log_info
+
+ Parameters  : $request_id, $no_cache (optional)
+ Returns     : hash reference
+ Description : Retrieves data from the log and sublog tables for the request.
+               A hash is constructed. Example:
+               {
+                 "computerid" => 3588,
+                 "ending" => "none",
+                 "finalend" => "0000-00-00 00:00:00",
+                 "id" => 5354,
+                 ...
+                 "sublog" => {
+                   74 => {
+                     "IPaddress" => undef,
+                     "blockEnd" => undef,
+                     "blockRequestid" => undef,
+                     "blockStart" => undef,
+                     "computerid" => 3588,
+                     "hostcomputerid" => undef,
+                     "id" => 74,
+                     "imageid" => 3081,
+                     "imagerevisionid" => 9147,
+                     "logid" => 5354,
+                     "managementnodeid" => 8,
+                     "predictivemoduleid" => 8
+                   },
+                   75 => {
+                     "IPaddress" => undef,
+                     ...
+                   },
+                 },
+                 "userid" => 2870,
+                 "wasavailable" => 0
+               }
+
+=cut
+
+sub get_request_log_info {
+       my ($request_id, $no_cache) = @_;
+       if (!defined($request_id)) {
+               notify($ERRORS{'WARNING'}, 0, "request ID argument was not 
specified");
+               return;
+       }
+       
+       if (!$no_cache && defined($ENV{log_info}{$request_id})) {
+               return $ENV{log_info}{$request_id};
+       }
+       
+       # Get a hash ref containing the database column names
+       my $database_table_columns = get_database_table_columns();
+       
+       my %tables = (
+               'log' => 'log',
+               'sublog' => 'sublog',
+       );
+       
+       # Construct the select statement
+       my $select_statement = "SELECT DISTINCT\n";
+       
+       # Get the column names for each table and add them to the select 
statement
+       for my $table_alias (keys %tables) {
+               my $table_name = $tables{$table_alias};
+               my @columns = @{$database_table_columns->{$table_name}};
+               for my $column (@columns) {
+                       $select_statement .= "$table_alias.$column AS 
'$table_alias-$column',\n";
+               }
+       }
+       
+       # Remove the comma after the last column line
+       $select_statement =~ s/,$//;
+       
+       # Complete the select statement
+       $select_statement .= <<EOF;
+FROM
+request,
+log,
+sublog
+WHERE
+request.id = $request_id
+AND log.id = request.logid
+AND sublog.logid = log.id
+EOF
+
+       # Call the database select subroutine
+       my @rows = database_select($select_statement);
+       if (!@rows) {
+               notify($ERRORS{'WARNING'}, 0, "log info for request $request_id 
could not be retrieved from the database, select 
statement:\n$select_statement");
+               return;
+       }
+
+       # Build the hash
+       my $log_info;
+
+       for my $row (@rows) {
+               my $sublog_id = $row->{'sublog-id'};
+               if (!$sublog_id) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to retrieve log 
info for request $request_id, row does not contain a 'sublog-id' value:\n" . 
format_data($row));
+                       return;
+               }
+               
+               # Loop through all the columns returned
+               for my $key (keys %$row) {
+                       my $value = $row->{$key};
+                       
+                       # Split the table-column names
+                       my ($table, $column) = $key =~ /^([^-]+)-(.+)/;
+                       
+                       if ($table eq 'log') {
+                               $log_info->{$column} = $value;
+                       }
+                       elsif ($table eq 'sublog') {
+                               $log_info->{$table}{$sublog_id}{$column} = 
$value;
+                       }
+                       else {
+                               $log_info->{$table}{$column} = $value;
+                       }
+               }
+       }
+       
+       $ENV{log_info}{$request_id} = $log_info;
+       #notify($ERRORS{'DEBUG'}, 0, "retrieved log info for request 
$request_id:\n" . format_data($log_info));
+       return $log_info;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 set_managementnode_state
 
  Parameters  : management node info, state
@@ -7548,6 +7680,76 @@ EOF
                return 0;
        }
 }
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 update_reservation_natlog
+
+ Parameters  : $reservation_id
+ Returns     : boolean
+ Description : Adds or updates an entry in the natlog table.
+
+=cut
+
+sub update_reservation_natlog {
+       my ($reservation_id) = @_;
+       if (!defined($reservation_id)) {
+               notify($ERRORS{'WARNING'}, 0, "reservation ID argument was not 
supplied");
+               return;
+       }
+       
+       my $insert_statement = <<EOF;
+INSERT IGNORE INTO
+natlog
+(
+   sublogid,
+   nathostresourceid,
+   publicIPaddress,
+   publicport,
+       internalIPaddress,
+   internalport,
+   protocol,
+   timestamp
+)
+(
+SELECT
+   sublog.id,
+   nathost.resourceid,
+   nathost.publicIPaddress,
+   natport.publicport,
+       nathost.internalIPaddress,
+   connectmethodport.port AS internalport,
+   connectmethodport.protocol,
+   NOW()
+   FROM
+   request,
+   reservation,
+   sublog,
+   natport,
+   nathost,
+   connectmethodport
+   WHERE
+   reservation.id = $reservation_id
+   AND reservation.requestid = request.id
+   AND request.logid = sublog.logid
+   AND sublog.computerid = reservation.computerid
+   AND natport.reservationid = reservation.id
+   AND natport.nathostid = nathost.id
+   AND natport.connectmethodportid = connectmethodport.id
+)
+ON DUPLICATE KEY UPDATE
+timestamp=VALUES(timestamp)
+EOF
+
+       if (database_execute($insert_statement)) {
+               notify($ERRORS{'DEBUG'}, 0, "updated natlog table for 
reservation $reservation_id");
+               return 1;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to update natlog table 
for reservation $reservation_id");
+               return 0;
+       }
+}
 
 #/////////////////////////////////////////////////////////////////////////////
 

Modified: vcl/trunk/mysql/update-vcl.sql
URL: 
http://svn.apache.org/viewvc/vcl/trunk/mysql/update-vcl.sql?rev=1657678&r1=1657677&r2=1657678&view=diff
==============================================================================
--- vcl/trunk/mysql/update-vcl.sql (original)
+++ vcl/trunk/mysql/update-vcl.sql Thu Feb  5 20:04:44 2015
@@ -87,6 +87,7 @@ BEGIN
   )
   THEN
     SET @statement_array = CONCAT('ALTER TABLE `', Database(), '`.', 
tableName, ' ADD COLUMN ', columnName, ' ', columnDefinition);
+    -- CALL PrintMessage((SELECT CONCAT('adding column: ', @statement_array)));
     PREPARE statement_string FROM @statement_array;
     EXECUTE statement_string;
   END IF;
@@ -1058,15 +1059,18 @@ CREATE TABLE IF NOT EXISTS `nathost` (
 -- 
 
 CREATE TABLE IF NOT EXISTS `natlog` (
-  `logid` int(10) unsigned NOT NULL,
-  `computerid` smallint(5) unsigned NOT NULL,
+  `sublogid` int(10) unsigned NOT NULL,
+  `nathostresourceid` mediumint(8) unsigned NOT NULL,
   `publicIPaddress` varchar(15) NOT NULL,
-  `internalIPaddress` varchar(15) NOT NULL,
   `publicport` smallint(5) unsigned NOT NULL,
+  `internalIPaddress` varchar(15) NOT NULL,
   `internalport` smallint(5) unsigned NOT NULL,
-  `protocol` enum('TCP','UDP') NOT NULL,
-  KEY `logid` (`logid`),
-  KEY `computerid` (`computerid`)
+  `protocol` enum('TCP','UDP') NOT NULL DEFAULT 'TCP',
+  `timestamp` datetime NOT NULL,
+  UNIQUE KEY `sublogid` 
(`sublogid`,`nathostresourceid`,`publicIPaddress`,`publicport`,`internalIPaddress`,`internalport`,`protocol`),
+  KEY `logid` (`sublogid`),
+  KEY `nathostid` (`nathostresourceid`),
+  KEY `nathostresourceid` (`nathostresourceid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
@@ -1278,6 +1282,7 @@ CALL AddIndexIfNotExists('statgraphcache
 -- Table structure change for table `sublog`
 --
 
+CALL AddColumnIfNotExists('sublog', 'id', "int(10) unsigned NOT NULL 
AUTO_INCREMENT PRIMARY KEY FIRST");
 CALL AddColumnIfNotExists('sublog', 'hostcomputerid', "smallint(5) unsigned 
default NULL");
 CALL AddColumnIfNotExists('sublog', 'blockRequestid', "mediumint(8) unsigned 
NOT NULL");
 CALL AddColumnIfNotExists('sublog', 'blockStart', "datetime NOT NULL");
@@ -2045,8 +2050,8 @@ CALL AddConstraintIfNotExists('nathost',
 -- Constraints for table `natlog`
 --
 
-CALL AddConstraintIfNotExists('natlog', 'computerid', 'computer', 'id', 
'both', 'CASCADE');
-CALL AddConstraintIfNotExists('natlog', 'logid', 'log', 'id', 'both', 
'CASCADE');
+CALL AddConstraintIfNotExists('natlog', 'sublogid', 'sublog', 'id', 'both', 
'CASCADE');
+CALL AddConstraintIfNotExists('natlog', 'nathostresourceid', 'resource', 'id', 
'update', 'CASCADE');
 
 -- --------------------------------------------------------
 

Modified: vcl/trunk/mysql/vcl.sql
URL: 
http://svn.apache.org/viewvc/vcl/trunk/mysql/vcl.sql?rev=1657678&r1=1657677&r2=1657678&view=diff
==============================================================================
--- vcl/trunk/mysql/vcl.sql (original)
+++ vcl/trunk/mysql/vcl.sql Thu Feb  5 20:04:44 2015
@@ -675,15 +675,18 @@ CREATE TABLE IF NOT EXISTS `nathost` (
 -- 
 
 CREATE TABLE IF NOT EXISTS `natlog` (
-  `logid` int(10) unsigned NOT NULL,
-  `computerid` smallint(5) unsigned NOT NULL,
+  `sublogid` int(10) unsigned NOT NULL,
+  `nathostresourceid` mediumint(8) unsigned NOT NULL,
   `publicIPaddress` varchar(15) NOT NULL,
-  `internalIPaddress` varchar(15) NOT NULL,
   `publicport` smallint(5) unsigned NOT NULL,
+  `internalIPaddress` varchar(15) NOT NULL,
   `internalport` smallint(5) unsigned NOT NULL,
-  `protocol` enum('TCP','UDP') NOT NULL,
-  KEY `logid` (`logid`),
-  KEY `computerid` (`computerid`)
+  `protocol` enum('TCP','UDP') NOT NULL DEFAULT 'TCP',
+  `timestamp` datetime NOT NULL,
+  UNIQUE KEY `sublogid` 
(`sublogid`,`nathostresourceid`,`publicIPaddress`,`publicport`,`internalIPaddress`,`internalport`,`protocol`),
+  KEY `logid` (`sublogid`),
+  KEY `nathostid` (`nathostresourceid`),
+  KEY `nathostresourceid` (`nathostresourceid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
@@ -1205,6 +1208,7 @@ CREATE TABLE IF NOT EXISTS `subimages` (
 -- 
 
 CREATE TABLE IF NOT EXISTS `sublog` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `logid` int(10) unsigned NOT NULL default '0',
   `imageid` smallint(5) unsigned NOT NULL default '0',
   `imagerevisionid` mediumint(8) unsigned NOT NULL,
@@ -1216,6 +1220,7 @@ CREATE TABLE IF NOT EXISTS `sublog` (
   `blockRequestid` mediumint(8) unsigned NOT NULL,
   `blockStart` datetime NOT NULL,
   `blockEnd` datetime NOT NULL,
+  PRIMARY KEY (`id`),
   KEY `logid` (`logid`),
   KEY `imageid` (`imageid`),
   KEY `imagerevisionid` (`imagerevisionid`),
@@ -2305,9 +2310,9 @@ ALTER TABLE `nathost` ADD CONSTRAINT FOR
 -- 
 -- Constraints for table `natlog`
 --
-ALTER TABLE `natlog` ADD CONSTRAINT FOREIGN KEY (`logid`) REFERENCES `log` 
(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-ALTER TABLE `natlog` ADD CONSTRAINT FOREIGN KEY (`computerid`) REFERENCES 
`computer` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-
+ALTER TABLE `natlog` ADD CONSTRAINT FOREIGN KEY (`sublogid`) REFERENCES 
`sublog` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
+ALTER TABLE `natlog` ADD CONSTRAINT FOREIGN KEY (`nathostresourceid`) 
REFERENCES `resource` (`id`) ON UPDATE CASCADE;
+  
 -- 
 -- Constraints for table `nathostcomputermap`
 -- 


Reply via email to