var bpaList; var fspList; var lparList; var selectLpar = new Object(); /** * Get all nodes' nodetype and parent, and create the physical layout div * * @param data: the response from xcat command "nodels all nodetype.nodetype ppc.parent ..." * area: the element to append tree and graphical layout * @return */ function createPhysicalLayout(data, area){ var nodes = data.rsp; var tempList = new Object(); bpaList = new Object(); fspList = new Object(); lparList = new Object(); //extract useful info into tempList for (var i = 0; i < nodes.length; i++){ var nodeName = nodes[i][0]; if (undefined == tempList[nodeName]){ tempList[nodeName] = new Object(); } switch(nodes[i][2]){ case 'nodetype.nodetype': { tempList[nodeName]['type'] = nodes[i][1]; } break; case 'ppc.parent' : { tempList[nodeName]['parent'] = nodes[i][1]; } break; case 'nodelist.status': { tempList[nodeName]['status'] = nodes[i][1]; } break; case 'vpd.mtm': { tempList[nodeName]['mtm'] = nodes[i][1]; } default : break; } } for (var nodeName in tempList){ var parentName = tempList[nodeName]['parent']; var mtm = tempList[nodeName]['mtm']; var status = tempList[nodeName]['status']; switch(tempList[nodeName]['type']){ case 'bpa': { if (undefined == bpaList[nodeName]){ bpaList[nodeName] = new Array(); } } break; case 'lpar,osi': { if ('' == parentName){ break; } if (undefined == fspList[parentName]){ fspList[parentName] = new Array(); //default is 4 units. so i select a 4u mtm randomly fspList[parentName]['mtm'] = '8202-E4B'; fspList[nodeName]['children'] = new Array(); } fspList[parentName]['children'].push(nodeName); lparList[nodeName] = status; } break; case 'fsp': { if (undefined == fspList[nodeName]){ fspList[nodeName] = new Array(); fspList[nodeName]['children'] = new Array(); } fspList[nodeName]['mtm'] = mtm; if ('' == parentName){ break; } if (undefined == bpaList[parentName]){ bpaList[parentName] = new Array(); } bpaList[parentName].push(nodeName); } break; default: break; } } createTree(bpaList, fspList, area); createGraphical(bpaList, fspList, area); } /** * create the physical tree layout * * @param bpa : all bpa and there related fsps * fsp : all fsp and there related lpars * area: the element to append tree layout * @return */ function createTree(bpa, fsp, area){ //create tree and layout var usedFsp = new Object(); var bpaList = '<ul>'; for(var bpaName in bpa) { var fspList = '<ul>'; for(var fspIndex in bpa[bpaName]) { var fspName = bpa[bpaName][fspIndex]; usedFsp[fspName] = 1; var lparList = '<ul>'; for (var lparIndex in fsp[fspName]['children']) { lparList += '<li><ins> </ins>' + fsp[fspName]['children'][lparIndex] + '</li>'; } lparList += '</ul>'; fspList += '<li><a href="#">' + fspName + '(' + fsp[fspName]['children'].length + ' lpars)</a>' + lparList + '</li>'; } fspList += '</ul>'; bpaList += '<li><a href="#">' + bpaName + '(' + bpa[bpaName].length + ' fsps)</a>' + fspList + '</li>'; } bpaList += '</ul>'; var cecList = '<ul>'; for (var fspName in fsp) { if (usedFsp[fspName]) { continue; } var lparList = '<ul>'; for (var lparIndex in fsp[fspName]['children']) { lparList += '<li><ins> </ins>' + fsp[fspName]['children'][lparIndex] + '</li>'; } lparList += '</ul>'; cecList += '<li><a href="#">' + fspName + '(' + fsp[fspName]['children'].length + ' lpars)</a>' + lparList + '</li>'; } cecList += '</ul>'; var tree_area = $('<div class="physicaltree"></div>'); tree_area.append('<ul><li><a href="#">BPA</a>' + bpaList + '</li><li><a href="#">FSP</a>' + cecList + '</li></ul>'); area.append(tree_area); tree_area.jstree({ themes : { "theme" : "default", "dots" : false, // No dots "icons" : false // No icons } }); } /** * create the physical graphical layout * * @param bpa : all bpa and there related fsps * fsp : all fsp and there related lpars * fspinfo : all fsps' hardwareinfo * area: the element to append graphical layout * @return */ function createGraphical(bpa, fsp, area){ var usedFsp = new Object(); var graphField = $('<fieldset></fieldset>'); graphField.append('<legend>Graphical Layout</legend>'); var graphTable = $('<table id="graphTable"><tbody></tbody></table>'); var elementNum = 0; var row; for (var bpaName in bpa){ if (0 == elementNum % 3){ row = $('<tr></tr>'); graphTable.append(row); } elementNum ++; var td = $('<td></td>'); var frameDiv = $('<div class="frameDiv"></div>'); frameDiv.append('<div style="height:27px;">' + bpaName + '</div>'); for (var fspIndex in bpa[bpaName]){ var fspName = bpa[bpaName][fspIndex]; usedFsp[fspName] = 1; frameDiv.append(createFspDiv(fspName, fsp[fspName]['mtm'], fsp)); frameDiv.append(createFspTip(fspName, fsp[fspName]['mtm'], fsp)); } td.append(frameDiv); row.append(td); } //find the single fsp and sort descend by units var singleFsp = new Array(); for (var fspName in fsp){ if (usedFsp[fspName]) { continue; } singleFsp.push([fspName, fsp[fspName]['mtm']]); } singleFsp.sort(function(a, b){ var unitNumA = 4; var unitNumB = 4; if (hardwareInfo[a[1]]){ unitNumA = hardwareInfo[a[1]][1]; } if (hardwareInfo[b[1]]){ unitNumB = hardwareInfo[b[1]][1]; } return (unitNumB - unitNumA); }); elementNum = 0; for (var fspIndex in singleFsp){ var fspName = singleFsp[fspIndex][0]; if (0 == elementNum % 3){ row = $('<tr></tr>'); graphTable.append(row); } elementNum ++; var td = $('<td style="vertical-align:top"></td>'); td.append(createFspDiv(fspName, fsp[fspName]['mtm'], fsp)); td.append(createFspTip(fspName, fsp[fspName]['mtm'], fsp)); row.append(td); } graphField.append(graphTable); var graphical_area = $('<div class="physicalview"></div>'); var selectLparDiv = $('<div id="selectLparDiv" style="margin: 20px;"></div>'); var temp = 0; for (var i in selectLpar){ temp ++; break; } //there is not selected lpars, show the info bar if (0 == temp){ selectLparDiv.append(createInfoBar('Click CEC and select lpars to do operations.')); } //show selected lpars else{ updateSelectLparDiv(); } graphical_area.append(selectLparDiv); graphical_area.append(graphField); area.append(graphical_area); $('.tooltip input[type = checkbox]').bind('click', function(){ var lparName = $(this).attr('name'); if ('' == lparName){ return; } if (true == $(this).attr('checked')){ selectLpar[lparName] = 1; $('#graphTable [name=' + lparName + ']').css('border-color', 'aqua'); } else{ delete selectLpar[lparName]; $('#graphTable [name=' + lparName + ']').css('border-color', 'transparent'); } updateSelectLparDiv(); }); $('.fspDiv2, .fspDiv4, .fspDiv42').tooltip({ }); $('.fspDiv2, .fspDiv4, .fspDiv42').bind('click', function(){ var fspName = $(this).attr('value'); showSelectDialog(fspList[fspName]['children']); }); } /** * show the fsp's information in a dialog * * @param fspName : fsp's name * * @return */ function showSelectDialog(lpars){ var diaDiv = $('<div class="tab" title=Select Lpars"></div>'); if (0 == lpars.length){ diaDiv.append(createInfoBar('There is not any lpars defined.')); } else{ //add the dialog content var selectTable = $('<table id="selectLparTable"><tbody></tbody></table>'); selectTable.append('<tr><th><input type="checkbox" onclick="selectAllLpars($(this))"></input></th><th>Name</th><th>Status</th></tr>'); for (var lparIndex in lpars){ var row = $('<tr></tr>'); var lparName = lpars[lparIndex]; var color = statusMap(lparList[lparName]); if (selectLpar[lparName]){ row.append('<td><input type="checkbox" checked="checked" name="' + lparName + '"></input></td>'); } else{ row.append('<td><input type="checkbox" name="' + lparName + '"></input></td>'); } row.append('<td>' + lparName + '</td>'); row.append('<td style="background-color:' + color + ';">' + lparList[lparName] + '</td>'); selectTable.append(row); } diaDiv.append(selectTable); } diaDiv.dialog({ modal: true, width: 400, close: function(event, ui){ $(this).remove(); }, buttons: { cancel : function(){ $(this).dialog('close'); }, ok : function(){ $('#selectLparTable input[type=checkbox]').each(function(){ var lparName = $(this).attr('name'); if ('' == lparName){ //continue return true; } if (true == $(this).attr('checked')){ selectLpar[lparName] = 1; $('#graphTable [name=' + lparName + ']').css('border-color', 'aqua'); } else{ delete selectLpar[lparName]; $('#graphTable [name=' + lparName + ']').css('border-color', 'transparent'); } }); updateSelectLparDiv(); $(this).dialog('close'); } } }); } /** * update the lpars' background in cec, lpars area and selectLpar * * @param * @return * **/ function updateSelectLparDiv(){ var temp = 0; $('#selectLparDiv').empty(); for (var LparName in selectLpar){ temp ++; break; } if (0 == temp){ $('#selectLparDiv').append(createInfoBar('Click CEC and select lpars to do operations.')); return; } temp =0; //add buttons var tempDiv = $('<div class="actionBar"></div>'); tempDiv.append(createActionMenu()); $('#selectLparDiv').append(tempDiv); $('#selectLparDiv').append('<br/>Lpars: '); for(var lparName in selectLpar){ $('#selectLparDiv').append(lparName + ' '); temp ++; if (6 < temp){ $('#selectLparDiv').append('...'); break; } } var reselectButton = createButton('Reselect'); $('#selectLparDiv').append(reselectButton); reselectButton.bind('click', function(){ reselectLpars(); }); } /** * create the action menu * * @param getNodesFunction * the function that can find selected nodes name * @return * action menu object */ function createActionMenu(){ // Create action bar var actionBar = $('<div class="actionBar"></div>'); /** * The following actions are available to perform against a given node: * power, clone, delete, unlock, and advanced */ /* * Power */ var powerLnk = $('<a>Power</a>'); /* * Power on */ var powerOnLnk = $('<a>Power on</a>'); powerOnLnk.bind('click', function(event) { var tgtNodes = getSelectLpars(); $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'rpower', tgt : tgtNodes, args : 'on', msg : '' } }); }); /* * Power off */ var powerOffLnk = $('<a>Power off</a>'); powerOffLnk.bind('click', function(event) { var tgtNodes = getSelectLpars(); $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'rpower', tgt : tgtNodes, args : 'off', msg : '' } }); }); /* * Clone */ var cloneLnk = $('<a>Clone</a>'); cloneLnk.bind('click', function(event) { var tgtNodes = getSelectLpars('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 = $('<a>Delete</a>'); deleteLnk.bind('click', function(event) { }); /* * Unlock */ var unlockLnk = $('<a>Unlock</a>'); unlockLnk.bind('click', function(event) { }); /* * Run script */ var scriptLnk = $('<a>Run script</a>'); scriptLnk.bind('click', function(event) { }); /* * Update node */ var updateLnk = $('<a>Update</a>'); updateLnk.bind('click', function(event) { }); /* * Set boot state */ var setBootStateLnk = $('<a>Set boot state</a>'); setBootStateLnk.bind('click', function(event) { }); /* * Boot to network */ var boot2NetworkLnk = $('<a>Boot to network</a>'); boot2NetworkLnk.bind('click', function(event) { }); /* * Open the Rcons page */ var rcons = $('<a>Open Rcons</a>'); rcons.bind('click', function(event){ var tgtNodes = getSelectLpars(); if (tgtNodes) { loadRconsPage(tgtNodes); } }); /* * Advanced */ var advancedLnk = $('<a>Advanced</a>'); // Power actions var powerActions = [ powerOnLnk, powerOffLnk ]; var powerActionMenu = createMenu(powerActions); // Advanced actions var advancedActions; advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk, rcons ]; var advancedActionMenu = createMenu(advancedActions); /** * Create an action menu */ var actionsDIV = $('<div></div>'); var actions = [ [ powerLnk, powerActionMenu ], cloneLnk, deleteLnk, unlockLnk, [ advancedLnk, advancedActionMenu ] ]; var actionMenu = createMenu(actions); actionMenu.superfish(); actionsDIV.append(actionMenu); actionBar.append(actionsDIV); return actionBar; } /** * create the physical graphical layout * * @param bpaName : fsp's key * fsp : all fsp and there related lpars * fspinfo : all fsps' hardwareinfo * @return * */ function createFspDiv(fspName, mtm, fsp){ //create fsp title var lparStatusRow = ''; for (var lparIndex in fsp[fspName]['children']){ var lparName = fsp[fspName]['children'][lparIndex]; var color = statusMap(lparList[lparName]); lparStatusRow += '<td class="lparStatus" style="background-color:' + color + ';color:' + color + ';" name="' + lparName + '">1</td>'; } //select the backgroud var divClass = ''; if (hardwareInfo[mtm][1]){ divClass += 'fspDiv' + hardwareInfo[mtm][1]; } else{ divClass += 'fspDiv4'; } //create return value var retHtml = '<div value="' + fspName + '" class="' + divClass + '">'; retHtml += '<div class="lparDiv"><table><tbody><tr>' + lparStatusRow + '</tr></tbody></table></div></div>'; return retHtml; } /** * create the physical graphical fsps' help witch could select the lpars. * * @param bpaName : fsp's key * fsp : all fsp and there related lpars * fspinfo : all fsps' hardwareinfo * @return * */ function createFspTip(fspName, mtm, fsp){ var tip = $('<div class="tooltip"></div>'); var tempTable = $('<table><tbody></tbody></table>'); if (hardwareInfo[mtm]){ tip.append('<h3>' + fspName + '(' + hardwareInfo[mtm][0] + ')</h3><br/>'); } else{ tip.append('<h3>' + fspName + '</h3><br/>'); } for (var lparIndex in fsp[fspName]['children']){ var lparName = fsp[fspName]['children'][lparIndex]; var color = statusMap(lparList[lparName]); var row = '<tr><td><input type="checkbox" name="' + lparName + '"></td>'; row += '<td>'+ lparName + '</td>'; row += '<td style="background-color:' + color + ';">' + lparList[lparName] + '</td></tr>'; tempTable.append(row); } tip.append(tempTable); return tip; } /** * map the lpar's status into a color * * @param status : lpar's status in nodelist table * @return * corresponding color name */ function statusMap(status){ var color = 'gainsboro'; switch(status){ case 'alive': case 'ready': case 'pbs': case 'sshd': case 'booting':{ color = 'green'; } break; case 'noping': case 'unreachable':{ color = 'red'; } break; case 'ping':{ color = 'yellow'; } break; default: break; } return color; } /** * select all lpars checkbox in the dialog * * @param * @return * */ function selectAllLpars(checkbox){ var temp = checkbox.attr('checked'); $('#selectLparTable input[type = checkbox]').attr('checked', temp); } /** * export all lpars' name from selectLpar * * @param * @return lpars' string * */ function getSelectLpars(){ var ret = ''; for (var lparName in selectLpar){ ret += lparName + ','; } return ret.substring(0, ret.length-1); } /** * show all lpars' for users to delete * * @param * @return */ function reselectLpars(){ var temp = new Array(); for (var lparName in selectLpar){ temp.push(lparName); } showSelectDialog(temp); }