/* * 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 . */ import { settings, elements, apiDelete, apiGet, apiPost, apiPut, parseParams, setupHeader } from "/global.js"; (function() { // Element names specific to this page elements.algorithm = "algorithm"; elements.centerCell = "center-cell"; elements.checkAttempts = "check-attempts"; elements.checkBody = "check-body"; elements.checkInterval = "check-interval"; elements.checkPath = "check-path"; elements.checkShow = "check-show"; elements.checkTimeout = "check-timeout"; elements.checkType = "check-type"; elements.cipherSuite = "cipher-suite"; elements.commonName = "common-name"; elements.configLabel = "config-label"; elements.fingerprint = "fingerprint"; elements.lmcRow = "lmc-tr1"; elements.lmcRowAlt = "lmc-tr2"; elements.nodebalancerLabel = "nodebalancer-label"; elements.nodebalancerTag = "nodebalancer-tag"; elements.nodebalancerTagLink = "nodebalancer-tag-link"; elements.nodesTable = "nodes-table"; elements.nonzero = "nonzero"; elements.passive = "passive"; elements.port = "port"; elements.protocol = "protocol"; elements.protocolShow = "protocol-show"; elements.proxyProtocol = "proxy-protocol"; elements.removePrefix = "remove-node-"; elements.replaceCert = "replace-cert"; elements.replaceCertOnly = "replace-cert-only"; elements.replaceLink = "replace-link"; elements.saveButton = "save-button"; elements.sslCert = "ssl-cert"; elements.sslKey = "ssl-key"; elements.stickiness = "stickiness"; // Data recieved from API calls var data = {}; data.config = {}; data.nodebalancer = {}; data.nodes = []; // Static references to UI elements var ui = {}; ui.algorithm = {}; ui.checkAttempts = {}; ui.checkBody = {}; ui.checkInterval = {}; ui.checkPath = {}; ui.checkShow = []; ui.checkTimeout = {}; ui.checkType = {}; ui.cipherSuite = {}; ui.commonName = {}; ui.configLabel = {}; ui.fingerprint = {}; ui.nodebalancerLabel = {}; ui.nodebalancerTag = {}; ui.nodebalancerTagLink = {}; ui.nodesTable = {}; ui.passive = {}; ui.port = {}; ui.protocol = {}; ui.protocolShow = []; ui.proxyProtocol = {}; ui.saveButton = {}; ui.replaceLink = {}; ui.sslCert = {}; ui.sslKey = {}; ui.stickiness = {}; // Temporary State var state = {}; state.replaceCert = true; // Create a row for the nodes table var createNodeRow = function(node, alt) { var row = document.createElement("tr"); if (alt) row.className = elements.lmcRowAlt; else row.className = elements.lmcRow; var label = document.createElement("td"); label.innerHTML = node.label; row.appendChild(label); var address = document.createElement("td"); var lastColon = node.address.lastIndexOf(":"); address.innerHTML = node.address.slice(0, lastColon); row.appendChild(address); var port = document.createElement("td"); port.innerHTML = node.address.slice(lastColon + 1); row.appendChild(port); var weight = document.createElement("td"); weight.innerHTML = node.weight; row.appendChild(weight); var mode = document.createElement("td"); mode.innerHTML = node.mode.charAt(0).toUpperCase() + node.mode.slice(1); row.appendChild(mode); var status = document.createElement("td"); status.innerHTML = node.status; row.appendChild(status); var options = document.createElement("td"); options.className = elements.centerCell; var editLink = document.createElement("a"); editLink.href = "/nodebalancers/node?nbid=" + data.params.nbid + "&nbcid=" + data.params.nbcid + "&nbnid=" + node.id; editLink.innerHTML = "Edit"; var separator = document.createElement("span"); separator.innerHTML = " | "; var removeLink = document.createElement("a"); removeLink.id = elements.removePrefix + node.id; removeLink.href = "#"; removeLink.innerHTML = "Remove"; removeLink.addEventListener("click", handleRemoveNode); options.appendChild(editLink); options.appendChild(separator); options.appendChild(removeLink); row.appendChild(options); return row; }; // Callback for config API call var displayConfig = function(response) { data.config = response; ui.configLabel.innerHTML = "Port " + data.config.port; ui.port.value = data.config.port; ui.protocol.value = data.config.protocol; ui.proxyProtocol.value = data.config.proxy_protocol; ui.algorithm.value = data.config.algorithm; ui.stickiness.value = data.config.stickiness; ui.commonName.innerHTML = data.config.ssl_commonname; ui.fingerprint.innerHTML = data.config.ssl_fingerprint; ui.cipherSuite.value = data.config.cipher_suite; ui.checkType.value = data.config.check; ui.checkInterval.value = data.config.check_interval; ui.checkTimeout.value = data.config.check_timeout; ui.checkAttempts.value = data.config.check_attempts; ui.checkPath.value = data.config.check_path; ui.checkBody.value = data.config.check_body; ui.passive.checked = data.config.check_passive; state.replaceCert = (!data.config.ssl_key || data.config.ssl_key.indexOf("") == -1); ui.saveButton.disabled = false; showHideChecks(); showHideProtocol(); }; // 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"; } }; // Callback for nodes API call var displayNodes = function(response) { data.nodes = data.nodes.concat(response.data); // Request the next page if there are more pages if (response.page != response.pages) { apiGet("/nodebalancers/" + data.params.nbid + "/configs/" + data.params.nbcid + "/nodes?page=" + (response.page + 1), displayNodes, null); return; } // Insert nodes into table for (var i = 0; i < data.nodes.length; i++) ui.nodesTable.appendChild(createNodeRow(data.nodes[i], i % 2)); }; // Remove node handler var handleRemoveNode = function(event) { if (!confirm("Are you sure you want to remove this node?")) return; var nbnid = event.currentTarget.id.substring(elements.removePrefix.length); apiDelete("/nodebalancers/" + data.params.nbid + "/configs/" + data.params.nbcid + "/nodes/" + nbnid, function() { location.reload(); }); }; // Replace link handler var handleReplace = function(event) { state.replaceCert = true; showHideProtocol(); }; // Save button handler var handleSave = function(event) { if (event.currentTarget.disabled) return; var req = { "port": parseInt(ui.port.value), "protocol": ui.protocol.value, "algorithm": ui.algorithm.value, "stickiness": ui.stickiness.value, "check": ui.checkType.value, "check_passive": ui.passive.checked }; if (ui.protocol.value == "tcp") { req.proxy_protocol = ui.proxyProtocol.value; } else if (ui.protocol.value == "https") { req.cipher_suite = ui.cipherSuite.value; if (state.replaceCert) { req.ssl_cert = ui.sslCert.value; req.ssl_key = ui.sslKey.value; } } switch (ui.checkType.value) { case "http_body": req.check_body = ui.checkBody.value; case "http": req.check_path = ui.checkPath.value; case "connection": req.check_interval = parseInt(ui.checkInterval.value); req.check_timeout = parseInt(ui.checkTimeout.value); req.check_attempts = parseInt(ui.checkAttempts.value); } if (data.params.nbcid == 0) { apiPost("/nodebalancers/" + data.params.nbid + "/configs", req, function(response) { location.href = "/nodebalancers/config?nbid=" + data.params.nbid + "&nbcid=" + response.id; }); } else { apiPut("/nodebalancers/" + data.params.nbid + "/configs/" + data.params.nbcid, req, function(response) { location.href = "/nodebalancers/balancer?nbid=" + data.params.nbid; }); } }; // 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; } // We also need a config ID if (!data.params.nbcid) { alert("No config 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); anchors[i].href = anchors[i].href.replace("nbcid=0", "nbcid=" + data.params.nbcid); } // Get element references ui.algorithm = document.getElementById(elements.algorithm); ui.checkAttempts = document.getElementById(elements.checkAttempts); ui.checkBody = document.getElementById(elements.checkBody); ui.checkInterval = document.getElementById(elements.checkInterval); ui.checkPath = document.getElementById(elements.checkPath); ui.checkShow = document.getElementsByClassName(elements.checkShow); ui.checkTimeout = document.getElementById(elements.checkTimeout); ui.checkType = document.getElementById(elements.checkType); ui.cipherSuite = document.getElementById(elements.cipherSuite); ui.commonName = document.getElementById(elements.commonName); ui.configLabel = document.getElementById(elements.configLabel); ui.fingerprint = document.getElementById(elements.fingerprint); ui.nodebalancerLabel = document.getElementById(elements.nodebalancerLabel); ui.nodebalancerTag = document.getElementById(elements.nodebalancerTag); ui.nodebalancerTagLink = document.getElementById(elements.nodebalancerTagLink); ui.nodesTable = document.getElementById(elements.nodesTable); ui.passive = document.getElementById(elements.passive); ui.port = document.getElementById(elements.port); ui.protocol = document.getElementById(elements.protocol); ui.protocolShow = document.getElementsByClassName(elements.protocolShow); ui.proxyProtocol = document.getElementById(elements.proxyProtocol); ui.replaceLink = document.getElementById(elements.replaceLink); ui.saveButton = document.getElementById(elements.saveButton); ui.sslCert = document.getElementById(elements.sslCert); ui.sslKey = document.getElementById(elements.sslKey); ui.stickiness = document.getElementById(elements.stickiness); // Register event handlers ui.checkType.addEventListener("input", showHideChecks); ui.protocol.addEventListener("input", showHideProtocol); ui.replaceLink.addEventListener("click", handleReplace); ui.saveButton.addEventListener("click", handleSave); // Get data from API apiGet("/nodebalancers/" + data.params.nbid, displayNodebalancer, null); if (parseInt(data.params.nbcid)) { apiGet("/nodebalancers/" + data.params.nbid + "/configs/" + data.params.nbcid, displayConfig, null); apiGet("/nodebalancers/" + data.params.nbid + "/configs/" + data.params.nbcid + "/nodes", displayNodes, null); } else { ui.configLabel.innerHTML = "Create Configuration"; ui.saveButton.disabled = false; var hideElements = document.getElementsByClassName(elements.nonzero); for (var i = 0; i < hideElements.length; i++) hideElements[i].style.display = "none"; } }; // Show/hide check rows var showHideChecks = function(event) { for (var i = 0; i < ui.checkShow.length; i++) { if (ui.checkShow[i].classList.contains(elements.checkShow + "-" + ui.checkType.value)) ui.checkShow[i].style.display = "table-row"; else ui.checkShow[i].style.display = "none"; } }; // Show/hide protocol stuff var showHideProtocol = function(event) { for (var i = 0; i < ui.protocolShow.length; i++) { if (ui.protocolShow[i].classList.contains(elements.protocolShow + "-" + ui.protocol.value)) { if (ui.protocolShow[i].classList.contains(elements.replaceCert)) { if (ui.protocolShow[i].classList.contains(elements.replaceCertOnly) == state.replaceCert) ui.protocolShow[i].style.display = "table-row"; else ui.protocolShow[i].style.display = "none"; } else { ui.protocolShow[i].style.display = "table-row"; } } else { ui.protocolShow[i].style.display = "none"; } } if (data.params.nbcid == 0 && ui.protocol.value == "http") ui.port.value = 80; if (data.params.nbcid == 0 && ui.protocol.value == "https") ui.port.value = 443; }; // Attach onload handler window.addEventListener("load", setup); })();