Implement NodeBalancers
This commit is contained in:
62
nodebalancers/balancer/balancer.css
Normal file
62
nodebalancers/balancer/balancer.css
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of Linode Manager Classic.
|
||||
*
|
||||
* Linode Manager Classic is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Linode Manager Classic is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@import url('/global.css');
|
||||
|
||||
canvas {
|
||||
height: 323px;
|
||||
}
|
||||
|
||||
.center-cell {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#cxn-color {
|
||||
background-color: #906;
|
||||
}
|
||||
|
||||
#graph-range {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
border-bottom: 1px solid #E8E8E8;
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
font-size: 18px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
#nodebalancer-details {
|
||||
padding: 0px 15px 20px;
|
||||
}
|
||||
|
||||
#settings-table tr td:first-of-type {
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#settings-table tr td:not(:last-of-type) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#traffic-in-color {
|
||||
background-color: #03C;
|
||||
}
|
||||
|
||||
#traffic-out-color {
|
||||
background-color: #32CD32;
|
||||
}
|
411
nodebalancers/balancer/balancer.js
Normal file
411
nodebalancers/balancer/balancer.js
Normal file
@ -0,0 +1,411 @@
|
||||
/*
|
||||
* This file is part of Linode Manager Classic.
|
||||
*
|
||||
* Linode Manager Classic is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Linode Manager Classic is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { settings, elements, apiDelete, apiGet, apiPut, countSI, drawSeries, parseParams, regionNames, setupHeader } from "/global.js";
|
||||
|
||||
(function()
|
||||
{
|
||||
// Element names specific to this page
|
||||
elements.centerCell = "center-cell";
|
||||
elements.configTable = "config-table";
|
||||
elements.cxnAvg = "cxn-avg";
|
||||
elements.cxnGraph = "cxn-graph";
|
||||
elements.cxnLast = "cxn-last";
|
||||
elements.cxnMax = "cxn-max";
|
||||
elements.hostname = "hostname";
|
||||
elements.inputLabel = "input-label";
|
||||
elements.ipv4 = "ipv4";
|
||||
elements.ipv6 = "ipv6";
|
||||
elements.lmcRow = "lmc-tr1";
|
||||
elements.lmcRowAlt = "lmc-tr2";
|
||||
elements.loadingConfigs = "loading-configs";
|
||||
elements.location = "location";
|
||||
elements.nodebalancerLabel = "nodebalancer-label";
|
||||
elements.nodebalancerTag = "nodebalancer-tag";
|
||||
elements.nodebalancerTagLink = "nodebalancer-tag-link";
|
||||
elements.removePrefix = "remove-config-";
|
||||
elements.saveButton = "save-button";
|
||||
elements.tableLabel = "table-label";
|
||||
elements.tags = "tags";
|
||||
elements.throttle = "throttle";
|
||||
elements.trafficGraph = "traffic-graph";
|
||||
elements.trafficInAvg = "traffic-in-avg";
|
||||
elements.trafficInLast = "traffic-in-last";
|
||||
elements.trafficInMax = "traffic-in-max";
|
||||
elements.trafficOutAvg = "traffic-out-avg";
|
||||
elements.trafficOutLast = "traffic-out-last";
|
||||
elements.trafficOutMax = "traffic-out-max";
|
||||
elements.transferred = "transferred";
|
||||
|
||||
// Data recieved from API calls
|
||||
var data = {};
|
||||
data.configs = [];
|
||||
data.nodebalancer = {};
|
||||
data.params = {};
|
||||
data.regions = [];
|
||||
data.stats = {};
|
||||
|
||||
// Static references to UI elements
|
||||
var ui = {};
|
||||
ui.configTable = {};
|
||||
ui.cxnAvg = {};
|
||||
ui.cxnGraph = {};
|
||||
ui.cxnLast = {};
|
||||
ui.cxnMax = {};
|
||||
ui.hostname = {};
|
||||
ui.inputLabel = {};
|
||||
ui.ipv4 = {};
|
||||
ui.ipv6 = {};
|
||||
ui.loadingConfigs = {};
|
||||
ui.location = {};
|
||||
ui.nodebalancerLabel = {};
|
||||
ui.nodebalancerTag = {};
|
||||
ui.nodebalancerTagLink = {};
|
||||
ui.saveButton = {};
|
||||
ui.tableLabel = {};
|
||||
ui.tags = {};
|
||||
ui.throttle = {};
|
||||
ui.trafficGraph = {};
|
||||
ui.trafficInAvg = {};
|
||||
ui.trafficInLast = {};
|
||||
ui.trafficInMax = {};
|
||||
ui.trafficOutAvg = {};
|
||||
ui.trafficOutLast = {};
|
||||
ui.trafficOutMax = {};
|
||||
ui.transferred = {};
|
||||
|
||||
// Temporary state
|
||||
var state = {};
|
||||
state.haveNodebalancer = false;
|
||||
state.haveRegions = false;
|
||||
|
||||
// Generate a configuration table row
|
||||
var createConfigRow = function(config, alt)
|
||||
{
|
||||
var row = document.createElement("tr");
|
||||
if (alt)
|
||||
row.className = elements.lmcRowAlt;
|
||||
else
|
||||
row.className = elements.lmcRow;
|
||||
|
||||
var port = document.createElement("td");
|
||||
var portLink = document.createElement("a");
|
||||
portLink.href = "/nodebalancers/config?nbid=" + data.params.nbid + "&nbcid=" + config.id;
|
||||
portLink.innerHTML = "Port " + config.port;
|
||||
port.appendChild(portLink);
|
||||
row.appendChild(port);
|
||||
|
||||
var protocol = document.createElement("td");
|
||||
protocol.innerHTML = config.protocol.toUpperCase();
|
||||
row.appendChild(protocol);
|
||||
|
||||
var algorithmStrings = {
|
||||
"roundrobin": "Round Robin",
|
||||
"leastconn": "Least Connections",
|
||||
"source": "Source IP"
|
||||
};
|
||||
var algorithm = document.createElement("td");
|
||||
if (algorithmStrings[config.algorithm])
|
||||
algorithm.innerHTML = algorithmStrings[config.algorithm];
|
||||
else
|
||||
algorithm.innerHTML = config.algorithm;
|
||||
row.appendChild(algorithm);
|
||||
|
||||
var stickinessStrings = {
|
||||
"none": "None",
|
||||
"table": "Table",
|
||||
"http_cookie": "HTTP Cookie"
|
||||
};
|
||||
var stickiness = document.createElement("td");
|
||||
if (stickinessStrings[config.stickiness])
|
||||
stickiness.innerHTML = stickinessStrings[config.stickiness];
|
||||
else
|
||||
stickiness.innerHTML = config.stickiness;
|
||||
row.appendChild(stickiness);
|
||||
|
||||
var healthStrings = {
|
||||
"none": "None",
|
||||
"connection": "TCP Connection",
|
||||
"http": "HTTP Valid Status",
|
||||
"http_body": "HTTP Body Regex"
|
||||
};
|
||||
var healthCheck = document.createElement("td");
|
||||
if (healthStrings[config.check])
|
||||
healthCheck.innerHTML = healthStrings[config.check];
|
||||
else
|
||||
healthCheck.innerHTML = config.check;
|
||||
row.appendChild(healthCheck);
|
||||
|
||||
var status = document.createElement("td");
|
||||
status.innerHTML = config.nodes_status.up + " up, " + config.nodes_status.down + " down";
|
||||
row.appendChild(status);
|
||||
|
||||
var options = document.createElement("td");
|
||||
options.className = elements.centerCell;
|
||||
var editLink = document.createElement("a");
|
||||
editLink.href = "/nodebalancers/config?nbid=" + data.params.nbid + "&nbcid=" + config.id;
|
||||
editLink.innerHTML = "Edit";
|
||||
var separator = document.createElement("span");
|
||||
separator.innerHTML = " | ";
|
||||
var removeLink = document.createElement("a");
|
||||
removeLink.href = "#";
|
||||
removeLink.id = elements.removePrefix + config.id;
|
||||
removeLink.innerHTML = "Remove";
|
||||
removeLink.addEventListener("click", handleConfigRemove);
|
||||
options.appendChild(editLink);
|
||||
options.appendChild(separator);
|
||||
options.appendChild(removeLink);
|
||||
row.appendChild(options);
|
||||
|
||||
return row;
|
||||
};
|
||||
|
||||
// Callback for nodebalancer configs API call
|
||||
var displayConfigs = function(response)
|
||||
{
|
||||
// Add configs to array
|
||||
data.configs = data.configs.concat(response.data);
|
||||
|
||||
// Request the next page if there are more pages
|
||||
if (response.page != response.pages) {
|
||||
apiGet("/nodebalancers/" + data.params.nbid + "/configs?page=" + (response.page + 1), displayConfigs, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove loading row
|
||||
ui.loadingConfigs.remove();
|
||||
|
||||
// Insert configuration rows into table
|
||||
for (var i = 0; i < data.configs.length; i++)
|
||||
ui.configTable.appendChild(createConfigRow(data.configs[i], i % 2));
|
||||
};
|
||||
|
||||
// Callback for nodebalancer API call
|
||||
var displayNodebalancer = function(response)
|
||||
{
|
||||
data.nodebalancer = response;
|
||||
|
||||
// Set page title and header stuff
|
||||
if (document.title.indexOf("//") == -1)
|
||||
document.title += " // Edit " + data.nodebalancer.label;
|
||||
ui.nodebalancerLabel.innerHTML = data.nodebalancer.label;
|
||||
if (data.nodebalancer.tags.length == 1) {
|
||||
ui.nodebalancerTagLink.href = "/nodebalancers?tag=" + data.nodebalancer.tags[0];
|
||||
ui.nodebalancerTagLink.innerHTML = "(" + data.nodebalancer.tags[0] + ")";
|
||||
ui.nodebalancerTag.style.display = "inline";
|
||||
} else {
|
||||
ui.nodebalancerTag.style.display = "none";
|
||||
}
|
||||
|
||||
// Populate info
|
||||
ui.tableLabel.innerHTML = data.nodebalancer.label;
|
||||
ui.hostname.innerHTML = data.nodebalancer.hostname;
|
||||
ui.ipv4.innerHTML = data.nodebalancer.ipv4;
|
||||
ui.ipv6.innerHTML = data.nodebalancer.ipv6;
|
||||
ui.transferred.innerHTML = countSI(data.nodebalancer.transfer.in * 1048576) + "B in - " + countSI(data.nodebalancer.transfer.out * 1048576) + "B out (" + countSI(data.nodebalancer.transfer.total * 1048576) + "B total)";
|
||||
ui.inputLabel.value = data.nodebalancer.label;
|
||||
ui.throttle.value = data.nodebalancer.client_conn_throttle;
|
||||
ui.tags.value = data.nodebalancer.tags.join(",");
|
||||
|
||||
ui.saveButton.disabled = false;
|
||||
|
||||
state.haveNodebalancer = true;
|
||||
if (state.haveRegions)
|
||||
insertRegion();
|
||||
};
|
||||
|
||||
// Callback for regions API call
|
||||
var displayRegions = function(response)
|
||||
{
|
||||
// Add regions to array
|
||||
data.regions = data.regions.concat(response.data);
|
||||
|
||||
// Request the next page if there are more pages
|
||||
if (response.page != response.pages) {
|
||||
apiGet("/regions?page=" + (response.page + 1), getRegions, null);
|
||||
return;
|
||||
}
|
||||
|
||||
state.haveRegions = true;
|
||||
if (state.haveNodebalancer)
|
||||
insertRegion();
|
||||
};
|
||||
|
||||
// Callback for nodebalancer stats API call
|
||||
var displayStats = function(response)
|
||||
{
|
||||
// Insert dummy points in case of blank data
|
||||
if (!response.data.connections.length)
|
||||
response.data.connections = [[0,0]];
|
||||
if (!response.data.traffic.in.length)
|
||||
response.data.traffic.in = [[0,0]];
|
||||
if (!response.data.traffic.out.length)
|
||||
reponse.data.traffic.out = [[0,0]];
|
||||
|
||||
data.stats.cxn = [{
|
||||
"color": "#906",
|
||||
"fill": true,
|
||||
"points": response.data.connections
|
||||
}];
|
||||
data.stats.traffic = [
|
||||
{
|
||||
"color": "#32CD32",
|
||||
"fill": true,
|
||||
"points": response.data.traffic.out
|
||||
},
|
||||
{
|
||||
"color": "#03C",
|
||||
"fill": false,
|
||||
"points": response.data.traffic.in
|
||||
}
|
||||
];
|
||||
|
||||
// Draw graphs
|
||||
drawSeries(data.stats.cxn, ui.cxnGraph);
|
||||
drawSeries(data.stats.traffic, ui.trafficGraph);
|
||||
|
||||
// Update tables
|
||||
ui.cxnMax.innerHTML = data.stats.cxn[0].max;
|
||||
ui.cxnAvg.innerHTML = data.stats.cxn[0].avg.toFixed(2);
|
||||
ui.cxnLast.innerHTML = data.stats.cxn[0].points[data.stats.cxn[0].points.length - 1][1];
|
||||
ui.trafficOutMax.innerHTML = countSI(data.stats.traffic[1].max) + "b/s";
|
||||
ui.trafficOutAvg.innerHTML = countSI(data.stats.traffic[1].avg) + "b/s";
|
||||
ui.trafficOutLast.innerHTML = countSI(data.stats.traffic[1].points[data.stats.traffic[1].points.length - 1][1]) + "b/s";
|
||||
ui.trafficInMax.innerHTML = countSI(data.stats.traffic[0].max) + "b/s";
|
||||
ui.trafficInAvg.innerHTML = countSI(data.stats.traffic[0].avg) + "b/s";
|
||||
ui.trafficInLast.innerHTML = countSI(data.stats.traffic[0].points[data.stats.traffic[0].points.length - 1][1]) + "b/s";
|
||||
};
|
||||
|
||||
// Click handler for config remove link
|
||||
var handleConfigRemove = function(event)
|
||||
{
|
||||
if (!confirm("Are you sure you want to delete this config?"))
|
||||
return;
|
||||
|
||||
var nbcid = event.currentTarget.id.substring(elements.removePrefix.length);
|
||||
apiDelete("/nodebalancers/" + data.params.nbid + "/configs/" + nbcid, function()
|
||||
{
|
||||
location.reload();
|
||||
});
|
||||
};
|
||||
|
||||
// Click handler for save button
|
||||
var handleSave = function(event)
|
||||
{
|
||||
if (event.currentTarget.disabled)
|
||||
return;
|
||||
|
||||
var req = {
|
||||
"label": ui.inputLabel.value,
|
||||
"client_conn_throttle": parseInt(ui.throttle.value),
|
||||
"tags": []
|
||||
};
|
||||
|
||||
if (ui.tags.value.length)
|
||||
req.tags = ui.tags.value.split(",");
|
||||
|
||||
apiPut("/nodebalancers/" + data.params.nbid, req, function(response)
|
||||
{
|
||||
location.reload();
|
||||
});
|
||||
};
|
||||
|
||||
// Display region info
|
||||
var insertRegion = function()
|
||||
{
|
||||
var regionData = null;
|
||||
for (var i = 0; i < data.regions.length; i++) {
|
||||
if (data.regions[i].id == data.nodebalancer.region) {
|
||||
regionData = data.regions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (regionData && regionData.label && regionData.label.length)
|
||||
ui.location.innerHTML = regionData.label;
|
||||
else if (regionNames[data.nodebalancer.region])
|
||||
ui.location.innerHTML = regionNames[data.nodebalancer.region];
|
||||
else
|
||||
ui.location.innerHTML = data.nodebalancer.region;
|
||||
};
|
||||
|
||||
// Initial setup
|
||||
var setup = function()
|
||||
{
|
||||
// Parse URL parameters
|
||||
data.params = parseParams();
|
||||
|
||||
// We need a NodeBalancer ID, so die if we don't have it
|
||||
if (!data.params.nbid) {
|
||||
alert("No NodeBalancer ID supplied!");
|
||||
return;
|
||||
}
|
||||
|
||||
setupHeader();
|
||||
|
||||
// Update links on page to include proper Linode ID
|
||||
var anchors = document.getElementsByTagName("a");
|
||||
for (var i = 0; i < anchors.length; i++)
|
||||
anchors[i].href = anchors[i].href.replace("nbid=0", "nbid=" + data.params.nbid);
|
||||
|
||||
// Get element references
|
||||
ui.configTable = document.getElementById(elements.configTable);
|
||||
ui.cxnAvg = document.getElementById(elements.cxnAvg);
|
||||
ui.cxnGraph = document.getElementById(elements.cxnGraph);
|
||||
ui.cxnLast = document.getElementById(elements.cxnLast);
|
||||
ui.cxnMax = document.getElementById(elements.cxnMax);
|
||||
ui.hostname = document.getElementById(elements.hostname);
|
||||
ui.inputLabel = document.getElementById(elements.inputLabel);
|
||||
ui.ipv4 = document.getElementById(elements.ipv4);
|
||||
ui.ipv6 = document.getElementById(elements.ipv6);
|
||||
ui.loadingConfigs = document.getElementById(elements.loadingConfigs);
|
||||
ui.location = document.getElementById(elements.location);
|
||||
ui.nodebalancerLabel = document.getElementById(elements.nodebalancerLabel);
|
||||
ui.nodebalancerTag = document.getElementById(elements.nodebalancerTag);
|
||||
ui.nodebalancerTagLink = document.getElementById(elements.nodebalancerTagLink);
|
||||
ui.saveButton = document.getElementById(elements.saveButton);
|
||||
ui.tableLabel = document.getElementById(elements.tableLabel);
|
||||
ui.tags = document.getElementById(elements.tags);
|
||||
ui.throttle = document.getElementById(elements.throttle);
|
||||
ui.trafficGraph = document.getElementById(elements.trafficGraph);
|
||||
ui.trafficInAvg = document.getElementById(elements.trafficInAvg);
|
||||
ui.trafficInLast = document.getElementById(elements.trafficInLast);
|
||||
ui.trafficInMax = document.getElementById(elements.trafficInMax);
|
||||
ui.trafficOutAvg = document.getElementById(elements.trafficOutAvg);
|
||||
ui.trafficOutLast = document.getElementById(elements.trafficOutLast);
|
||||
ui.trafficOutMax = document.getElementById(elements.trafficOutMax);
|
||||
ui.transferred = document.getElementById(elements.transferred);
|
||||
|
||||
// Attach event handlers
|
||||
ui.saveButton.addEventListener("click", handleSave);
|
||||
|
||||
// Set graph resolutions
|
||||
ui.cxnGraph.height = ui.cxnGraph.clientHeight;
|
||||
ui.cxnGraph.width = ui.cxnGraph.clientWidth;
|
||||
ui.trafficGraph.height = ui.trafficGraph.clientHeight;
|
||||
ui.trafficGraph.width = ui.trafficGraph.clientWidth;
|
||||
|
||||
// Get data from the API
|
||||
apiGet("/nodebalancers/" + data.params.nbid, displayNodebalancer, null);
|
||||
apiGet("/regions", displayRegions, null);
|
||||
apiGet("/nodebalancers/" + data.params.nbid + "/configs", displayConfigs, null);
|
||||
apiGet("/nodebalancers/" + data.params.nbid + "/stats", displayStats, null);
|
||||
};
|
||||
|
||||
// Attach onload handler
|
||||
window.addEventListener("load", setup);
|
||||
})();
|
162
nodebalancers/balancer/index.shtml
Normal file
162
nodebalancers/balancer/index.shtml
Normal file
@ -0,0 +1,162 @@
|
||||
<!--
|
||||
This file is part of Linode Manager Classic.
|
||||
|
||||
Linode Manager Classic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Linode Manager Classic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>LMC - NodeBalancers</title>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" type="text/css" href="balancer.css" />
|
||||
<script src="balancer.js" type="module"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!--#include virtual="/include/header.html"-->
|
||||
<div id="main-content" class="wrapper">
|
||||
<div id="top-links"><a href="/nodebalancers">NodeBalancers</a> » <span id="nodebalancer-tag"><a id="nodebalancer-tag-link" href=""></a> » </span><span id="nodebalancer-label" class="top-links-title"></span></div>
|
||||
<div id="nodebalancer-details">
|
||||
<table class="lmc-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td colspan="7">Configurations</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Port</td>
|
||||
<td>Protocol</td>
|
||||
<td>Algorithm</td>
|
||||
<td>Session Stickiness</td>
|
||||
<td>Health Check Method</td>
|
||||
<td>Node Status</td>
|
||||
<td class="center-cell">Options</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="config-table">
|
||||
<tr id="loading-configs" class="lmc-tr3">
|
||||
<td colspan="7">Loading configurations...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="sub-links"><a href="/nodebalancers/config?nbid=0&nbcid=0">Create Configuration</a></p>
|
||||
<table class="lmc-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td id="table-label" colspan="3"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">NodeBalancer Settings</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="settings-table">
|
||||
<tr class="lmc-tr3">
|
||||
<td>Hostname</td>
|
||||
<td id="hostname"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="lmc-tr3">
|
||||
<td>IPv4 Address</td>
|
||||
<td id="ipv4"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="lmc-tr3">
|
||||
<td>IPv6 Address</td>
|
||||
<td id="ipv6"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="lmc-tr3">
|
||||
<td>Location</td>
|
||||
<td id="location"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="lmc-tr3">
|
||||
<td>Transferred this Month</td>
|
||||
<td id="transferred"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="lmc-tr3">
|
||||
<td>NodeBalancer Label</td>
|
||||
<td><input id="input-label" type="text" value="" size="24" /></td>
|
||||
<td class="info">Rename your NodeBalancer</td>
|
||||
</tr>
|
||||
<tr class="lmc-tr3">
|
||||
<td>Client Connection Throttle</td>
|
||||
<td><input id="throttle" type="number" min="0" max="20" value="0" size="4" /></td>
|
||||
<td class="info">To help mitigate abuse, throttle connections from a single client IP to this number per second. 0 to disable.</td>
|
||||
</tr>
|
||||
<tr class="lmc-tr3">
|
||||
<td>Tags</td>
|
||||
<td><input id="tags" type="text" size="24" /> (comma-separated)</td>
|
||||
<td class="info">Group NodeBalancers together on the NodeBalancers tab using tags!</td>
|
||||
</tr>
|
||||
<tr class="lmc-tr3">
|
||||
<td></td>
|
||||
<td><button disabled id="save-button" type="button">Save Changes</button></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Graphs</h3>
|
||||
<div class="lmc-graph">
|
||||
<h4>Connections (CXN/s) - Last 24 Hours</h4>
|
||||
<canvas id="cxn-graph"></canvas>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>Max</td>
|
||||
<td>Avg</td>
|
||||
<td>Last</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><div id="cxn-color" class="lmc-graph-color"></div> Connections</td>
|
||||
<td id="cxn-max"></td>
|
||||
<td id="cxn-avg"></td>
|
||||
<td id="cxn-last"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h4>Traffic (bits/s) - Last 24 Hours</h4>
|
||||
<canvas id="traffic-graph"></canvas>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>Max</td>
|
||||
<td>Avg</td>
|
||||
<td>Last</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><div id="traffic-out-color" class="lmc-graph-color"></div> Outgoing</td>
|
||||
<td id="traffic-out-max"></td>
|
||||
<td id="traffic-out-avg"></td>
|
||||
<td id="traffic-out-last"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="traffic-in-color" class="lmc-graph-color"></div> Incoming</td>
|
||||
<td id="traffic-in-max"></td>
|
||||
<td id="traffic-in-avg"></td>
|
||||
<td id="traffic-in-last"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user