Pretty IPv6 PTR. Use the actual IPv6 address when editing PTR.

Rather than dealing with ip6.arpa-dotted-strings from hell, you can
now edit IPv6 PTR-records using the IPv6 address.
This commit is contained in:
Joachim Tingvold 2016-08-19 23:04:20 +00:00
parent 4ff755bc20
commit 671a319e93
3 changed files with 69 additions and 24 deletions

View File

@ -7,6 +7,9 @@ import urlparse
import itertools import itertools
import traceback import traceback
import onetimepass import onetimepass
import dns.inet
import dns.name
import dns.reversename
from datetime import datetime from datetime import datetime
from distutils.version import StrictVersion from distutils.version import StrictVersion
@ -32,6 +35,7 @@ PDNS_STATS_URL = app.config['PDNS_STATS_URL']
PDNS_API_KEY = app.config['PDNS_API_KEY'] PDNS_API_KEY = app.config['PDNS_API_KEY']
PDNS_VERSION = app.config['PDNS_VERSION'] PDNS_VERSION = app.config['PDNS_VERSION']
API_EXTENDED_URL = utils.pdns_api_extended_uri(PDNS_VERSION) API_EXTENDED_URL = utils.pdns_api_extended_uri(PDNS_VERSION)
PRETTY_IPV6_PTR = app.config['PRETTY_IPV6_PTR']
# Flag for pdns v4.x.x # Flag for pdns v4.x.x
# TODO: Find another way to do this # TODO: Find another way to do this
@ -741,7 +745,14 @@ class Record(object):
if NEW_SCHEMA: if NEW_SCHEMA:
rrsets = jdata['rrsets'] rrsets = jdata['rrsets']
for rrset in rrsets: for rrset in rrsets:
rrset['name'] = rrset['name'].rstrip('.') r_name = rrset['name'].rstrip('.')
if PRETTY_IPV6_PTR: # only if activated
if rrset['type'] == 'PTR': # only ptr
if 'ip6.arpa' in r_name: # only if v6-ptr
v6_addr = dns.reversename.to_address(dns.name.from_text(r_name))
r_name = v6_addr
rrset['name'] = r_name
rrset['content'] = rrset['records'][0]['content'] rrset['content'] = rrset['records'][0]['content']
rrset['disabled'] = rrset['records'][0]['disabled'] rrset['disabled'] = rrset['records'][0]['disabled']
return {'records': rrsets} return {'records': rrsets}
@ -837,13 +848,40 @@ class Record(object):
""" """
Apply record changes to domain Apply record changes to domain
""" """
deleted_records, new_records = self.compare(domain, post_records) records = []
for r in post_records:
r_name = domain if r['record_name'] in ['@', ''] else r['record_name'] + '.' + domain
r_type = r['record_type']
if PRETTY_IPV6_PTR: # only if activated
if NEW_SCHEMA: # only if new schema
if r_type == 'PTR': # only ptr
if ':' in r['record_name']: # dirty ipv6 check
r_name = r['record_name']
record = {
"name": r_name,
"type": r_type,
"content": r['record_data'],
"disabled": True if r['record_status'] == 'Disabled' else False,
"ttl": int(r['record_ttl']) if r['record_ttl'] else 3600,
}
records.append(record)
deleted_records, new_records = self.compare(domain, records)
records = [] records = []
for r in deleted_records: for r in deleted_records:
r_name = r['name'] + '.' if NEW_SCHEMA else r['name']
r_type = r['type']
if PRETTY_IPV6_PTR: # only if activated
if NEW_SCHEMA: # only if new schema
if r_type == 'PTR': # only ptr
if ':' in r['name']: # dirty ipv6 check
r_name = dns.reversename.from_address(r['name']).to_text()
record = { record = {
"name": r['name'] + '.' if NEW_SCHEMA else r['name'], "name": r_name,
"type": r['type'], "type": r_type,
"changetype": "DELETE", "changetype": "DELETE",
"records": [ "records": [
] ]
@ -855,9 +893,16 @@ class Record(object):
records = [] records = []
for r in new_records: for r in new_records:
if NEW_SCHEMA: if NEW_SCHEMA:
r_name = r['name'] + '.'
r_type = r['type']
if PRETTY_IPV6_PTR: # only if activated
if r_type == 'PTR': # only ptr
if ':' in r['name']: # dirty ipv6 check
r_name = r['name']
record = { record = {
"name": r['name'] + '.', "name": r_name,
"type": r['type'], "type": r_type,
"changetype": "REPLACE", "changetype": "REPLACE",
"ttl": r['ttl'], "ttl": r['ttl'],
"records": [ "records": [
@ -891,10 +936,19 @@ class Record(object):
records = sorted(records, key = lambda item: (item["name"], item["type"], item["changetype"])) records = sorted(records, key = lambda item: (item["name"], item["type"], item["changetype"]))
for key, group in itertools.groupby(records, lambda item: (item["name"], item["type"], item["changetype"])): for key, group in itertools.groupby(records, lambda item: (item["name"], item["type"], item["changetype"])):
if NEW_SCHEMA: if NEW_SCHEMA:
r_name = key[0]
r_type = key[1]
r_changetype = key[2]
if PRETTY_IPV6_PTR: # only if activated
if r_type == 'PTR': # only ptr
if ':' in r_name: # dirty ipv6 check
r_name = dns.reversename.from_address(r_name).to_text()
new_record = { new_record = {
"name": key[0], "name": r_name,
"type": key[1], "type": r_type,
"changetype": key[2], "changetype": r_changetype,
"ttl": None, "ttl": None,
"records": [] "records": []
} }

View File

@ -311,6 +311,7 @@ def domain(domain_name):
if jr['type'] in app.config['RECORDS_ALLOW_EDIT']: if jr['type'] in app.config['RECORDS_ALLOW_EDIT']:
record = Record(name=jr['name'], type=jr['type'], status='Disabled' if jr['disabled'] else 'Active', ttl=jr['ttl'], data=jr['content']) record = Record(name=jr['name'], type=jr['type'], status='Disabled' if jr['disabled'] else 'Active', ttl=jr['ttl'], data=jr['content'])
records.append(record) records.append(record)
return render_template('domain.html', domain=domain, records=records, editable_records=app.config['RECORDS_ALLOW_EDIT']) return render_template('domain.html', domain=domain, records=records, editable_records=app.config['RECORDS_ALLOW_EDIT'])
else: else:
return redirect(url_for('error', code=404)) return redirect(url_for('error', code=404))
@ -408,24 +409,11 @@ def record_apply(domain_name):
try: try:
pdata = request.data pdata = request.data
jdata = json.loads(pdata) jdata = json.loads(pdata)
records = []
for j in jdata:
record = {
"name": domain_name if j['record_name'] in ['@', ''] else j['record_name'] + '.' + domain_name,
"type": j['record_type'],
"content": j['record_data'],
"disabled": True if j['record_status'] == 'Disabled' else False,
"name": domain_name if j['record_name'] in ['@', ''] else j['record_name'] + '.' + domain_name,
"ttl": int(j['record_ttl']) if j['record_ttl'] else 3600,
"type": j['record_type'],
}
records.append(record)
r = Record() r = Record()
result = r.apply(domain_name, records) result = r.apply(domain_name, jdata)
if result['status'] == 'ok': if result['status'] == 'ok':
history = History(msg='Apply record changes to domain %s' % domain_name, detail=str(records), created_by=current_user.username) history = History(msg='Apply record changes to domain %s' % domain_name, detail=str(jdata), created_by=current_user.username)
history.add() history.add()
return make_response(jsonify( result ), 200) return make_response(jsonify( result ), 200)
else: else:

View File

@ -76,3 +76,6 @@ PDNS_VERSION = '3.4.7'
# RECORDS ALLOWED TO EDIT # RECORDS ALLOWED TO EDIT
RECORDS_ALLOW_EDIT = ['A', 'AAAA', 'CNAME', 'SPF', 'PTR', 'MX', 'TXT'] RECORDS_ALLOW_EDIT = ['A', 'AAAA', 'CNAME', 'SPF', 'PTR', 'MX', 'TXT']
# EXPERIMENTAL FEATURES
PRETTY_IPV6_PTR = False