diff --git a/CHANGELOG.md b/CHANGELOG.md index e1fd456b..91d1d82d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Control panel: * Backblaze B2 is now a supported backup protocol. * Fixed an issue in the daily mail reports. +* Sort the Custom DNS by zone and qname, and add an option to go back to the old sort order (creation order). Mail: diff --git a/management/daemon.py b/management/daemon.py index a0cfefa6..8490ee44 100755 --- a/management/daemon.py +++ b/management/daemon.py @@ -277,17 +277,50 @@ def dns_set_secondary_nameserver(): @app.route('/dns/custom') @authorized_personnel_only def dns_get_records(qname=None, rtype=None): - from dns_update import get_custom_dns_config - return json_response([ - { - "qname": r[0], - "rtype": r[1], - "value": r[2], - } - for r in get_custom_dns_config(env) - if r[0] != "_secondary_nameserver" - and (not qname or r[0] == qname) - and (not rtype or r[1] == rtype) ]) + # Get the current set of custom DNS records. + from dns_update import get_custom_dns_config, get_dns_zones + records = get_custom_dns_config(env, only_real_records=True) + + # Filter per the arguments for the more complex GET routes below. + records = [r for r in records + if (not qname or r[0] == qname) + and (not rtype or r[1] == rtype) ] + + # Make a better data structure. + records = [ + { + "qname": r[0], + "rtype": r[1], + "value": r[2], + "sort-order": { }, + } for r in records ] + + # To help with grouping by zone in qname sorting, label each record with which zone it is in. + # There's an inconsistency in how we handle zones in get_dns_zones and in sort_domains, so + # do this first before sorting the domains within the zones. + zones = utils.sort_domains([z[0] for z in get_dns_zones(env)], env) + for r in records: + for z in zones: + if r["qname"] == z or r["qname"].endswith("." + z): + r["zone"] = z + break + + # Add sorting information. The 'created' order follows the order in the YAML file on disk, + # which tracs the order entries were added in the control panel since we append to the end. + # The 'qname' sort order sorts by our standard domain name sort (by zone then by qname), + # then by rtype, and last by the original order in the YAML file (since sorting by value + # may not make sense, unless we parse IP addresses, for example). + for i, r in enumerate(records): + r["sort-order"]["created"] = i + domain_sort_order = utils.sort_domains([r["qname"] for r in records], env) + for i, r in enumerate(sorted(records, key = lambda r : ( + zones.index(r["zone"]), + domain_sort_order.index(r["qname"]), + r["rtype"]))): + r["sort-order"]["qname"] = i + + # Return. + return json_response(records) @app.route('/dns/custom/', methods=['GET', 'POST', 'PUT', 'DELETE']) @app.route('/dns/custom//', methods=['GET', 'POST', 'PUT', 'DELETE']) diff --git a/management/dns_update.py b/management/dns_update.py index 781fb1dc..b2901bc8 100755 --- a/management/dns_update.py +++ b/management/dns_update.py @@ -753,7 +753,7 @@ def write_opendkim_tables(domains, env): ######################################################################## -def get_custom_dns_config(env): +def get_custom_dns_config(env, only_real_records=False): try: custom_dns = rtyaml.load(open(os.path.join(env['STORAGE_ROOT'], 'dns/custom.yaml'))) if not isinstance(custom_dns, dict): raise ValueError() # caught below @@ -761,6 +761,8 @@ def get_custom_dns_config(env): return [ ] for qname, value in custom_dns.items(): + if qname == "_secondary_nameserver" and only_real_records: continue # skip fake record + # Short form. Mapping a domain name to a string is short-hand # for creating A records. if isinstance(value, str): diff --git a/management/templates/aliases.html b/management/templates/aliases.html index 848fcf49..3d37c4fd 100644 --- a/management/templates/aliases.html +++ b/management/templates/aliases.html @@ -153,8 +153,8 @@ function show_aliases() { function(r) { $('#alias_table tbody').html(""); for (var i = 0; i < r.length; i++) { - var hdr = $("

"); - hdr.find('h4').text(r[i].domain); + var hdr = $(""); + hdr.find('th').text(r[i].domain); $('#alias_table tbody').append(hdr); for (var k = 0; k < r[i].aliases.length; k++) { diff --git a/management/templates/custom-dns.html b/management/templates/custom-dns.html index b1b98b9b..c59624eb 100644 --- a/management/templates/custom-dns.html +++ b/management/templates/custom-dns.html @@ -57,7 +57,13 @@ - +
+ sort by: + domain name + | + created +
+ @@ -192,36 +198,38 @@ function show_current_custom_dns() { $('#custom-dns-current').fadeIn(); else $('#custom-dns-current').fadeOut(); - - var reverse_fqdn = function(el) { - el.qname = el.qname.split('.').reverse().join('.'); - return el; - } - var sort = function(a, b) { - if(a.qname === b.qname) { - if(a.rtype === b.rtype) { - return a.value > b.value ? 1 : -1; - } - return a.rtype > b.rtype ? 1 : -1; - } - return a.qname > b.qname ? 1 : -1; - } + window.miab_custom_dns_data = data; + show_current_custom_dns_update_after_sort(); + }); +} - data = data.map(reverse_fqdn).sort(sort).map(reverse_fqdn); +function show_current_custom_dns_update_after_sort() { + var data = window.miab_custom_dns_data; + var sort_key = window.miab_custom_dns_data_sort_order || "qname"; - $('#custom-dns-current').find("tbody").text(''); + data.sort(function(a, b) { return a["sort-order"][sort_key] - b["sort-order"][sort_key] }); + + var tbody = $('#custom-dns-current').find("tbody"); + tbody.text(''); + var last_zone = null; for (var i = 0; i < data.length; i++) { + if (sort_key == "qname" && data[i].zone != last_zone) { + var r = $(""); + r.find("th").text(data[i].zone); + tbody.append(r); + last_zone = data[i].zone; + } + var tr = $(""); - $('#custom-dns-current').find("tbody").append(tr); + tbody.append(tr); tr.attr('data-qname', data[i].qname); tr.attr('data-rtype', data[i].rtype); tr.attr('data-value', data[i].value); tr.append($('')); } - }); } function delete_custom_dns_record(elem) { diff --git a/management/templates/users.html b/management/templates/users.html index 4b349875..24adf4a1 100644 --- a/management/templates/users.html +++ b/management/templates/users.html @@ -1,7 +1,6 @@

Users