/** * Global variables */ var nodesTabs; // Node tabs var nodesDataTable; // Datatable containing all nodes within a group /** * Set the nodes tab * * @param obj * Tab object * @return Nothing */ function setNodesTab(obj) { nodesTabs = obj; } /** * Get the nodes tab * * @param Nothing * @return Tab object */ function getNodesTab() { return nodesTabs; } /** * Get the nodes datatable * * @param Nothing * @return Data table object */ function getNodesDataTable() { return nodesDataTable; } /** * Set the nodes datatable * * @param table * Data table object * @return Nothing */ function setNodesDataTable(table) { nodesDataTable = table; } /** * Load nodes page * * @return Nothing */ function loadNodesPage() { // If groups are not already loaded if (!$('#groups').length) { // Create a groups division groupDIV = $('
'); nodesDIV = $(''); $('#content').append(groupDIV); $('#content').append(nodesDIV); // Create loader var loader = createLoader(); groupDIV.append(loader); // Create info bar var info = createInfoBar('Select a group to view its nodes'); $('#nodes').append(info); // Get groups $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'extnoderange', tgt : '/.*', args : 'subgroups', msg : '' }, success : loadGroups }); } } /** * Load groups * * @param data * Data returned from HTTP request * @return */ function loadGroups(data) { // Remove loader $('#groups').find('img').remove(); var groups = data.rsp; setGroupsCookies(data); // Create a list of groups var ul = $('
', 
		'power
');
	// Create a datatable
	var dTable = new DataTable('nodesDataTable');
	dTable.init(sorted);
	// Go through each node
	for ( var node in attrs) {
		// Create a row
		var row = new Array();
		// Create a check box
		var checkBx = '';
		// Open node onclick
		var nodeLink = $('' + node + '').bind('click', loadNode);
		row.push(checkBx, nodeLink, '', '');
		// Go through each header
		for ( var i = 4; i < sorted.length; i++) {
			// Add the node attributes to the row
			var key = sorted[i];
			var val = attrs[node][key];
			if (val) {
				row.push(val);
			} else {
				row.push('');
			}
		}
		// Add the row to the table
		dTable.add(row);
	}
	// Clear the tab before inserting the table
	$('#nodesTab').children().remove();
	// Create action bar
	var actionBar = $('');
	/**
	 * The following actions are available to perform against a given node:
	 * power, clone, delete, unlock, and advanced
	 */
	/*
	 * Power
	 */
	var powerLnk = $('Power');
	/*
	 * Power on
	 */
	var powerOnLnk = $('Power on');
	powerOnLnk.bind('click', function(event) {
		var tgtNodes = getNodesChecked('nodesDataTable');
		if (tgtNodes) {
			powerNode(tgtNodes, 'on');
		}
	});
	/*
	 * Power off
	 */
	var powerOffLnk = $('Power off');
	powerOffLnk.bind('click', function(event) {
		var tgtNodes = getNodesChecked('nodesDataTable');
		if (tgtNodes) {
			powerNode(tgtNodes, 'off');
		}
	});
	/*
	 * Clone
	 */
	var cloneLnk = $('Clone');
	cloneLnk.bind('click', function(event) {
		var tgtNodes = getNodesChecked('nodesDataTable').split(',');
		for ( var i = 0; i < tgtNodes.length; i++) {
			var mgt = getNodeAttr(tgtNodes[i], 'mgt');
			
			// Create an instance of the plugin
			var plugin;
			switch(mgt) {
				case "blade":
		    		plugin = new bladePlugin();
		    		break;
				case "fsp":
					plugin = new fspPlugin();
					break;
				case "hmc":
					plugin = new hmcPlugin();
					break;
				case "ipmi":
					plugin = new ipmiPlugin();
					break;		
				case "ivm":
					plugin = new ivmPlugin();
					break;
				case "zvm":
					plugin = new zvmPlugin();
					break;
			}
			
			plugin.loadClonePage(tgtNodes[i]);
		}
	});
	/*
	 * Delete
	 */
	var deleteLnk = $('Delete');
	deleteLnk.bind('click', function(event) {
		var tgtNodes = getNodesChecked('nodesDataTable');
		if (tgtNodes) {
			deleteNode(tgtNodes);
		}
	});
	/*
	 * Unlock
	 */
	var unlockLnk = $('Unlock');
	unlockLnk.bind('click', function(event) {
		var tgtNodes = getNodesChecked('nodesDataTable');
		if (tgtNodes) {
			loadUnlockPage(tgtNodes);
		}
	});
	/*
	 * Run script
	 */
	var scriptLnk = $('Run script');
	scriptLnk.bind('click', function(event) {
		var tgtNodes = getNodesChecked('nodesDataTable');
		if (tgtNodes) {
			loadScriptPage(tgtNodes);
		}
	});
	/*
	 * Update node
	 */
	var updateLnk = $('Update');
	updateLnk.bind('click', function(event) {
		var tgtNodes = getNodesChecked('nodesDataTable');
		if (tgtNodes) {
			loadUpdatenodePage(tgtNodes);
		}
	});
	/*
	 * Set boot state
	 */
	var setBootStateLnk = $('Set boot state');
	setBootStateLnk.bind('click', function(event) {
		var tgtNodes = getNodesChecked('nodesDataTable');
		if (tgtNodes) {
			loadNodesetPage(tgtNodes);
		}
	});
	/*
	 * Boot to network
	 */
	var boot2NetworkLnk = $('Boot to network');
	boot2NetworkLnk.bind('click', function(event) {
		var tgtNodes = getNodesChecked('nodesDataTable');
		if (tgtNodes) {
			loadNetbootPage(tgtNodes);
		}
	});
	/*
	 * Open the Rcons page
	 */
	var rcons = $('Open Rcons');
	rcons.bind('click', function(event){
		var tgtNodes = getNodesChecked('nodesDataTable');
		if (tgtNodes) {
			loadRconsPage(tgtNodes);
		}
	});
	/*
	 * Advanced
	 */
	var advancedLnk = $('Advanced');
	// Power actions
	var powerActions = [ powerOnLnk, powerOffLnk ];
	var powerActionMenu = createMenu(powerActions);
	// Advanced actions
	var advancedActions;
	if ('compute' == group) {
		advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk, rcons ];
	} else {
		advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk ];
	}
	var advancedActionMenu = createMenu(advancedActions);
	/**
	 * Create an action menu
	 */
	var actionsDIV = $('');
	var actions = [ [ powerLnk, powerActionMenu ], cloneLnk, deleteLnk, unlockLnk, [ advancedLnk, advancedActionMenu ] ];
	var actionMenu = createMenu(actions);
	actionMenu.superfish();
	actionsDIV.append(actionMenu);
	actionBar.append(actionsDIV);
	$('#nodesTab').append(actionBar);
	// Insert table
	$('#nodesTab').append(dTable.object());
	// Turn table into a datatable
	var myDataTable = $('#nodesDataTable').dataTable();
	setNodesDataTable(myDataTable);
	
	// Do not sort ping and power column
	var pingCol = $('#nodesDataTable thead tr th').eq(2);
	var powerCol = $('#nodesDataTable thead tr th').eq(3);
	pingCol.unbind('click');
	powerCol.unbind('click');
	
	// Create enough space for loader to be displayed
	$('#nodesDataTable tbody tr td:nth-child(3)').css('min-width', '60px');
	$('#nodesDataTable tbody tr td:nth-child(4)').css('min-width', '60px');
	
	// Instead refresh the ping status and power status
	pingCol.bind('click', function(event) {
		refreshPingStatus(group);
	});
	
	powerCol.bind('click', function(event) {
		refreshPowerStatus(group);
	});
	/**
	 * Get power and ping status for each node
	 */
	// Get the power status
	$.ajax( {
		url : 'lib/cmd.php',
		dataType : 'json',
		data : {
			cmd : 'rpower',
			tgt : group,
			args : 'stat',
			msg : ''
		},
		success : loadPowerStatus
	});
	// Get the ping status
	$.ajax( {
		url : 'lib/cmd.php',
		dataType : 'json',
		data : {
			cmd : 'webrun',
			tgt : '',
			args : 'pping ' + group,
			msg : ''
		},
		success : loadPingStatus
	});
	/**
	 * Additional ajax requests need to be made for zVM
	 */
	// Get the index of the HCP column
	var i = $.inArray('hcp', sorted);
	if (i) {
		// Get hardware control point
		var rows = dTable.object().find('tbody tr');
		var hcps = new Object();
		for ( var j = 0; j < rows.length; j++) {
			var val = rows.eq(j).find('td').eq(i).html();
			hcps[val] = 1;
		}
		var args;
		for ( var h in hcps) {
			// Get node without domain name
			args = h.split('.');
			// Get disk pools
			$.ajax( {
				url : 'lib/cmd.php',
				dataType : 'json',
				data : {
					cmd : 'lsvm',
					tgt : args[0],
					args : '--diskpoolnames',
					msg : args[0]
				},
				success : setDiskPoolCookies
			});
			// Get network names
			$.ajax( {
				url : 'lib/cmd.php',
				dataType : 'json',
				data : {
					cmd : 'lsvm',
					tgt : args[0],
					args : '--getnetworknames',
					msg : args[0]
				},
				success : setNetworkCookies
			});
		}
	}
}
/**
 * Load power status for each node
 * 
 * @param data
 *            Data returned from HTTP request
 * @return Nothing
 */
function loadPowerStatus(data) {
	// Get datatable
	var dTable = getNodesDataTable();
	var power = data.rsp;
	var rowNum, node, status, args;
	for ( var i in power) {
		// power[0] = nodeName and power[1] = state
		args = power[i].split(':');
		node = jQuery.trim(args[0]);
		status = jQuery.trim(args[1]);
		// Get the row containing the node
		rowNum = getRowNum(node);
		// Update the power status column
		dTable.fnUpdate(status, rowNum, 3);
	}
	
	// Hide power loader
	var powerCol = $('#nodesDataTable thead tr th').eq(3);
	powerCol.find('img').hide();
}
/**
 * Refresh power status for each node
 * 
 * @param group
 *            Group name
 * @return Nothing
 */
function refreshPowerStatus(group) {
	// Show power loader
	var powerCol = $('#nodesDataTable thead tr th').eq(3);
	powerCol.find('img').show();
	
	// Get the power status
	$.ajax( {
		url : 'lib/cmd.php',
		dataType : 'json',
		data : {
			cmd : 'rpower',
			tgt : group,
			args : 'stat',
			msg : ''
		},
		success : loadPowerStatus
	});
}
/**
 * Load ping status for each node
 * 
 * @param data
 *            Data returned from HTTP request
 * @return Nothing
 */
function loadPingStatus(data) {
	// Get data table
	var dTable = getNodesDataTable();
	var ping = data.rsp;
	var rowPos, node, status;
	// Get all nodes within the datatable
	var rows = dTable.fnGetNodes();
	for ( var i in ping) {
		// ping[0] = nodeName and ping[1] = state
		node = jQuery.trim(ping[i][0]);
		status = jQuery.trim(ping[i][1]);
		// Get the row containing the node
		rowPos = getRowNum(node);
		// Update the ping status column
		dTable.fnUpdate(status, rowPos, 2);
	}
	
	// Hide ping loader
	var pingCol = $('#nodesDataTable thead tr th').eq(2);
	pingCol.find('img').hide();
}
/**
 * Refresh ping status for each node
 * 
 * @param group
 *            Group name
 * @return Nothing
 */
function refreshPingStatus(group) {
	// Show ping loader
	var pingCol = $('#nodesDataTable thead tr th').eq(2);
	pingCol.find('img').show();
	
	// Get the ping status
	$.ajax( {
		url : 'lib/cmd.php',
		dataType : 'json',
		data : {
			cmd : 'webrun',
			tgt : '',
			args : 'pping ' + group,
			msg : ''
		},
		success : loadPingStatus
	});
}
/**
 * Load inventory for given node
 * 
 * @param e
 *            Windows event
 * @return Nothing
 */
function loadNode(e) {
	if (!e) {
		e = window.event;
	}
	
	// Get node that was clicked
	var node = (e.target) ? e.target.id : e.srcElement.id;
	var mgt = getNodeAttr(node, 'mgt');
		
	// Create an instance of the plugin
	var plugin;
	switch(mgt) {
		case "blade":
    		plugin = new bladePlugin();
    		break;
		case "fsp":
			plugin = new fspPlugin();
			break;
		case "hmc":
			plugin = new hmcPlugin();
			break;
		case "ipmi":
			plugin = new ipmiPlugin();
			break;		
		case "ivm":
			plugin = new ivmPlugin();
			break;
		case "zvm":
			plugin = new zvmPlugin();
			break;
	}
	// Get tab area where a new tab will be inserted
	// The node name may contain special characters (e.g. '.','#'), so we can not use the node name as an ID.
	var myTab = getNodesTab();
	var inst = 0;
	var newTabId = 'nodeTab' + inst;
	while ($('#' + newTabId).length) {
		// If one already exists, generate another one
		inst = inst + 1;
		newTabId = 'nodeTab' + inst;
	}
	// Reset node process
	$.cookie(node + 'Processes', 0);
	// Add new tab, only if one does not exist
	var loader = createLoader(newTabId + 'TabLoader');
	loader = $('Do you want to delete ' + tgtNodesStr + '?
').css('word-wrap', 'break-word'); deleteForm.append(instr); /** * Delete */ var deleteBtn = createButton('Delete'); deleteBtn.bind('click', function(event) { // Delete the virtual server $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'rmvm', tgt : tgtNodes, args : '', msg : 'out=' + statBarId + ';cmd=rmvm;tgt=' + tgtNodes }, success : updateStatusBar }); // Show status bar loader statBar.show(); // Disable delete button $(this).attr('disabled', 'true'); }); var cancelBtn = createButton('Cancel'); cancelBtn.bind('click', function(){ myTab.remove($(this).parent().parent().attr('id')); }); deleteForm.append(deleteBtn); deleteForm.append(cancelBtn); myTab.add(newTabId, 'Delete', deleteForm, true); myTab.select(newTabId); } /** * Update status bar of a given tab * * @param data * Data returned from HTTP request * @return Nothing */ function updateStatusBar(data) { // Get ajax response var rsp = data.rsp; var args = data.msg.split(';'); var statBarId = args[0].replace('out=', ''); var cmd = args[1].replace('cmd=', ''); var tgts = args[2].replace('tgt=', '').split(','); if (cmd == 'unlock' || cmd == 'updatenode') { // Hide loader $('#' + statBarId).find('img').hide(); // Write ajax response to status bar var prg = writeRsp(rsp, ''); $('#' + statBarId).append(prg); } else if (cmd == 'rmvm') { // Get data table var dTable = getNodesDataTable(); var failed = false; // Hide loader $('#' + statBarId).find('img').hide(); // Write ajax response to status bar var prg = writeRsp(rsp, ''); $('#' + statBarId).append(prg); // If there was an error, do not continue if (prg.html().indexOf('Error') > -1) { failed = true; } // Update data table var rows = dTable.fnGetNodes(); for ( var i = 0; i < tgts.length; i++) { if (!failed) { // Get the row containing the node link and delete it var row = getNodeRow(tgts[i], rows); var rowPos = dTable.fnGetPosition(row); dTable.fnDeleteRow(rowPos); } } } else if (cmd == 'xdsh') { // Hide loader $('#' + statBarId).find('img').hide(); // Write ajax response to status bar var prg = $(''); for (var i in rsp) { for (var j in tgts) { rsp[i] = rsp[i].replace(new RegExp(tgts[j] + ':', 'g'), '