| |
| <!-- |
| Copyright 2017-present Open Networking Foundation |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| |
| <div id="HPCDashboard"> |
| <h1>CDN Operations View</h1> |
| <span id="hpcSummary"> |
| <span class="summary-attr"><b>Allocated Instances:</b> <span id="active-instances-value"> </span> </span> |
| <span class="summary-attr"><b>CDN Bandwidth:</b> <span id="overall-throughput-value"> </span> </span> |
| <span class="summary-attr-util"><b>CDN Load:</b> <span id="cpu-utilization-value"> </span> </span> |
| </span> |
| <div id="map-us" ></div> |
| <div style="line-height: 30%"><br></div><table border=0><tr> |
| <td>Least Loaded </td> |
| <td bgcolor="#0000FF" width=40> </td> |
| <td bgcolor="#00FFFF" width=40> </td> |
| <td bgcolor="#00FF00" width=40> </td> |
| <td bgcolor="#FFFF00" width=40> </td> |
| <td bgcolor="#FF0000" width=40> </td> |
| <td> Most Loaded</td> |
| </tr></table> |
| </div> |
| |
| <div id="confirmNodeAdded" title="Added Node to Site"><p>Added Node to Site</p></div> |
| <div id="confirmNodeRemoved" title="Removed Node from Site"><p>Added Node to Site</p></div> |
| |
| <script> |
| $( "#confirmNodeAdded" ).dialog({ autoOpen: false, |
| modal: true, |
| buttons: { |
| Ok: function() { |
| $( this ).dialog( "close" ); |
| } |
| }}); |
| $( "#confirmNodeRemoved" ).dialog({ autoOpen: false }); |
| |
| L.Map = L.Map.extend({ |
| openPopup: function(popup) { |
| this._popup = popup; |
| |
| return this.addLayer(popup).fire('popupopen', { |
| popup: this._popup |
| }); |
| } |
| }); |
| |
| |
| //Iterate through data and find the max/min coordinates to include all of our points to start |
| var map = L.map('map-us'); //.setView([0, 0], 1); |
| map.scrollWheelZoom.disable(); |
| |
| // |
| // Great tiles, but starting to occasionally see 403 errors on certain tiles causing grey out effect |
| //L.tileLayer('http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png', { |
| // |
| // Swapping out cloudmade tiles to openstreetmap - too many grey tiles showing |
| L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
| maxZoom: 18, |
| attribution: 'Test' |
| }).addTo(map); |
| |
| var arrayOfLatLngs = []; |
| var mapData = {{ cdnData|safe }}; |
| log.debug( mapData ); |
| |
| for ( var key in mapData ) { |
| arrayOfLatLngs.push([mapData[key]['lat'],mapData[key]['long']]); |
| log.debug( arrayOfLatLngs ); |
| |
| mapData[key]['marker'] = L.marker([mapData[key]['lat'], mapData[key]['long']], {icon: getIcon(mapData[key]['numNodes'], mapData[key]['numHPCInstances'], 0, mapData[key]['hot']) }); |
| mapData[key]['marker'].addTo(map).bindPopup(setPopupVals(key, mapData[key])); |
| |
| } |
| var bounds = new L.LatLngBounds(arrayOfLatLngs); |
| map.fitBounds(bounds); |
| |
| var popup = L.popup(); |
| |
| |
| function setPopupVals (site, siteData) { |
| var retVal = '<span class="SiteDetail"><b>' + site + '</b></span>' + |
| '</br><a href="' + siteData['siteUrl'] + '">' + siteData['siteUrl'] + '</a>' + |
| '</br><b>HPC Instances: </b>' + siteData['numHPCInstances'] + |
| '</br><b>Total Nodes: </b>' + siteData['numNodes'] + |
| // '</br><b>Hot: </b>' + Math.round(siteData['hot']*100) + |
| '</br><b>Measured Load: </b>' + siteData['load'] + '%' + |
| '<span id="addInstances"></br><a href="#" id="addHPCInstance" data-site="' + site + '" data-availNodes="' + siteData['numNodes'] +'">Add HPC Instances</a> </span>' + |
| '<span id="remInstances"><a href="#" id="remHPCInstance" data-site="' + site + '">Remove HPC Instances</a> </span>'; |
| |
| return retVal; |
| } |
| |
| $('#map-us').on('click', '#remHPCInstance', function() { |
| |
| $.ajax({ |
| url : '/dashboardaddorreminstance/', |
| dataType : 'json', |
| data: {site: $(this).data('site'), |
| actionToDo: "rem", |
| csrfmiddlewaretoken: "{{ csrf_token }}", // < here |
| state:"inactive" }, |
| type : 'POST', |
| success:function(){ |
| confirmDialog("Info","Removed an HPC Instance from Site "); |
| }, |
| error:function (xhr, textStatus, thrownError){ |
| errorDialog("Error", textStatus + " " + xhr.responseText); |
| } |
| }); |
| }); |
| |
| $('#map-us').on('click', '#addHPCInstance', function() { |
| |
| $.ajax({ |
| url : '/dashboardaddorreminstance/', |
| dataType : 'json', |
| data: {site: $(this).data('site'), |
| actionToDo: "add", |
| csrfmiddlewaretoken: "{{ csrf_token }}", // < here |
| state:"inactive" }, |
| type : 'POST', |
| success: function(response) |
| { |
| confirmDialog("Info","Added an HPC Instance to Site "); |
| }, |
| error:function (xhr, textStatus, thrownError){ |
| errorDialog("Error", textStatus + " " + xhr.responseText); |
| } |
| }); |
| }); |
| |
| function getIcon(numNodes, numHPCInstances, currentBW, hot) { |
| //var colorChoices = ["#007FFF", "#0000FF", "#7f00ff", "#FF00FF", "#FF007F", "#FF0000"]; |
| var colorChoices = ["#0000FF", "#00FFFF", "#00FF00", "#FFFF00", "#FF0000"]; |
| |
| var ratio = hot * 100; //(numHPCInstances/numNodes) * 100; |
| var numColors = colorChoices.length; |
| var colorBands = 100/numColors; |
| |
| //Algorithm for color tone should consider the number of available nodes |
| // on the site, and then how much the current dedicated nodes are impacted |
| //var iconColor = 0; |
| var iconColor = colorChoices.length-1; |
| for (colorBand = 0; colorBand < numColors; colorBand ++) { |
| if (ratio < colorBands * colorBand+1) { |
| iconColor = colorBand |
| break; |
| } |
| } |
| |
| if (numHPCInstances < 1) { |
| iconColor = "#7F7F7F"; |
| } else { |
| iconColor = colorChoices[iconColor]; |
| } |
| |
| var icon = L.MakiMarkers.icon({icon: "star-stroked", color: iconColor , size: "s"}); |
| return icon; |
| } |
| |
| function updateMaps() { |
| log.debug("Attempting to update Maps"); |
| $.ajax({ |
| url : '/hpcdashboard', |
| dataType : 'json', |
| type : 'GET', |
| success: function(newData) |
| { |
| log.debug("Successfully got data back..."); |
| log.debug(newData); |
| log.debug("Still have old data too"); |
| log.debug(mapData); |
| updateMapData(newData); |
| } |
| }); |
| setTimeout(updateMaps, 30000) |
| |
| } |
| |
| function updateMapData(newData) { |
| for ( site in newData ) { |
| var isNewSite = false; |
| //check to see if the site is new or not |
| if (site in mapData) { |
| log.debug("Site " + site + " already mapped"); |
| //take ownership of marker |
| newData[site]['marker'] = mapData[site]['marker']; |
| delete mapData[site]; |
| newData[site]['marker'].setIcon(getIcon(newData[site]['numNodes'], newData[site]['numHPCInstances'], 0, newData[site]['hot'])); |
| // workaround, markers currently don't have a setPopup Content method -- so have to grab object directly |
| newData[site]['marker']._popup.setContent(setPopupVals(site, newData[site])); |
| } |
| else { |
| isNewSite = true; |
| log.debug("New Site detected: " + site); |
| newData[site]['marker'] = L.marker([newData[site]['lat'], newData[site]['long']], |
| {icon: getIcon(newData[site]['numNodes'], newData[site]['numHPCInstances'], 0, newData[site]['hot']) }); |
| newData[site]['marker'].addTo(map).bindPopup(setPopupVals(site, newData[site])); //.openPopup(); |
| log.debug("Should have added the new site"); |
| |
| } |
| } |
| |
| // Anything still in data needs to be removed since it is no longer a valid site |
| for (remSite in mapData) { |
| log.warn("Site: " + remSite + " is no longer valid, removing from map"); |
| map.removeLayer(data[remSite]['marker']); |
| } |
| mapData = newData; |
| } |
| |
| function onMapClick(e) { |
| popup |
| .setLatLng(e.latlng) |
| .setContent("You clicked the map at " + e.latlng.toString()) |
| .openOn(map); |
| } |
| |
| setTimeout(updateMaps, 5000) |
| |
| // from stackexchange |
| function setInnerText (elementId, text) { |
| var element; |
| if (document.getElementById) { |
| element = document.getElementById(elementId); |
| } else if (document.all) { |
| element = document.all[elementId]; |
| } |
| if (element) { |
| if (typeof element.textContent != 'undefined') { |
| element.textContent = text; |
| } else if (typeof element.innerText != 'undefined') { |
| element.innerText = text; |
| } else if (typeof element.removeChild != 'undefined') { |
| while (element.hasChildNodes()) { |
| element.removeChild(element.lastChild); |
| } |
| element.appendChild(document.createTextNode(text)) ; |
| } |
| } |
| } |
| |
| function updateLabelData(summaryData) { |
| setInnerText("active-instances-value", summaryData["total_instances"]); |
| setInnerText("overall-throughput-value", (summaryData["total_bandwidth"]*8/1024/1024/1024).toFixed(2) + " Gbps"); |
| setInnerText("cpu-utilization-value", summaryData["average_cpu"] + "%"); |
| } |
| |
| function updateLabels() { |
| log.debug("Attempting to update Labels"); |
| $.ajax({ |
| url : '/hpcsummary', |
| dataType : 'json', |
| type : 'GET', |
| success: function(newData) |
| { |
| updateLabelData(newData); |
| } |
| }); |
| setTimeout(updateLabels, 30000) |
| |
| } |
| |
| setTimeout(updateLabels, 5000) |
| |
| |
| </script> |