/* * 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, apiGet, apiPost, parseParams, setupHeader } from "/global.js"; (function() { // Element names specific to this page elements.destClass = "dest-ip"; elements.destLinode = "dest-linode"; elements.doIt = "do-it"; elements.info = "info"; elements.linodeLabel = "linode-label"; elements.linodeSelect = "linode-select"; elements.linodeTag = "linode-tag"; elements.linodeTagLink = "linode-tag-link"; elements.lmcRow = "lmc-tr3"; elements.privateIPs = "private-ips"; elements.publicIPs = "public-ips"; elements.selectButton = "select-button"; elements.srcClass = "src-ip"; elements.srcLinode = "src-linode"; elements.subnav = "subnav-link"; elements.subnavActive = "subnav-link-active"; // Data recieved from API calls var data = {}; data.destNet = {}; data.linode = {}; data.linodes = []; data.srcNet = {}; // Static references to UI elements var ui = {}; ui.destLinode = {}; ui.doIt = {}; ui.linodeLabel = {}; ui.linodeSelect = {}; ui.linodeTag = {}; ui.linodeTagLink = {}; ui.privateIPs = {}; ui.publicIPs = {}; ui.selectButton = {}; ui.srcLinode = {}; // Temporary state var state = {}; state.destIndex = -1; state.haveDest = false; state.haveSrc = false; // Callback for destination linode network details API call var displayDestNet = function(response) { data.destNet = response; state.haveDest = true; if (state.haveSrc) displayIPs(); }; // Callback for linode details API call var displayDetails = function(response) { data.linode = response; // Set page title and header stuff document.title += " // " + data.linode.label; ui.linodeLabel.innerHTML = data.linode.label; ui.srcLinode.innerHTML = data.linode.label; if (data.linode.tags.length == 1) { ui.linodeTagLink.href = "/linodes?tag=" + data.linode.tags[0]; ui.linodeTagLink.innerHTML = "(" + data.linode.tags[0] + ")"; ui.linodeTag.style.display = "inline"; } // Get other Linodes in the same DC var filter = { "region": data.linode.region }; apiGet("/linode/instances", displayLinodes, filter); apiGet("/linode/instances/" + data.params.lid + "/ips", displaySrcNet, null); }; // Populate swap table with source and dest IPs var displayIPs = function() { // Add public IPs var numIPs = Math.max(data.srcNet.ipv4["public"].length, data.destNet.ipv4["public"].length); for (var i = 0; i < numIPs; i++) { var row = document.createElement("tr"); row.className = elements.lmcRow; var srcAddr = document.createElement("td"); var srcMove = document.createElement("td"); if (data.srcNet.ipv4["public"][i]) { var ip = document.createElement("span"); ip.innerHTML = data.srcNet.ipv4["public"][i].address; var br = document.createElement("br"); var rdns = document.createElement("span"); rdns.className = elements.info; rdns.innerHTML = data.srcNet.ipv4["public"][i].rdns; srcAddr.appendChild(ip); srcAddr.appendChild(br); srcAddr.appendChild(rdns); var move = document.createElement("input"); move.id = data.srcNet.ipv4["public"][i].address; move.className = elements.srcClass; move.type = "checkbox"; srcMove.appendChild(move); } row.appendChild(srcAddr); row.appendChild(srcMove); var arrow = document.createElement("td"); arrow.innerHTML = "↔"; row.appendChild(arrow); var destAddr = document.createElement("td"); var destMove = document.createElement("td"); if (data.destNet.ipv4["public"][i]) { var ip = document.createElement("span"); ip.innerHTML = data.destNet.ipv4["public"][i].address; var br = document.createElement("br"); var rdns = document.createElement("span"); rdns.className = elements.info; rdns.innerHTML = data.destNet.ipv4["public"][i].rdns; destAddr.appendChild(ip); destAddr.appendChild(br); destAddr.appendChild(rdns); var move = document.createElement("input"); move.id = data.destNet.ipv4["public"][i].address; move.className = elements.destClass; move.type = "checkbox"; destMove.appendChild(move); } row.appendChild(destMove); row.appendChild(destAddr); ui.publicIPs.appendChild(row); } // Add private IPs var numIPs = Math.max(data.srcNet.ipv4["private"].length, data.destNet.ipv4["private"].length); for (var i = 0; i < numIPs; i++) { var row = document.createElement("tr"); row.className = elements.lmcRow; var srcAddr = document.createElement("td"); var srcMove = document.createElement("td"); if (data.srcNet.ipv4["private"][i]) { var ip = document.createElement("span"); ip.innerHTML = data.srcNet.ipv4["private"][i].address; var br = document.createElement("br"); var rdns = document.createElement("span"); rdns.className = elements.info; rdns.innerHTML = data.srcNet.ipv4["private"][i].rdns; srcAddr.appendChild(ip); srcAddr.appendChild(br); srcAddr.appendChild(rdns); var move = document.createElement("input"); move.id = data.srcNet.ipv4["private"][i].address; move.className = elements.srcClass; move.type = "checkbox"; srcMove.appendChild(move); } row.appendChild(srcAddr); row.appendChild(srcMove); var arrow = document.createElement("td"); arrow.innerHTML = "↔"; row.appendChild(arrow); var destAddr = document.createElement("td"); var destMove = document.createElement("td"); if (data.destNet.ipv4["private"][i]) { var ip = document.createElement("span"); ip.innerHTML = data.destNet.ipv4["private"][i].address; var br = document.createElement("br"); var rdns = document.createElement("span"); rdns.className = elements.info; rdns.innerHTML = data.destNet.ipv4["private"][i].rdns; destAddr.appendChild(ip); destAddr.appendChild(br); destAddr.appendChild(rdns); var move = document.createElement("input"); move.id = data.destNet.ipv4["private"][i].address; move.className = elements.destClass; move.type = "checkbox"; destMove.appendChild(move); } row.appendChild(destMove); row.appendChild(destAddr); ui.privateIPs.appendChild(row); } ui.doIt.disabled = false; ui.selectButton.disabled = false; }; // Callback for linodes API call var displayLinodes = function(response) { // Add linodes to array data.linodes = data.linodes.concat(response.data); // Request the next page if there are more pages if (response.page != response.pages) { var filter = { "region": data.linode.region }; apiGet("/linode/instances?page=" + (response.page + 1), displayLinodes, filter); return; } // Add linodes to selector for (var i = 0; i < data.linodes.length; i++) { if (data.linodes[i].id == data.linode.id) continue; var option = document.createElement("option"); option.value = data.linodes[i].id; option.innerHTML = data.linodes[i].label; ui.linodeSelect.appendChild(option); } ui.selectButton.disabled = false; }; // Callback for source linode network details API call var displaySrcNet = function(response) { data.srcNet = response; state.haveSrc = true; if (state.haveDest) displayIPs(); }; // Handler for select button var handleSelect = function(event) { if (event.currentTarget.disabled) return; state.haveDest = false; var lid = parseInt(ui.linodeSelect.value); for (var i = 0; i < data.linodes.length; i++) { if (data.linodes[i].id == lid) { state.destIndex = i; break; } } if (state.destIndex == -1) return; ui.doIt.disabled = true; ui.selectButton.disabled = true; ui.publicIPs.innerHTML = ""; ui.privateIPs.innerHTML = ""; ui.destLinode.innerHTML = data.linodes[state.destIndex].label; apiGet("/linode/instances/" + data.linodes[state.destIndex].id + "/ips", displayDestNet, null); }; // Handler for "do it" button var handleSwap = function(event) { if (event.currentTarget.disabled) return; var assignments = []; // Assign all checked source IPs to the destination Linode var srcBoxes = document.getElementsByClassName(elements.srcClass); for (var i = 0; i < srcBoxes.length; i++) { if (!srcBoxes[i].checked) continue; assignments.push({ "address": srcBoxes[i].id, "linode_id": data.linodes[state.destIndex].id }); } // Assign all checked destination IPs to the source Linode var destBoxes = document.getElementsByClassName(elements.destClass); for (var i = 0; i < destBoxes.length; i++) { if (!destBoxes[i].checked) continue; assignments.push({ "address": destBoxes[i].id, "linode_id": data.linode.id }); } if (!assignments.length) return; var req = { "assignments": assignments, "region": data.linode.region }; apiPost("/networking/ipv4/assign", req, function(response) { location.href = "/linodes/remote_access?lid=" + data.params.lid; }); }; // Initial setup var setup = function() { // Parse URL parameters data.params = parseParams(); // We need a Linode ID, so die if we don't have it if (!data.params.lid) { alert("No Linode 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("lid=0", "lid=" + data.params.lid); // Highlight the remote access subnav link var subnavLinks = document.getElementsByClassName(elements.subnav); for (var i = 0; i < subnavLinks.length; i++) { if (subnavLinks[i].pathname == "/linodes/remote_access") subnavLinks[i].className += " " + elements.subnavActive; } // Get element references ui.destLinode = document.getElementById(elements.destLinode); ui.doIt = document.getElementById(elements.doIt); ui.linodeLabel = document.getElementById(elements.linodeLabel); ui.linodeSelect = document.getElementById(elements.linodeSelect); ui.linodeTag = document.getElementById(elements.linodeTag); ui.linodeTagLink = document.getElementById(elements.linodeTagLink); ui.privateIPs = document.getElementById(elements.privateIPs); ui.publicIPs = document.getElementById(elements.publicIPs); ui.selectButton = document.getElementById(elements.selectButton); ui.srcLinode = document.getElementById(elements.srcLinode); // Add event handlers ui.selectButton.addEventListener("click", handleSelect); ui.doIt.addEventListener("click", handleSwap); // Get data from API apiGet("/linode/instances/" + data.params.lid, displayDetails, null); }; // Attach onload handler window.addEventListener("load", setup); })();