Added all DNS functionality

This commit is contained in:
2020-01-18 17:50:00 -05:00
parent 4e033be21b
commit 1ffa87a980
29 changed files with 2980 additions and 1 deletions

226
dns/resource/index.shtml Normal file
View File

@ -0,0 +1,226 @@
<!--
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 - Edit Resource</title>
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<link rel="stylesheet" type="text/css" href="resource.css" />
<script src="resource.js" type="module"></script>
</head>
<body>
<!--#include virtual="/include/header.html"-->
<div id="main-content" class="wrapper">
<div id="top-links"><a href="/dns">DNS Manager</a> » <span id="domain-tag"><a id="domain-tag-link" href=""></a> » </span><a id="domain-label" href="/dns/domain?did=0"></a> » <span class="top-links-title">Edit Resource Record</span></div>
<div id="resource">
<table class="lmc-table">
<thead class="a resource-section">
<tr>
<td colspan="3">Add/edit an A/AAAA Record</td>
</tr>
</thead>
<tbody class="a resource-section">
<tr class="lmc-tr3">
<td>Hostname</td>
<td><input id="a-hostname" type="text" size="30" /></td>
<td class="info">Example: www.example.com</td>
</tr>
<tr class="lmc-tr3">
<td>IP Address</td>
<td><input id="a-ip" type="text" size="30" /></td>
<td></td>
</tr>
</tbody>
<tbody class="caa resource-section lmc-tbody-head">
<tr>
<td colspan="3">Add/edit a CAA Record</td>
</tr>
</tbody>
<tbody class="caa resource-section lmc-tbody-head">
<tr class="lmc-tr3">
<td>Subdomain</td>
<td><input id="caa-subdomain" type="text" size="30" /></td>
<td class="info">See Linode's <a href="https://www.linode.com/docs/quick-answers/linode-platform/add-caa-dns-records" target="_blank">CAA records guide</a> for more info.</td>
</tr>
<tr class="lmc-tr3">
<td>Tag</td>
<td>
<select id="caa-tag">
<option value="issue">issue</option>
<option value="issuewild">issuewild</option>
<option value="iodef">iodef</option>
</select>
</td>
<td></td>
</tr>
<tr class="lmc-tr3">
<td>Value</td>
<td><input id="caa-value" type="text" size="50" /></td>
<td></td>
</tr>
</tbody>
<tbody class="cname resource-section lmc-tbody-head">
<tr>
<td colspan="3">Add/edit a CNAME Record</td>
</tr>
</tbody>
<tbody class="cname resource-section">
<tr class="lmc-tr3">
<td>Hostname</td>
<td><input id="cname-hostname" type="text" size="30" /></td>
<td class="info">Example: www.example.com</td>
</tr>
<tr class="lmc-tr3">
<td>Aliases to</td>
<td><input id="cname-alias" type="text" size="30" /></td>
<td class="info">Example: www.example.org</td>
</tr>
</tbody>
<tbody class="mx resource-section lmc-tbody-head">
<tr>
<td colspan="3">Add/edit an MX Record</td>
</tr>
</tbody>
<tbody class="mx resource-section">
<tr class="lmc-tr3">
<td>Mail Server</td>
<td><input id="mx-server" type="text" size="30" /></td>
<td class="info">Example: mail2.example.com</td>
</tr>
<tr class="lmc-tr3">
<td>Priority</td>
<td><input id="mx-priority" type="number" min="0" max="255" /></td>
<td class="info">0-255</td>
</tr>
<tr class="lmc-tr3">
<td>Subdomain</td>
<td><input id="mx-subdomain" type="text" size="30" /></td>
<td class="info">Leave blank unless delegating a subdomain to the mail server above. A wildcard is also valid here.</td>
</tr>
</tbody>
<tbody class="ns resource-section lmc-tbody-head">
<tr>
<td colspan="3">Add/edit an NS Record</td>
</tr>
</tbody>
<tbody class="ns resource-section">
<tr class="lmc-tr3">
<td>Name Server</td>
<td><input id="ns-nameserver" type="text" size="30" /></td>
<td class="info">Example: ns1.example.com</td>
</tr>
<tr class="lmc-tr3">
<td>Subdomain</td>
<td><input id="ns-subdomain" type="text" size="30" /></td>
<td class="info">Leave this blank unless you're delegating a subdomain to the nameserver above.</td>
</tr>
</tbody>
<tbody class="srv resource-section lmc-tbody-head">
<tr>
<td colspan="3">Add/edit an SRV Record</td>
</tr>
</tbody>
<tbody class="srv resource-section">
<tr class="lmc-tr3">
<td>Service</td>
<td><input id="srv-service" type="text" size="30" /></td>
<td class="info">Example: _sip</td>
</tr>
<tr class="lmc-tr3">
<td>Protocol</td>
<td>
<select id="srv-protocol">
<option value="tcp">tcp</option>
<option value="udp">udp</option>
<option disabled value="xmpp">xmpp</option>
<option disabled value="tls">tls</option>
<option disabled value="smtp">smtp</option>
</select>
</td>
<td></td>
</tr>
<tr class="lmc-tr3">
<td>Target</td>
<td><input id="srv-target" type="text" size="30" /></td>
<td></td>
</tr>
<tr class="lmc-tr3">
<td>Priority</td>
<td><input id="srv-priority" type="number" min="0" max="65535" value="10" /></td>
<td class="info">0-65535</td>
</tr>
<tr class="lmc-tr3">
<td>Weight</td>
<td><input id="srv-weight" type="number" min="0" max="65535" value="5" /></td>
<td class="info">0-65535</td>
</tr>
<tr class="lmc-tr3">
<td>Port</td>
<td><input id="srv-port" type="number" min="0" max="65535" value="80" /></td>
<td class="info">0-65535</td>
</tr>
</tbody>
<tbody class="txt resource-section lmc-tbody-head">
<tr>
<td colspan="3">Add/edit a TXT Record</td>
</tr>
</tbody>
<tbody class="txt resource-section">
<tr class="lmc-tr3">
<td>Name</td>
<td><input id="txt-name" type="text" size="30" /></td>
<td></td>
</tr>
<tr class="lmc-tr3">
<td>Value</td>
<td><input id="txt-value" type="text" size="50" /></td>
<td></td>
</tr>
</tbody>
<tbody>
<tr class="lmc-tr3">
<td>TTL</td>
<td>
<select id="ttl">
<option value="0">Default</option>
<option value="300">300 (5 minutes)</option>
<option value="3600">3600 (1 hour)</option>
<option value="7200">7200 (2 hours)</option>
<option value="14400">14400 (4 hours)</option>
<option value="28800">28800 (8 hours)</option>
<option value="57600">57600 (16 hours)</option>
<option value="86400">86400 (1 day)</option>
<option value="172800">172800 (2 days)</option>
<option value="345600">345600 (4 days)</option>
<option value="604800">604800 (1 week)</option>
<option value="1209600">1209600 (2 weeks)</option>
<option value="2419200">2419200 (4 weeks)</option>
</select>
</td>
<td></td>
</tr>
<tr class="lmc-tr3">
<td></td>
<td colspan="2"><button disabled id="save-button" type="button">Save Changes</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

36
dns/resource/resource.css Normal file
View File

@ -0,0 +1,36 @@
/*
* 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');
#resource {
padding: 0px 15px 15px;
}
.resource-section {
display: none;
}
tbody:not(.lmc-tbody-head) tr td:first-of-type {
font-weight: bold;
text-align: right;
white-space: nowrap;
}
tbody:not(.lmc-tbody-head):not(.resource-section) tr:last-of-type {
border: none;
}

315
dns/resource/resource.js Normal file
View File

@ -0,0 +1,315 @@
/*
* 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, apiGet, apiPost, apiPut, parseParams, setupHeader } from "/global.js";
(function()
{
// Element names specific to this page
elements.a = "a";
elements.aHostname = "a-hostname";
elements.aIP = "a-ip";
elements.caa = "caa";
elements.caaSubdomain = "caa-subdomain";
elements.caaTag = "caa-tag";
elements.caaValue = "caa-value";
elements.cname = "cname";
elements.cnameHostname = "cname-hostname";
elements.cnameAlias = "cname-alias";
elements.domainLabel = "domain-label";
elements.domainTag = "domain-tag";
elements.domainTagLink = "domain-tag-link";
elements.mx = "mx";
elements.mxServer = "mx-server";
elements.mxPriority = "mx-priority";
elements.mxSubdomain = "mx-subdomain";
elements.ns = "ns";
elements.nsNameserver = "ns-nameserver";
elements.nsSubdomain = "ns-subdomain";
elements.saveButton = "save-button";
elements.srv = "srv";
elements.srvService = "srv-service";
elements.srvProtocol = "srv-protocol";
elements.srvTarget = "srv-target";
elements.srvPriority = "srv-priority";
elements.srvWeight = "srv-weight";
elements.srvPort = "srv-port";
elements.ttl = "ttl";
elements.txt = "txt";
elements.txtName = "txt-name";
elements.txtValue = "txt-value";
// Data recieved from API calls
var data = {};
data.domain = {};
data.record = {};
// Static references to UI elements
var ui = {};
ui.a = [];
ui.aHostname = {};
ui.aIP = {};
ui.caa = [];
ui.caaSubdomain = {};
ui.caaTag = {};
ui.caaValue = {};
ui.cname = [];
ui.cnameHostname = {};
ui.cnameAlias = {};
ui.domainLabel = {};
ui.domainTag = {};
ui.domainTagLink = {};
ui.mx = [];
ui.mxServer = {};
ui.mxPriority = {};
ui.mxSubdomain = {};
ui.ns = [];
ui.nsNameserver = {};
ui.nsSubdomain = {};
ui.saveButton = {};
ui.srv = [];
ui.srvService = {};
ui.srvProtocol = {};
ui.srvTarget = {};
ui.srvPriority = {};
ui.srvWeight = {};
ui.srvPort = {};
ui.ttl = {};
ui.txt = [];
ui.txtName = {};
ui.txtValue = {};
// Callback for domain details API call
var displayDetails = function(response)
{
data.domain = response;
// Set page title and header stuff
document.title += " // " + data.domain.domain;
ui.domainLabel.innerHTML = data.domain.domain;
if (data.domain.tags.length == 1) {
ui.domainTagLink.href = "/dns?tag=" + data.domain.tags[0];
ui.domainTagLink.innerHTML = "(" + data.domain.tags[0] + ")";
ui.domainTag.style.display = "inline";
}
};
// Callback for record details API call
var displayRecord = function(response)
{
data.record = response;
// Display controls for record type
data.record.type = data.record.type.toLowerCase();
for (var i = 0; i < ui[data.record.type].length; i++)
ui[data.record.type][i].style.display = "table-row-group";
// Fill in form data
switch (data.record.type) {
case "a":
case "aaaa":
ui.aHostname.value = data.record.name;
ui.aIP.value = data.record.target;
break;
case "caa":
ui.caaSubdomain.value = data.record.name;
ui.caaTag.value = data.record.tag;
ui.caaValue.value = data.record.target;
break;
case "cname":
ui.cnameHostname.value = data.record.name;
ui.cnameAlias.value = data.record.target;
break;
case "mx":
ui.mxServer.value = data.record.target;
ui.mxPriority.value = data.record.priority;
ui.mxSubdomain.value = data.record.name;
break;
case "ns":
ui.nsNameserver.value = data.record.target;
ui.nsSubdomain.value = data.record.name;
break;
case "srv":
if (data.record.service.charAt(0) == "_")
ui.srvService.value = data.record.service;
else
ui.srvService.value = "_" + data.record.service;
ui.srvProtocol.value = data.record.protocol;
ui.srvTarget.value = data.record.target;
ui.srvPriority.value = data.record.priority;
ui.srvWeight.value = data.record.weight;
ui.srvPort.value = data.record.port;
break;
case "txt":
ui.txtName.value = data.record.name;
ui.txtValue.value = data.record.target;
break;
}
ui.ttl.value = data.record.ttl_sec;
ui.saveButton.disabled = false;
};
// Click handler for save button
var handleSave = function(event)
{
if (event.currentTarget.disabled)
return;
var type;
if (data.record.type)
type = data.record.type;
else
type = data.params.type;
var req = {
"ttl_sec": parseInt(ui.ttl.value),
"type": type.toUpperCase()
};
switch (type) {
case "a":
case "aaaa":
req.name = ui.aHostname.value;
req.target = ui.aIP.value;
break;
case "caa":
req.name = ui.caaSubdomain.value;
req.tag = ui.caaTag.value;
req.target = ui.caaValue.value;
break;
case "cname":
req.name = ui.cnameHostname.value;
req.target = ui.cnameAlias.value;
break;
case "mx":
req.target = ui.mxServer.value;
req.priority = parseInt(ui.mxPriority.value);
req.name = ui.mxSubdomain.value;
break;
case "ns":
req.target = ui.nsNameserver.value;
req.name = ui.nsSubdomain.value;
break;
case "srv":
req.service = ui.srvService.value;
req.protocol = ui.srvProtocol.value;
req.target = ui.srvTarget.value;
req.priority = parseInt(ui.srvPriority.value);
req.weight = parseInt(ui.srvWeight.value);
req.port = parseInt(ui.srvPort.value);
break;
case "txt":
req.name = ui.txtName.value;
req.target = ui.txtValue.value;
break;
}
var callback = function(response)
{
location.href = "/dns/domain?did=" + data.params.did;
};
if (data.params.rid == "0")
apiPost("/domains/" + data.params.did + "/records", req, callback);
else
apiPut("/domains/" + data.params.did + "/records/" + data.params.rid, req, callback);
};
// Initial setup
var setup = function()
{
// Parse URL parameters
data.params = parseParams();
// We need a domain ID, so die if we don't have it
if (!data.params.did) {
alert("No domain ID supplied!");
return;
}
// We also need a resource ID
if (!data.params.rid) {
alert("No resource ID supplied!");
return;
}
// If this is a new resource, we also need a resource type
if (data.params.rid == "0" && !data.params.type) {
alert("No resource type 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("did=0", "did=" + data.params.did);
// Get element references
ui.a = document.getElementsByClassName(elements.a);
ui.aHostname = document.getElementById(elements.aHostname);
ui.aIP = document.getElementById(elements.aIP);
ui.caa = document.getElementsByClassName(elements.caa);
ui.caaSubdomain = document.getElementById(elements.caaSubdomain);
ui.caaTag = document.getElementById(elements.caaTag);
ui.caaValue = document.getElementById(elements.caaValue);
ui.cname = document.getElementsByClassName(elements.cname);
ui.cnameHostname = document.getElementById(elements.cnameHostname);
ui.cnameAlias = document.getElementById(elements.cnameAlias);
ui.domainLabel = document.getElementById(elements.domainLabel);
ui.domainTag = document.getElementById(elements.domainTag);
ui.domainTagLink = document.getElementById(elements.domainTagLink);
ui.mx = document.getElementsByClassName(elements.mx);
ui.mxServer = document.getElementById(elements.mxServer);
ui.mxPriority = document.getElementById(elements.mxPriority);
ui.mxSubdomain = document.getElementById(elements.mxSubdomain);
ui.ns = document.getElementsByClassName(elements.ns);
ui.nsNameserver = document.getElementById(elements.nsNameserver);
ui.nsSubdomain = document.getElementById(elements.nsSubdomain);
ui.saveButton = document.getElementById(elements.saveButton);
ui.srv = document.getElementsByClassName(elements.srv);
ui.srvService = document.getElementById(elements.srvService);
ui.srvProtocol = document.getElementById(elements.srvProtocol);
ui.srvTarget = document.getElementById(elements.srvTarget);
ui.srvPriority = document.getElementById(elements.srvPriority);
ui.srvWeight = document.getElementById(elements.srvWeight);
ui.srvPort = document.getElementById(elements.srvPort);
ui.ttl = document.getElementById(elements.ttl);
ui.txt = document.getElementsByClassName(elements.txt);
ui.txtName = document.getElementById(elements.txtName);
ui.txtValue = document.getElementById(elements.txtValue);
// Display controls for given type
if (data.params.rid == "0") {
for (var i = 0; i < ui[data.params.type].length; i++)
ui[data.params.type][i].style.display = "table-row-group";
ui.saveButton.disabled = false;
}
// Attach event handlers
ui.saveButton.addEventListener("click", handleSave);
// Get data from API
apiGet("/domains/" + data.params.did, displayDetails, null);
if (data.params.rid != "0")
apiGet("/domains/" + data.params.did + "/records/" + data.params.rid, displayRecord, null);
};
// Attach onload handler
window.addEventListener("load", setup);
})();