You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2014/12/18 15:20:52 UTC

svn commit: r1646463 - in /vcl/trunk/web: .ht-inc/computer.php .ht-inc/utils.php js/resources/computer.js

Author: jfthomps
Date: Thu Dec 18 14:20:51 2014
New Revision: 1646463

URL: http://svn.apache.org/r1646463
Log:
VCL-174 - NAT - support for sites that have small IP address ranges

added section to add/edit computer to configure settings for using as NAT host

computer.php:
-modified addEditDialogHTML: added form elements to configure settings for using as NAT host
-modified AJsaveResource: added queries for handling nathost entries
-modified validateResourceData: modified query that checks for reservations for node when modifying connect with NAT data to ignore reload reservations; added nathostenabled, natpublicIpaddress, and natinternalIPaddress; added check for reservations for nodes using this node as a NAT host, disallow changes to NAT host info if there are reservations
-modified addResource: when adding a single computer, include insert into nathost table if configured to be NAT host

utils.php: modified getComputers: added nathostenabled, natpublicIPaddress, and natinternalIPaddress

computer.js:
-modified addNewResource: set 'mode' to 'single' when opening dialog; added disabling natpublicipaddress and natinternalipaddress
-modified toggleAddSingle: remove 'hidden' from 'nathost' div
-modified toggleAddMultiple: add 'hidden' to 'nathost' div
-modified toggleNAT: if natenabled and nathostenabled, uncheck nathostenabled
-added toggleNAThost
-modified inlineEditResourceCB: added setting nathostenabled, natpublicipaddress, and natinternalipaddress
-modified resetEditResource: added natpublicipaddress and natinternalipaddress
-modified saveResource: added natpublicipaddress and natinternalipaddress; added check for both using nat and being nat host being selected

Modified:
    vcl/trunk/web/.ht-inc/computer.php
    vcl/trunk/web/.ht-inc/utils.php
    vcl/trunk/web/js/resources/computer.js

Modified: vcl/trunk/web/.ht-inc/computer.php
URL: http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/computer.php?rev=1646463&r1=1646462&r2=1646463&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/computer.php (original)
+++ vcl/trunk/web/.ht-inc/computer.php Thu Dec 18 14:20:51 2014
@@ -684,11 +684,24 @@ class Computer extends Resource {
 		# use NAT
 		$extra = array('onChange' => "toggleNAT('natenabled', 'nathostid');");
 		$h .= labeledFormItem('natenabled', 'Connect Using NAT', 'check', '', '', '1', '', '', $extra);
-		# NAT host
+		# which NAT host
 		$nathosts = getNAThosts(0, 1);
 		$h .= labeledFormItem('nathostid', 'NAT Host', 'select', $nathosts);
 		$h .= "</div>\n"; # NAT
 
+		# NAT Host
+		$h .= "<div id=\"nathost\" class=\"boxedoptions\">\n";
+		# use as NAT host
+		$extra = array('onChange' => "toggleNAThost();");
+		$h .= labeledFormItem('nathostenabled', 'Use as NAT Host', 'check', '', '', '1', '', '', $extra);
+		# public IP
+		$errmsg = "Invalid NAT Public IP address specified - must be a valid IPV4 address";
+		$h .= labeledFormItem('natpublicipaddress', 'NAT Public IP Address', 'text', $ipreg1, 1, '', $errmsg); 
+		# internal IP
+		$errmsg = "Invalid NAT Internal IP address specified - must be a valid IPV4 address";
+		$h .= labeledFormItem('natinternalipaddress', 'NAT Internal IP Address', 'text', $ipreg1, 1, '', $errmsg); 
+		$h .= "</div>\n"; # NAT Host
+
 		# compid
 		$h .= "<div id=\"compidspan\">\n";
 		$h .= "<label for=\"compid\">Computer ID:</label>\n";
@@ -843,7 +856,7 @@ class Computer extends Resource {
 					$updates[] = "eth1macaddress = '{$data['eth1macaddress']}'";
 			}
 
-			# NAT
+			# use NAT
 			if($data['natenabled'] != $olddata['natenabled']) {
 				if($data['natenabled']) {
 					$query = "INSERT INTO nathostcomputermap "
@@ -867,6 +880,38 @@ class Computer extends Resource {
 				doQuery($query);
 			}
 
+			# NAT host
+			if($data['nathostenabled'] != $olddata['nathostenabled']) {
+				if($data['nathostenabled']) {
+					$query = "INSERT INTO nathost "
+					       .       "(resourceid, "
+					       .       "publicIPaddress, "
+					       .       "internalIPaddress) "
+					       . "VALUES "
+					       .       "({$olddata['resourceid']}, "
+					       .       "'{$data['natpublicIPaddress']}', "
+					       .       "'{$data['natinternalIPaddress']}') "
+					       . "ON DUPLICATE KEY UPDATE "
+					       . "publicIPaddress = '{$data['natpublicIPaddress']}', "
+					       . "internalIPaddress = '{$data['natinternalIPaddress']}'";
+					doQuery($query);
+				}
+				else {
+					$query = "DELETE FROM nathost "
+					       . "WHERE resourceid = {$olddata['resourceid']}";
+					doQuery($query);
+				}
+			}
+			elseif($data['nathostenabled'] &&
+			       ($olddata['natpublicIPaddress'] != $data['natpublicIPaddress'] ||
+					 $olddata['natinternalIPaddress'] != $data['natinternalIPaddress'])) {
+				$query = "UPDATE nathost "
+				       . "SET publicIPaddress = '{$data['natpublicIPaddress']}', "
+				       .     "internalIPaddress = '{$data['natinternalIPaddress']}' "
+				       . "WHERE resourceid = {$olddata['resourceid']}";
+				doQuery($query);
+			}
+
 			# other fields
 			$fields = array('type', 'IPaddress', 'privateIPaddress',
 			                'provisioningid', 'platformid', 'scheduleid', 'ram',
@@ -1639,6 +1684,9 @@ class Computer extends Resource {
 		$return['predictivemoduleid'] = processInputVar('predictivemoduleid', ARG_NUMERIC);
 		$return['natenabled'] = processInputVar('natenabled', ARG_NUMERIC);
 		$return['nathostid'] = processInputVar('nathostid', ARG_NUMERIC);
+		$return['nathostenabled'] = processInputVar('nathostenabled', ARG_NUMERIC);
+		$return['natpublicIPaddress'] = processInputVar('natpublicipaddress', ARG_STRING);
+		$return['natinternalIPaddress'] = processInputVar('natinternalipaddress', ARG_STRING);
 		$return['location'] = processInputVar('location', ARG_STRING);
 		$addmode = processInputVar('addmode', ARG_STRING);
 
@@ -1946,6 +1994,7 @@ class Computer extends Resource {
 			$naterror = 1;
 		}
 		# nat change - check for active reservations
+		$vclreloadid = getUserlistID('vclreload@Local');
 		if($return['mode'] == 'edit') {
 			if($olddata['nathostid'] == '')
 				$olddata['nathostid'] = 0;
@@ -1958,7 +2007,8 @@ class Computer extends Resource {
 				       .       "rs.computerid = {$return['rscid']} AND "
 				       .       "rq.start <= NOW() AND "
 				       .       "rq.end > NOW() AND "
-				       .       "rq.stateid NOT IN (1,5,11,12)";
+				       .       "rq.stateid NOT IN (1,5,11,12) AND "
+				       .       "rq.userid != $vclreloadid";
 				$qh = doQuery($query);
 				if(mysql_num_rows($qh)) {
 					$return['error'] = 1;
@@ -1966,6 +2016,55 @@ class Computer extends Resource {
 				}
 			}
 		}
+		$nathosterror = 0;
+		# nathostenabled
+		if($return['nathostenabled'] != 0 && $return['nathostenabled'] != 1) {
+			$return['error'] = 1;
+			$errormsg[] = "Invalid value for Use as NAT Host";
+			$nathosterror = 1;
+		}
+		# natpublicIPaddress
+		if($return['mode'] == 'edit' || $addmode == 'single') {
+			if(! validateIPv4addr($return['natpublicIPaddress'])) {
+				$return['error'] = 1;
+				$errormsg[] = "Invalid NAT Public IP address. Must be w.x.y.z with each of "
+			               . "w, x, y, and z being between 1 and 255 (inclusive)";
+				$nathosterror = 1;
+			}
+			# natinternalIPaddress
+			if(! validateIPv4addr($return['natinternalIPaddress'])) {
+				$return['error'] = 1;
+				$errormsg[] = "Invalid NAT Internal IP address. Must be w.x.y.z with each of "
+			               . "w, x, y, and z being between 1 and 255 (inclusive)";
+				$nathosterror = 1;
+			}
+		}
+		# nat host change - check for active reservations
+		if(! $nathosterror && $return['mode'] == 'edit') {
+			if($olddata['nathostenabled'] != $return['nathostenabled'] ||
+			   $olddata['natpublicIPaddress'] != $return['natpublicIPaddress'] ||
+				$olddata['natinternalIPaddress'] != $return['natinternalIPaddress']) {
+				$query = "SELECT rq.id "
+				       . "FROM request rq, "
+				       .      "reservation rs, "
+				       .      "nathostcomputermap nhcm, "
+				       .      "nathost nh, "
+				       .      "resource r "
+				       . "WHERE rs.requestid = rq.id AND "
+				       .       "rs.computerid = nhcm.computerid AND "
+				       .       "nhcm.nathostid = nh.id AND "
+				       .       "nh.resourceid = {$olddata['resourceid']} AND "
+				       .       "rq.start <= NOW() AND "
+				       .       "rq.end > NOW() AND "
+				       .       "rq.stateid NOT IN (1,5,11,12) AND "
+				       .       "rq.userid != $vclreloadid";
+				$qh = doQuery($query);
+				if(mysql_num_rows($qh)) {
+					$return['error'] = 1;
+					$errormsg[] = "This computer is the NAT host for other computers that have active reservations. NAT host<br>settings cannot be changed while providing NAT for active reservations.";
+				}
+			}
+		}
 		# location
 		if(! preg_match('/^([-a-zA-Z0-9_\. ,@#\(\)]{0,255})$/', $return['location'])) {
 			$return['error'] = 1;
@@ -2138,7 +2237,7 @@ class Computer extends Resource {
 				       .        "{$data['nathostid']})";
 				doQuery($query);
 			}
-		
+
 			// add entry in resource table
 			$query = "INSERT INTO resource "
 					 .        "(resourcetypeid, "
@@ -2147,6 +2246,21 @@ class Computer extends Resource {
 					 .         "$rscid)";
 			doQuery($query);
 
+			$resourceid = dbLastInsertID();
+
+			# NAT host
+			if($data['nathostenabled']) {
+				$query = "INSERT INTO nathost "
+				       .       "(resourceid, "
+				       .       "publicIPaddress, "
+				       .       "internalIPaddress) "
+				       . "VALUES "
+				       .       "($resourceid, "
+				       .       "'{$data['natpublicIPaddress']}', "
+				       .       "'{$data['natinternalIPaddress']}')";
+				doQuery($query);
+			}
+
 			return $rscid;
 		}
 		else {

Modified: vcl/trunk/web/.ht-inc/utils.php
URL: http://svn.apache.org/viewvc/vcl/trunk/web/.ht-inc/utils.php?rev=1646463&r1=1646462&r2=1646463&view=diff
==============================================================================
--- vcl/trunk/web/.ht-inc/utils.php (original)
+++ vcl/trunk/web/.ht-inc/utils.php Thu Dec 18 14:20:51 2014
@@ -8214,17 +8214,19 @@ function getComputers($sort=0, $included
 	       .        "vh2.vmprofileid, "
 	       .        "c.predictivemoduleid, "
 	       .        "m.prettyname AS predictivemodule, "
-	       .        "nh.id AS nathostid "
+	       .        "nh.id AS nathostid, "
+	       .        "nh2.publicIPaddress AS natpublicIPaddress, "
+	       .        "COALESCE(nh2.internalIPaddress, '') AS natinternalIPaddress "
 	       . "FROM state st, "
 	       .      "platform p, "
 	       .      "schedule sc, "
 	       .      "image cur, "
-	       .      "resource r, "
-	       .      "resourcetype t, "
 	       .      "user u, "
 	       .      "affiliation a, "
 	       .      "module m, "
 	       .      "computer c "
+	       . "LEFT JOIN resourcetype t ON (t.name = 'computer') "
+	       . "LEFT JOIN resource r ON (r.resourcetypeid = t.id AND r.subid = c.id) "
 	       . "LEFT JOIN vmhost vh ON (c.vmhostid = vh.id) "
 	       . "LEFT JOIN vmhost vh2 ON (c.id = vh2.computerid) "
 	       . "LEFT JOIN computer c2 ON (c2.id = vh.computerid) "
@@ -8232,13 +8234,11 @@ function getComputers($sort=0, $included
 	       . "LEFT JOIN provisioning pr ON (c.provisioningid = pr.id) "
 	       . "LEFT JOIN nathostcomputermap nm ON (nm.computerid = c.id) "
 	       . "LEFT JOIN nathost nh ON (nm.nathostid = nh.id) "
+	       . "LEFT JOIN nathost nh2 ON (r.id = nh2.resourceid) "
 	       . "WHERE c.stateid = st.id AND "
 	       .       "c.platformid = p.id AND "
 	       .       "c.scheduleid = sc.id AND "
 	       .       "c.currentimageid = cur.id AND "
-	       .       "r.resourcetypeid = t.id AND "
-	       .       "t.name = 'computer' AND "
-	       .       "r.subid = c.id AND "
 	       .       "c.ownerid = u.id AND "
 	       .       "u.affiliationid = a.id AND "
 	       .       "c.predictivemoduleid = m.id ";
@@ -8257,6 +8257,12 @@ function getComputers($sort=0, $included
 			$row['natenabled'] = 1;
 			$row['nathost'] = $nathosts[$row['nathostid']]['hostname'];
 		}
+		if(is_null($row['natpublicIPaddress'])) {
+			$row['nathostenabled'] = 0;
+			$row['natpublicIPaddress'] = '';
+		}
+		else
+			$row['nathostenabled'] = 1;
 		$return[$row['id']] = $row;
 	}
 	if($sort) {

Modified: vcl/trunk/web/js/resources/computer.js
URL: http://svn.apache.org/viewvc/vcl/trunk/web/js/resources/computer.js?rev=1646463&r1=1646462&r2=1646463&view=diff
==============================================================================
--- vcl/trunk/web/js/resources/computer.js (original)
+++ vcl/trunk/web/js/resources/computer.js Thu Dec 18 14:20:51 2014
@@ -500,10 +500,11 @@ function applyExtraFilters(value) {
 }
 
 function addNewResource(title) {
-		if(dijit.byId('scheduleid').options.length == 0) {
-			dijit.byId('noschedulenoadd').show();
-			return;
-		}
+	if(dijit.byId('scheduleid').options.length == 0) {
+		dijit.byId('noschedulenoadd').show();
+		return;
+	}
+	dijit.byId('mode').set('value', 'single');
 	addedit = 'add';
 	resetEditResource();
 	dijit.byId('type').reset();
@@ -517,6 +518,8 @@ function addNewResource(title) {
 	dojo.addClass('curimgspan', 'hidden');
 	dojo.addClass('compidspan', 'hidden');
 	dijit.byId('nathostid').set('disabled', true);
+	dijit.byId('natpublicipaddress').set('disabled', true);
+	dijit.byId('natinternalipaddress').set('disabled', true);
 	dijit.byId('addeditdlg').show();
 }
 
@@ -532,6 +535,7 @@ function toggleAddSingle() {
 	dojo.addClass('startenddiv', 'hidden');
 	dojo.addClass('multiipmacdiv', 'hidden');
 	dojo.removeClass('singleipmacdiv', 'hidden');
+	dojo.removeClass('nathost', 'hidden');
 	dijit.byId('name').set('regExp', '^([a-zA-Z0-9_][-a-zA-Z0-9_\.]{1,35})$');
 	dijit.byId('addeditbtn').setLabel('Add Computer');
 	recenterDijitDialog('addeditdlg');
@@ -542,6 +546,7 @@ function toggleAddMultiple() {
 	dojo.removeClass('startenddiv', 'hidden');
 	dojo.removeClass('multiipmacdiv', 'hidden');
 	dojo.addClass('singleipmacdiv', 'hidden');
+	dojo.addClass('nathost', 'hidden');
 	dijit.byId('name').set('regExp', '^([a-zA-Z0-9_%][-a-zA-Z0-9_\.%]{1,35})$');
 	dijit.byId('addeditbtn').setLabel('Add Computers');
 	recenterDijitDialog('addeditdlg');
@@ -554,6 +559,24 @@ function toggleNAT(chkid, selid) {
 	else {
 		dijit.byId(selid).set('disabled', true);
 	}
+	if(chkid == 'natenabled' &&
+	   dijit.byId(chkid).checked &&
+	   dijit.byId('nathostenabled').checked) {
+		dijit.byId('nathostenabled').set('checked', false);
+	}
+}
+
+function toggleNAThost() {
+	if(dijit.byId('nathostenabled').checked) {
+		if(dijit.byId('natenabled').checked)
+			dijit.byId('natenabled').set('checked', false);
+		dijit.byId('natpublicipaddress').set('disabled', false);
+		dijit.byId('natinternalipaddress').set('disabled', false);
+	}
+	else {
+		dijit.byId('natpublicipaddress').set('disabled', true);
+		dijit.byId('natinternalipaddress').set('disabled', true);
+	}
 }
 
 function inlineEditResourceCB(data, ioArgs) {
@@ -623,6 +646,20 @@ function inlineEditResourceCB(data, ioAr
 			dijit.byId('natenabled').set('checked', false);
 			dijit.byId('nathostid').set('disabled', true);
 		}
+		if(data.items.data.nathostenabled == 1) {
+			dijit.byId('nathostenabled').set('checked', true);
+			dijit.byId('natpublicipaddress').set('disabled', false);
+			dijit.byId('natinternalipaddress').set('disabled', false);
+			dijit.byId('natpublicipaddress').set('value', data.items.data.natpublicIPaddress);
+			dijit.byId('natinternalipaddress').set('value', data.items.data.natinternalIPaddress);
+		}
+		else {
+			dijit.byId('nathostenabled').set('checked', false);
+			dijit.byId('natpublicipaddress').set('disabled', true);
+			dijit.byId('natinternalipaddress').set('disabled', true);
+			dijit.byId('natpublicipaddress').set('value', '');
+			dijit.byId('natinternalipaddress').set('value', '');
+		}
 		dojo.byId('addeditdlgerrmsg').innerHTML = '';
 		dijit.byId('addeditdlg').show();
 	}
@@ -716,7 +753,8 @@ function resetEditResource() {
 	              'vmprofileid', 'platformid', 'scheduleid', 'ram', 'cores',
 	              'procspeed', 'network', 'location', 'startnum', 'endnum',
 	              'startpubipaddress', 'endpubipaddress', 'startprivipaddress',
-	              'endprivipaddress', 'startmac', 'notes', 'predictivemoduleid'];
+	              'endprivipaddress', 'startmac', 'notes', 'predictivemoduleid',
+	              'natpublicipaddress', 'natinternalipaddress'];
 	for(var i = 0; i < fields.length; i++) {
 		dijit.byId(fields[i]).reset();
 	}
@@ -735,11 +773,13 @@ function saveResource() {
 	var errobj = dojo.byId('addeditdlgerrmsg');
 	if(addedit == 'edit' || dijit.byId('mode').get('value') == 'single')
 		var fields = ['name', 'owner', 'ipaddress', 'privateipaddress', 'publicmac',
-		              'privatemac', 'ram', 'cores', 'procspeed', 'location'];
+		              'privatemac', 'ram', 'cores', 'procspeed', 'location',
+		              'natpublicipaddress', 'natinternalipaddress'];
 	else
 		var fields = ['name', 'startnum', 'endnum', 'owner', 'startpubipaddress',
 		              'endpubipaddress', 'startprivipaddress', 'endprivipaddress',
-		              'startmac', 'ram', 'cores', 'procspeed', 'location'];
+		              'startmac', 'ram', 'cores', 'procspeed', 'location',
+		              'natpublicipaddress', 'natinternalipaddress'];
 	for(var i = 0; i < fields.length; i++) {
 		if(! checkValidatedObj(fields[i], errobj))
 			return;
@@ -779,6 +819,15 @@ function saveResource() {
 		data['natenabled'] = 0;
 		data['nathostid'] = 0;
 	}
+	data['nathostenabled'] = dijit.byId('nathostenabled').get('value');
+	if(data['nathostenabled'] == 1) {
+		if(data['natenabled'] == 1) {
+			errobj.innerHTML = "Connect Using NAT and Use as NAT Host cannot both be checked";
+			return;
+		}
+	}
+	else
+		data['nathostenabled'] = 0;
 	data['addmode'] = dijit.byId('mode').get('value');
 
 	dijit.byId('addeditbtn').set('disabled', true);