Fix domain template. Drop PDNS 3.x support

This commit is contained in:
Khanh Ngo 2019-12-16 14:23:17 +07:00
parent a891ed38e2
commit 3196297f57
No known key found for this signature in database
GPG key ID: D5FAA6A16150E49E
4 changed files with 49 additions and 147 deletions

View file

@ -3,7 +3,6 @@ import traceback
from flask import current_app
from urllib.parse import urljoin
from distutils.util import strtobool
from distutils.version import StrictVersion
from ..lib import utils
from .base import db, domain_apikey
@ -57,11 +56,6 @@ class Domain(db.Model):
self.PDNS_VERSION = Setting().get('pdns_version')
self.API_EXTENDED_URL = utils.pdns_api_extended_uri(self.PDNS_VERSION)
if StrictVersion(self.PDNS_VERSION) >= StrictVersion('4.0.0'):
self.NEW_SCHEMA = True
else:
self.NEW_SCHEMA = False
def __repr__(self):
return '<Domain {0}>'.format(self.name)
@ -214,9 +208,8 @@ class Domain(db.Model):
headers = {}
headers['X-API-Key'] = self.PDNS_API_KEY
if self.NEW_SCHEMA:
domain_name = domain_name + '.'
domain_ns = [ns + '.' for ns in domain_ns]
domain_name = domain_name + '.'
domain_ns = [ns + '.' for ns in domain_ns]
if soa_edit_api not in ["DEFAULT", "INCREASE", "EPOCH", "OFF"]:
soa_edit_api = 'DEFAULT'

View file

@ -3,7 +3,6 @@ import traceback
import dns.reversename
import dns.inet
import dns.name
from distutils.version import StrictVersion
from flask import current_app
from urllib.parse import urljoin
from distutils.util import strtobool
@ -41,55 +40,6 @@ class Record(object):
self.API_EXTENDED_URL = utils.pdns_api_extended_uri(self.PDNS_VERSION)
self.PRETTY_IPV6_PTR = Setting().get('pretty_ipv6_ptr')
if StrictVersion(self.PDNS_VERSION) >= StrictVersion('4.0.0'):
self.NEW_SCHEMA = True
else:
self.NEW_SCHEMA = False
def get_record_data(self, domain):
"""
Query domain's DNS records via API
"""
headers = {}
headers['X-API-Key'] = self.PDNS_API_KEY
try:
jdata = utils.fetch_json(urljoin(
self.PDNS_STATS_URL, self.API_EXTENDED_URL +
'/servers/localhost/zones/{0}'.format(domain)),
timeout=int(
Setting().get('pdns_api_timeout')),
headers=headers)
except Exception as e:
current_app.logger.error(
"Cannot fetch domain's record data from remote powerdns api. DETAIL: {0}"
.format(e))
return False
if self.NEW_SCHEMA:
rrsets = jdata['rrsets']
for rrset in rrsets:
if rrset['records']:
r_name = rrset['name'].rstrip('.')
if self.PRETTY_IPV6_PTR: # only if activated
if rrset['type'] == 'PTR': # only ptr
if 'ip6.arpa' in r_name: # only if v6-ptr
r_name = dns.reversename.to_address(
dns.name.from_text(r_name))
rrset['name'] = r_name
rrset['content'] = rrset['records'][0]['content']
rrset['disabled'] = rrset['records'][0]['disabled']
# Get the record's comment. PDNS support multiple comments
# per record. However, we are only interested in the 1st
# one, for now.
rrset['comment_data'] = {"content": "", "account": ""}
if rrset['comments']:
rrset['comment_data'] = rrset['comments'][0]
return {'records': rrsets}
return jdata
def get_rrsets(self, domain):
"""
Query domain's rrsets via PDNS API
@ -524,17 +474,13 @@ class Record(object):
"""
Check if record is present within domain records, and if it's present set self to found record
"""
jdata = self.get_record_data(domain)
jrecords = jdata['records']
for jr in jrecords:
if jr['name'] == self.name and jr['type'] == self.type:
self.name = jr['name']
self.type = jr['type']
self.status = jr['disabled']
self.ttl = jr['ttl']
self.data = jr['content']
self.priority = 10
rrsets = self.get_rrsets(domain)
for r in rrsets:
if r['name'].rstrip('.') == self.name and r['type'] == self.type and r['records']:
self.type = r['type']
self.status = r['records'][0]['disabled']
self.ttl = r['ttl']
self.data = r['records'][0]['content']
return True
return False
@ -545,42 +491,23 @@ class Record(object):
headers = {}
headers['X-API-Key'] = self.PDNS_API_KEY
if self.NEW_SCHEMA:
data = {
"rrsets": [{
"name":
self.name + '.',
"type":
self.type,
"ttl":
self.ttl,
"changetype":
"REPLACE",
"records": [{
"content": content,
"disabled": self.status,
}]
data = {
"rrsets": [{
"name":
self.name + '.',
"type":
self.type,
"ttl":
self.ttl,
"changetype":
"REPLACE",
"records": [{
"content": content,
"disabled": self.status,
}]
}
else:
data = {
"rrsets": [{
"name":
self.name,
"type":
self.type,
"changetype":
"REPLACE",
"records": [{
"content": content,
"disabled": self.status,
"name": self.name,
"ttl": self.ttl,
"type": self.type,
"priority": 10
}]
}]
}
}]
}
try:
utils.fetch_json(urljoin(
self.PDNS_STATS_URL, self.API_EXTENDED_URL +

View file

@ -2,7 +2,6 @@ import re
import json
import traceback
from ast import literal_eval
from distutils.version import StrictVersion
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
@ -829,59 +828,42 @@ def create_template_from_zone():
created_by=current_user.username)
history.add()
# After creating the domain in Domain Template in the,
# local DB. We add records into it Record Template.
records = []
r = Record()
domain = Domain.query.filter(Domain.name == domain_name).first()
if domain:
# query domain info from PowerDNS API
zone_info = r.get_record_data(domain.name)
if zone_info:
jrecords = zone_info['records']
if StrictVersion(Setting().get(
'pdns_version')) >= StrictVersion('4.0.0'):
for jr in jrecords:
if jr['type'] in Setting().get_records_allow_to_edit():
name = '@' if jr['name'] == domain_name else re.sub(
r'\.{}$'.format(domain_name), '', jr['name'])
for subrecord in jr['records']:
record = DomainTemplateRecord(
name=name,
type=jr['type'],
status=True
if subrecord['disabled'] else False,
ttl=jr['ttl'],
data=subrecord['content'],
comment=jr['comment_data']['content'])
records.append(record)
else:
for jr in jrecords:
if jr['type'] in Setting().get_records_allow_to_edit():
name = '@' if jr['name'] == domain_name else re.sub(
r'\.{}$'.format(domain_name), '', jr['name'])
record = DomainTemplateRecord(
# Query zone's rrsets from PowerDNS API
rrsets = Record().get_rrsets(domain.name)
if rrsets:
for r in rrsets:
name = '@' if r['name'] == domain_name + '.' else r[
'name'].replace('.{}.'.format(domain_name), '')
for record in r['records']:
t_record = DomainTemplateRecord(
name=name,
type=jr['type'],
status=True if jr['disabled'] else False,
ttl=jr['ttl'],
data=jr['content'],
comment=jr['comment_data']['content'])
records.append(record)
type=r['type'],
status=False if record['disabled'] else True,
ttl=r['ttl'],
data=record['content'])
records.append(t_record)
result_records = t.replace_records(records)
result = t.replace_records(records)
if result_records['status'] == 'ok':
if result['status'] == 'ok':
return make_response(
jsonify({
'status': 'ok',
'msg': result['msg']
}), 200)
else:
# Revert the domain template (remove it)
# ff we cannot add records.
t.delete_template()
return make_response(
jsonify({
'status': 'error',
'msg': result_records['msg']
'msg': result['msg']
}), 500)
else:
@ -918,7 +900,7 @@ def edit_template(template):
record = DomainTemplateRecord(
name=jr.name,
type=jr.type,
status='Disabled' if jr.status else 'Active',
status='Active' if jr.status else 'Disabled',
ttl=jr.ttl,
data=jr.data,
comment=jr.comment if jr.comment else '')
@ -952,14 +934,14 @@ def apply_records(template):
type = j['record_type']
data = j['record_data']
comment = j['record_comment']
disabled = True if j['record_status'] == 'Disabled' else False
status = 0 if j['record_status'] == 'Disabled' else 1
ttl = int(j['record_ttl']) if j['record_ttl'] else 3600
dtr = DomainTemplateRecord(name=name,
type=type,
data=data,
comment=comment,
status=disabled,
status=status,
ttl=ttl)
records.append(dtr)

View file

@ -168,7 +168,7 @@ def add():
record_row = {
'record_data': template_record.data,
'record_name': template_record.name,
'record_status': template_record.status,
'record_status': 'Active' if template_record.status else 'Disabled',
'record_ttl': template_record.ttl,
'record_type': template_record.type,
'comment_data': [{'content': template_record.comment, 'account': ''}]