/** * 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 = $(''); var item = $('
  • Groups

  • '); ul.append(item); var subUL = $(''); item.append(subUL); // Create a link for each group for ( var i = groups.length; i--;) { var subItem = $('
  • '); var link = $('' + groups[i] + ''); subItem.append(link); subUL.append(subItem); } // Turn groups list into a tree $('#groups').append(ul); $('#groups').tree( { callback : { // Open group onclick onselect : function(node, tree) { var thisGroup = tree.get_text(node); if (thisGroup) { // Clear nodes division $('#nodes').children().remove(); // Create loader var loader = $('
    ').append(createLoader()); // Create a tab for this group var tab = new Tab(); setNodesTab(tab); tab.init(); $('#nodes').append(tab.object()); tab.add('nodesTab', 'Nodes', loader, false); // Get nodes within selected group $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'lsdef', tgt : '', args : thisGroup, msg : thisGroup }, success : loadNodes }); } // End of if (thisGroup) } // End of onselect } // End of callback }); // Create link to add nodes var addNodeLink = $('Add node'); addNodeLink.bind('click', function(event) { var info = createInfoBar('Select the hardware management for the new node range'); var addNodeForm = $('
    '); addNodeForm.append(info); addNodeForm.append('
    ' + '' + '
    ' ); // Open dialog to add node addNodeForm.dialog({ modal: true, width: 400, buttons: { "Ok": function(){ // Get hardware management var mgt = $(this).find('select[name=mgt]').val(); 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.addNode(); $(this).dialog( "close" ); }, "Cancel": function(){ $(this).dialog( "close" ); } } }); }); // Generate tooltips addNodeLink.tooltip({ position: "center right", // Place tooltip on the right edge offset: [-2, 10], // A little tweaking of the position effect: "fade", // Use the built-in fadeIn/fadeOut effect opacity: 0.7 // Custom opacity setting }); $('#groups').append(addNodeLink); } /** * Load nodes belonging to a given group * * @param data * Data returned from HTTP request * @return Nothing */ function loadNodes(data) { // Data returned var rsp = data.rsp; // Group name var group = data.msg; // Node attributes hash var attrs = new Object(); // Node attributes var headers = new Object(); var node; var args; for ( var i in rsp) { // Get the node var pos = rsp[i].indexOf('Object name:'); if (pos > -1) { var temp = rsp[i].split(': '); node = jQuery.trim(temp[1]); // Create a hash for the node attributes attrs[node] = new Object(); i++; } // Get key and value args = rsp[i].split('='); var key = jQuery.trim(args[0]); var val = jQuery.trim(args[1]); // Create a hash table attrs[node][key] = val; headers[key] = 1; } // Sort headers var sorted = new Array(); for ( var key in headers) { sorted.push(key); } sorted.sort(); // Add column for check box, node, ping, and power sorted.unshift('', 'node', 'ping', '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 = $('
    ').append(loader); myTab.add(newTabId, node, loader, true); // Get node inventory var msg = 'out=' + newTabId + ',node=' + node; $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'rinv', tgt : node, args : 'all', msg : msg }, success : plugin.loadInventory }); // Select new tab // Tab ID may contains special char, so we had to use the index myTab.select(newTabId); } /** * Unlock a node by setting the SSH keys * * @param tgtNodes * Nodes to unlock * @return Nothing */ function loadUnlockPage(tgtNodes) { // Get nodes tab var tab = getNodesTab(); // Generate new tab ID var instance = 0; var newTabId = 'UnlockTab' + instance; while ($('#' + newTabId).length) { // If one already exists, generate another one instance = instance + 1; newTabId = 'UnlockTab' + instance; } var unlockForm = $('
    '); // Create status bar, hide on load var statBarId = 'UnlockStatusBar' + instance; var statusBar = createStatusBar(statBarId).hide(); unlockForm.append(statusBar); // Create loader var loader = createLoader(''); statusBar.append(loader); // Create info bar var infoBar = createInfoBar('Give the root password for this node range to setup its SSH keys'); unlockForm.append(infoBar); unlockForm.append('
    '); unlockForm.append('
    '); // Generate tooltips unlockForm.find('div input[title]').tooltip({ position: "center right", // Place tooltip on the right edge offset: [-2, 10], // A little tweaking of the position effect: "fade", // Use the built-in fadeIn/fadeOut effect opacity: 0.7 // Custom opacity setting }); /** * Ok */ var okBtn = createButton('Ok'); okBtn.bind('click', function(event) { // Remove any warning messages $(this).parent().parent().find('.ui-state-error').remove(); // If form is complete var ready = formComplete(newTabId); if (ready) { var password = $('#' + newTabId + ' input[name=password]').val(); // Setup SSH keys $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'webrun', tgt : '', args : 'unlock;' + tgtNodes + ';' + password, msg : 'out=' + statBarId + ';cmd=unlock;tgt=' + tgtNodes }, success : updateStatusBar }); // Show status bar statusBar.show(); // Disable Ok button $(this).attr('disabled', 'true'); } else { // Show warning message var warn = createWarnBar('You are missing some values'); warn.prependTo($(this).parent().parent()); } }); unlockForm.append(okBtn); tab.add(newTabId, 'Unlock', unlockForm, true); tab.select(newTabId); } /** * Load script page * * @param tgtNodes * Targets to run script against * @return Nothing */ function loadScriptPage(tgtNodes) { // Get nodes tab var tab = getNodesTab(); // Generate new tab ID var inst = 0; var newTabId = 'scriptTab' + inst; while ($('#' + newTabId).length) { // If one already exists, generate another one inst = inst + 1; newTabId = 'scriptTab' + inst; } // Open new tab // Create remote script form var scriptForm = $('
    '); // Create status bar var barId = 'scriptStatusBar' + inst; var statBar = createStatusBar(barId); statBar.hide(); scriptForm.append(statBar); // Create loader var loader = createLoader('scriptLoader' + inst); statBar.append(loader); // Create info bar var infoBar = createInfoBar('Run a script against this node range'); scriptForm.append(infoBar); // Target node or group var tgt = $('
    '); scriptForm.append(tgt); // Upload file var upload = $('
    '); var label = $(''); var file = $(''); var subBtn = createButton('Load'); upload.append(label); upload.append(file); upload.append(subBtn); scriptForm.append(upload); // Generate tooltips scriptForm.find('div input[title]').tooltip({ position: "center right", // Place tooltip on the right edge offset: [-2, 10], // A little tweaking of the position effect: "fade", // Use the built-in fadeIn/fadeOut effect opacity: 0.7 // Custom opacity setting }); // Script var script = $('