mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-11-09 23:20:27 +00:00
Re-add pretty_ipv6_ptr. Bug fixes
This commit is contained in:
parent
95fe2a8a85
commit
5ac58d5503
@ -1,5 +1,5 @@
|
|||||||
|
import re
|
||||||
import traceback
|
import traceback
|
||||||
import itertools
|
|
||||||
import dns.reversename
|
import dns.reversename
|
||||||
import dns.inet
|
import dns.inet
|
||||||
import dns.name
|
import dns.name
|
||||||
@ -113,7 +113,14 @@ class Record(object):
|
|||||||
|
|
||||||
def add(self, domain_name, rrset):
|
def add(self, domain_name, rrset):
|
||||||
"""
|
"""
|
||||||
Add a record to a domain (a reverse domain name)
|
Add a record to a domain (Used by auto_ptr and DynDNS)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
domain_name(str): The zone name
|
||||||
|
rrset(dict): The record in PDNS rrset format
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(dict): A dict contains status code and message
|
||||||
"""
|
"""
|
||||||
# Validate record first
|
# Validate record first
|
||||||
rrsets = self.get_rrsets(domain_name)
|
rrsets = self.get_rrsets(domain_name)
|
||||||
@ -131,46 +138,6 @@ class Record(object):
|
|||||||
headers = {}
|
headers = {}
|
||||||
headers['X-API-Key'] = self.PDNS_API_KEY
|
headers['X-API-Key'] = self.PDNS_API_KEY
|
||||||
|
|
||||||
# if self.NEW_SCHEMA:
|
|
||||||
# data = {
|
|
||||||
# "rrsets": [{
|
|
||||||
# "name":
|
|
||||||
# self.name.rstrip('.') + '.',
|
|
||||||
# "type":
|
|
||||||
# self.type,
|
|
||||||
# "changetype":
|
|
||||||
# "REPLACE",
|
|
||||||
# "ttl":
|
|
||||||
# self.ttl,
|
|
||||||
# "records": [{
|
|
||||||
# "content": self.data,
|
|
||||||
# "disabled": self.status,
|
|
||||||
# }],
|
|
||||||
# "comments":
|
|
||||||
# [self.comment_data] if self.comment_data else []
|
|
||||||
# }]
|
|
||||||
# }
|
|
||||||
# else:
|
|
||||||
# data = {
|
|
||||||
# "rrsets": [{
|
|
||||||
# "name":
|
|
||||||
# self.name,
|
|
||||||
# "type":
|
|
||||||
# self.type,
|
|
||||||
# "changetype":
|
|
||||||
# "REPLACE",
|
|
||||||
# "records": [{
|
|
||||||
# "content": self.data,
|
|
||||||
# "disabled": self.status,
|
|
||||||
# "name": self.name,
|
|
||||||
# "ttl": self.ttl,
|
|
||||||
# "type": self.type
|
|
||||||
# }],
|
|
||||||
# "comments":
|
|
||||||
# [self.comment_data] if self.comment_data else []
|
|
||||||
# }]
|
|
||||||
# }
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
jdata = utils.fetch_json(urljoin(
|
jdata = utils.fetch_json(urljoin(
|
||||||
self.PDNS_STATS_URL, self.API_EXTENDED_URL +
|
self.PDNS_STATS_URL, self.API_EXTENDED_URL +
|
||||||
@ -184,8 +151,10 @@ class Record(object):
|
|||||||
return {'status': 'ok', 'msg': 'Record was added successfully'}
|
return {'status': 'ok', 'msg': 'Record was added successfully'}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
"Cannot add record {0}/{1}/{2} to domain {3}. DETAIL: {4}".
|
"Cannot add record to domain {}. Error: {}".format(
|
||||||
format(self.name, self.type, self.data, domain_name, e))
|
domain_name, e))
|
||||||
|
current_app.logger.debug("Submitted record rrset: \n{}".format(
|
||||||
|
utils.pretty_json(rrset)))
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg':
|
'msg':
|
||||||
@ -226,11 +195,26 @@ class Record(object):
|
|||||||
rrsets = []
|
rrsets = []
|
||||||
for record in submitted_records:
|
for record in submitted_records:
|
||||||
# Format the record name
|
# Format the record name
|
||||||
record_name = "{}.{}.".format(
|
#
|
||||||
record["record_name"],
|
# If it is ipv6 reverse zone and PRETTY_IPV6_PTR is enabled,
|
||||||
domain_name) if record["record_name"] not in [
|
# We convert ipv6 address back to reverse record format
|
||||||
'@', ''
|
# before submitting to PDNS API.
|
||||||
] else domain_name + '.'
|
if self.PRETTY_IPV6_PTR and re.search(r'ip6\.arpa', domain_name):
|
||||||
|
if record['record_type'] == 'PTR' and ':' in record[
|
||||||
|
'record_name']:
|
||||||
|
record_name = dns.reversename.from_address(
|
||||||
|
record['record_name']).to_text()
|
||||||
|
|
||||||
|
# Else, it is forward zone, then record name should be
|
||||||
|
# in format "<name>.<domain>.". If it is root
|
||||||
|
# domain name (name == '@' or ''), the name should
|
||||||
|
# be in format "<domain>."
|
||||||
|
else:
|
||||||
|
record_name = "{}.{}.".format(
|
||||||
|
record["record_name"],
|
||||||
|
domain_name) if record["record_name"] not in [
|
||||||
|
'@', ''
|
||||||
|
] else domain_name + '.'
|
||||||
|
|
||||||
# Format the record content, it musts end
|
# Format the record content, it musts end
|
||||||
# with a dot character if in following types
|
# with a dot character if in following types
|
||||||
@ -249,7 +233,7 @@ class Record(object):
|
|||||||
record_comments = [{
|
record_comments = [{
|
||||||
"content": record["record_comment"],
|
"content": record["record_comment"],
|
||||||
"account": ""
|
"account": ""
|
||||||
}] if record["record_comment"] else []
|
}] if record.get("record_comment") else []
|
||||||
|
|
||||||
# Add the formatted record to rrsets list
|
# Add the formatted record to rrsets list
|
||||||
rrsets.append({
|
rrsets.append({
|
||||||
@ -267,7 +251,7 @@ class Record(object):
|
|||||||
# Sort the list before using groupby
|
# Sort the list before using groupby
|
||||||
rrsets = sorted(rrsets, key=lambda r: (r['name'], r['type']))
|
rrsets = sorted(rrsets, key=lambda r: (r['name'], r['type']))
|
||||||
groups = groupby(rrsets, key=lambda r: (r['name'], r['type']))
|
groups = groupby(rrsets, key=lambda r: (r['name'], r['type']))
|
||||||
for k, v in groups:
|
for _k, v in groups:
|
||||||
group = list(v)
|
group = list(v)
|
||||||
transformed_rrsets.append(self.merge_rrsets(group))
|
transformed_rrsets.append(self.merge_rrsets(group))
|
||||||
|
|
||||||
@ -336,38 +320,6 @@ class Record(object):
|
|||||||
# Get the list of rrsets to be added and deleted
|
# Get the list of rrsets to be added and deleted
|
||||||
new_rrsets, del_rrsets = self.compare(domain_name, submitted_records)
|
new_rrsets, del_rrsets = self.compare(domain_name, submitted_records)
|
||||||
|
|
||||||
# records = []
|
|
||||||
# for r in deleted_records:
|
|
||||||
# r_name = r['name'].rstrip(
|
|
||||||
# '.') + '.' if self.NEW_SCHEMA else r['name']
|
|
||||||
# r_type = r['type']
|
|
||||||
# if self.PRETTY_IPV6_PTR: # only if activated
|
|
||||||
# if self.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 = {
|
|
||||||
# "name": r_name,
|
|
||||||
# "type": r_type,
|
|
||||||
# "changetype": "DELETE",
|
|
||||||
# "records": []
|
|
||||||
# }
|
|
||||||
# records.append(record)
|
|
||||||
|
|
||||||
# postdata_for_delete = {"rrsets": records}
|
|
||||||
|
|
||||||
# records = []
|
|
||||||
# for r in new_records:
|
|
||||||
# if self.NEW_SCHEMA:
|
|
||||||
# r_name = r['name'].rstrip('.') + '.'
|
|
||||||
# r_type = r['type']
|
|
||||||
# if self.PRETTY_IPV6_PTR: # only if activated
|
|
||||||
# if r_type == 'PTR': # only ptr
|
|
||||||
# if ':' in r['name']: # dirty ipv6 check
|
|
||||||
# r_name = r['name']
|
|
||||||
|
|
||||||
# Submit the changes to PDNS API
|
# Submit the changes to PDNS API
|
||||||
try:
|
try:
|
||||||
headers = {}
|
headers = {}
|
||||||
|
@ -3,7 +3,7 @@ import json
|
|||||||
import traceback
|
import traceback
|
||||||
from ast import literal_eval
|
from ast import literal_eval
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
from flask import Blueprint, render_template, make_response, url_for, current_app, request, redirect, jsonify, abort
|
from flask import Blueprint, render_template, make_response, url_for, current_app, request, redirect, jsonify, abort, flash
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
|
|
||||||
from ..decorators import operator_role_required, admin_role_required
|
from ..decorators import operator_role_required, admin_role_required
|
||||||
@ -843,7 +843,7 @@ def create_template_from_zone():
|
|||||||
for jr in jrecords:
|
for jr in jrecords:
|
||||||
if jr['type'] in Setting().get_records_allow_to_edit():
|
if jr['type'] in Setting().get_records_allow_to_edit():
|
||||||
name = '@' if jr['name'] == domain_name else re.sub(
|
name = '@' if jr['name'] == domain_name else re.sub(
|
||||||
'\.{}$'.format(domain_name), '', jr['name'])
|
r'\.{}$'.format(domain_name), '', jr['name'])
|
||||||
for subrecord in jr['records']:
|
for subrecord in jr['records']:
|
||||||
record = DomainTemplateRecord(
|
record = DomainTemplateRecord(
|
||||||
name=name,
|
name=name,
|
||||||
@ -858,7 +858,7 @@ def create_template_from_zone():
|
|||||||
for jr in jrecords:
|
for jr in jrecords:
|
||||||
if jr['type'] in Setting().get_records_allow_to_edit():
|
if jr['type'] in Setting().get_records_allow_to_edit():
|
||||||
name = '@' if jr['name'] == domain_name else re.sub(
|
name = '@' if jr['name'] == domain_name else re.sub(
|
||||||
'\.{}$'.format(domain_name), '', jr['name'])
|
r'\.{}$'.format(domain_name), '', jr['name'])
|
||||||
record = DomainTemplateRecord(
|
record = DomainTemplateRecord(
|
||||||
name=name,
|
name=name,
|
||||||
type=jr['type'],
|
type=jr['type'],
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
import traceback
|
import traceback
|
||||||
|
import dns.name
|
||||||
|
import dns.reversename
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
from flask import Blueprint, render_template, make_response, url_for, current_app, request, redirect, abort, jsonify
|
from flask import Blueprint, render_template, make_response, url_for, current_app, request, redirect, abort, jsonify
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
@ -63,15 +65,27 @@ def domain(domain_name):
|
|||||||
if StrictVersion(Setting().get('pdns_version')) >= StrictVersion('4.0.0'):
|
if StrictVersion(Setting().get('pdns_version')) >= StrictVersion('4.0.0'):
|
||||||
for r in rrsets:
|
for r in rrsets:
|
||||||
if r['type'] in records_allow_to_edit:
|
if r['type'] in records_allow_to_edit:
|
||||||
|
r_name = r['name'].rstrip('.')
|
||||||
|
|
||||||
|
# If it is reverse zone and pretty_ipv6_ptr setting
|
||||||
|
# is enabled, we reformat the name for ipv6 records.
|
||||||
|
if Setting().get('pretty_ipv6_ptr') and r[
|
||||||
|
'type'] == 'PTR' and 'ip6.arpa' in r_name:
|
||||||
|
r_name = dns.reversename.to_address(
|
||||||
|
dns.name.from_text(r_name))
|
||||||
|
|
||||||
|
# Create the list of records in format that
|
||||||
|
# PDA jinja2 template can understand.
|
||||||
index = 0
|
index = 0
|
||||||
for record in r['records']:
|
for record in r['records']:
|
||||||
record_entry = RecordEntry(
|
record_entry = RecordEntry(
|
||||||
name=r['name'].rstrip('.'),
|
name=r_name,
|
||||||
type=r['type'],
|
type=r['type'],
|
||||||
status='Disabled' if record['disabled'] else 'Active',
|
status='Disabled' if record['disabled'] else 'Active',
|
||||||
ttl=r['ttl'],
|
ttl=r['ttl'],
|
||||||
data=record['content'],
|
data=record['content'],
|
||||||
comment=r['comments'][index]['content'] if r['comments'] else '',
|
comment=r['comments'][index]['content']
|
||||||
|
if r['comments'] else '',
|
||||||
is_allowed_edit=True)
|
is_allowed_edit=True)
|
||||||
index += 1
|
index += 1
|
||||||
records.append(record_entry)
|
records.append(record_entry)
|
||||||
@ -79,7 +93,7 @@ def domain(domain_name):
|
|||||||
# Unsupported version
|
# Unsupported version
|
||||||
abort(500)
|
abort(500)
|
||||||
|
|
||||||
if not re.search('ip6\.arpa|in-addr\.arpa$', domain_name):
|
if not re.search(r'ip6\.arpa|in-addr\.arpa$', domain_name):
|
||||||
editable_records = forward_records_allow_to_edit
|
editable_records = forward_records_allow_to_edit
|
||||||
else:
|
else:
|
||||||
editable_records = reverse_records_allow_to_edit
|
editable_records = reverse_records_allow_to_edit
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import json
|
import json
|
||||||
import traceback
|
import traceback
|
||||||
import datetime
|
import datetime
|
||||||
@ -423,7 +424,7 @@ def dyndns_update():
|
|||||||
|
|
||||||
domain = None
|
domain = None
|
||||||
domain_segments = hostname.split('.')
|
domain_segments = hostname.split('.')
|
||||||
for index in range(len(domain_segments)):
|
for _index in range(len(domain_segments)):
|
||||||
full_domain = '.'.join(domain_segments)
|
full_domain = '.'.join(domain_segments)
|
||||||
potential_domain = Domain.query.filter(
|
potential_domain = Domain.query.filter(
|
||||||
Domain.name == full_domain).first()
|
Domain.name == full_domain).first()
|
||||||
@ -489,12 +490,23 @@ def dyndns_update():
|
|||||||
DomainSetting.setting == 'create_via_dyndns').first()
|
DomainSetting.setting == 'create_via_dyndns').first()
|
||||||
if (ondemand_creation is not None) and (strtobool(
|
if (ondemand_creation is not None) and (strtobool(
|
||||||
ondemand_creation.value) == True):
|
ondemand_creation.value) == True):
|
||||||
record = Record(name=hostname,
|
|
||||||
type=rtype,
|
# Build the rrset
|
||||||
data=str(ip),
|
rrset_data = [{
|
||||||
status=False,
|
"changetype": "REPLACE",
|
||||||
ttl=3600)
|
"name": hostname + '.',
|
||||||
result = record.add(domain.name)
|
"ttl": 3600,
|
||||||
|
"type": rtype,
|
||||||
|
"records": [{
|
||||||
|
"content": str(ip),
|
||||||
|
"disabled": False
|
||||||
|
}],
|
||||||
|
"comments": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
# Format the rrset
|
||||||
|
rrset = {"rrsets": rrset_data}
|
||||||
|
result = Record().add(domain.name, rrset)
|
||||||
if result['status'] == 'ok':
|
if result['status'] == 'ok':
|
||||||
history = History(
|
history = History(
|
||||||
msg=
|
msg=
|
||||||
@ -679,7 +691,7 @@ def handle_account(account_name):
|
|||||||
clean_name = ''.join(c for c in account_name.lower()
|
clean_name = ''.join(c for c in account_name.lower()
|
||||||
if c in "abcdefghijklmnopqrstuvwxyz0123456789")
|
if c in "abcdefghijklmnopqrstuvwxyz0123456789")
|
||||||
if len(clean_name) > Account.name.type.length:
|
if len(clean_name) > Account.name.type.length:
|
||||||
logging.error(
|
current_app.logger.error(
|
||||||
"Account name {0} too long. Truncated.".format(clean_name))
|
"Account name {0} too long. Truncated.".format(clean_name))
|
||||||
account = Account.query.filter_by(name=clean_name).first()
|
account = Account.query.filter_by(name=clean_name).first()
|
||||||
if not account:
|
if not account:
|
||||||
|
Loading…
Reference in New Issue
Block a user