use FQDN typed params in api, remove unused parse_name (which was problematic anyway)

This commit is contained in:
Thomas Waldmann 2014-08-30 18:27:21 +02:00
parent f13d985f4a
commit cf2c46e612
7 changed files with 61 additions and 107 deletions

View File

@ -32,7 +32,7 @@ SECURE = False # TLS/SNI support on python 2.x sucks :(
from django.utils.translation import activate from django.utils.translation import activate
from nsupdate.main.dnstools import update_ns from nsupdate.main.dnstools import update_ns, FQDN
@pytest.yield_fixture(scope="function") @pytest.yield_fixture(scope="function")
@ -43,13 +43,14 @@ def ddns_hostname():
""" """
hostname = "test%d" % randint(1000000000, 2000000000) hostname = "test%d" % randint(1000000000, 2000000000)
yield hostname yield hostname
update_ns(hostname + '.' + TESTDOMAIN, 'A', action='del') fqdn = FQDN(hostname, TESTDOMAIN)
update_ns(hostname + '.' + TESTDOMAIN, 'AAAA', action='del') update_ns(fqdn, 'A', action='del')
update_ns(fqdn, 'AAAA', action='del')
@pytest.yield_fixture(scope="function") @pytest.yield_fixture(scope="function")
def ddns_fqdn(ddns_hostname): def ddns_fqdn(ddns_hostname):
yield ddns_hostname + '.' + TESTDOMAIN yield FQDN(ddns_hostname, TESTDOMAIN)
# Note: fixture must be "function" scope (default), see https://github.com/pelme/pytest_django/issues/33 # Note: fixture must be "function" scope (default), see https://github.com/pelme/pytest_django/issues/33

View File

@ -4,7 +4,7 @@ Tests for api package.
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from nsupdate.main.dnstools import query_ns from nsupdate.main.dnstools import query_ns, FQDN
from nsupdate.main.models import Domain from nsupdate.main.models import Domain
from conftest import TESTDOMAIN, TEST_HOST, TEST_HOST2, TEST_SECRET, TEST_SECRET2 from conftest import TESTDOMAIN, TEST_HOST, TEST_HOST2, TEST_SECRET, TEST_SECRET2
@ -13,7 +13,7 @@ USERNAME = 'test'
PASSWORD = 'pass' PASSWORD = 'pass'
BASEDOMAIN = "nsupdate.info" BASEDOMAIN = "nsupdate.info"
HOSTNAME = 'nsupdate-ddns-client-unittest.' + BASEDOMAIN TEST_HOST_OTHER = FQDN('nsupdate-ddns-client-unittest', BASEDOMAIN)
def test_myip(client): def test_myip(client):
@ -124,14 +124,14 @@ def test_nic_update_authorized_update_other_services(client):
# must be good (was different IP) # must be good (was different IP)
assert response.content == b'good 1.2.3.4' assert response.content == b'good 1.2.3.4'
# now check if it updated the other service also: # now check if it updated the other service also:
assert query_ns(HOSTNAME, 'A') == '1.2.3.4' assert query_ns(TEST_HOST_OTHER, 'A') == '1.2.3.4'
response = client.get(reverse('nic_update') + '?myip=2.3.4.5', response = client.get(reverse('nic_update') + '?myip=2.3.4.5',
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET)) HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200 assert response.status_code == 200
# must be good (was different IP) # must be good (was different IP)
assert response.content == b'good 2.3.4.5' assert response.content == b'good 2.3.4.5'
# now check if it updated the other service also: # now check if it updated the other service also:
assert query_ns(HOSTNAME, 'A') == '2.3.4.5' assert query_ns(TEST_HOST_OTHER, 'A') == '2.3.4.5'
def test_nic_update_authorized_badagent(client, settings): def test_nic_update_authorized_badagent(client, settings):

View File

@ -224,9 +224,9 @@ class NicUpdateView(View):
ipaddr = request.META.get('REMOTE_ADDR') ipaddr = request.META.get('REMOTE_ADDR')
secure = request.is_secure() secure = request.is_secure()
if delete: if delete:
return _delete(host, hostname, ipaddr, secure, logger=logger) return _delete(host, ipaddr, secure, logger=logger)
else: else:
return _update(host, hostname, ipaddr, secure, logger=logger) return _update(host, ipaddr, secure, logger=logger)
class NicDeleteView(NicUpdateView): class NicDeleteView(NicUpdateView):
@ -282,9 +282,9 @@ class AuthorizedNicUpdateView(View):
ipaddr = request.META.get('REMOTE_ADDR') ipaddr = request.META.get('REMOTE_ADDR')
secure = request.is_secure() secure = request.is_secure()
if delete: if delete:
return _delete(host, hostname, ipaddr, secure, logger=logger) return _delete(host, ipaddr, secure, logger=logger)
else: else:
return _update(host, hostname, ipaddr, secure, logger=logger) return _update(host, ipaddr, secure, logger=logger)
class AuthorizedNicDeleteView(AuthorizedNicUpdateView): class AuthorizedNicDeleteView(AuthorizedNicUpdateView):
@ -300,12 +300,11 @@ class AuthorizedNicDeleteView(AuthorizedNicUpdateView):
return super(AuthorizedNicDeleteView, self).get(request, logger=logger, delete=delete) return super(AuthorizedNicDeleteView, self).get(request, logger=logger, delete=delete)
def _update(host, hostname, ipaddr, secure=False, logger=None): def _update(host, ipaddr, secure=False, logger=None):
""" """
common code shared by the 2 update views common code shared by the 2 update views
:param host: host object :param host: host object
:param hostname: hostname (fqdn)
:param ipaddr: new ip addr (v4 or v6) :param ipaddr: new ip addr (v4 or v6)
:param secure: True if we use TLS/https :param secure: True if we use TLS/https
:param logger: a logger object :param logger: a logger object
@ -330,9 +329,10 @@ def _update(host, hostname, ipaddr, secure=False, logger=None):
# some people manage to even give a non-ascii string instead of an ip addr # some people manage to even give a non-ascii string instead of an ip addr
return Response('dnserr') # there should be a better response code for this return Response('dnserr') # there should be a better response code for this
host.poke(kind, secure) host.poke(kind, secure)
fqdn = host.get_fqdn()
try: try:
update(hostname, ipaddr) update(fqdn, ipaddr)
logger.info('%s - received good update -> ip: %s tls: %r' % (hostname, ipaddr, secure)) logger.info('%s - received good update -> ip: %s tls: %r' % (fqdn, ipaddr, secure))
# now check if there are other services we shall relay updates to: # now check if there are other services we shall relay updates to:
for hc in host.serviceupdaterhostconfigs.all(): for hc in host.serviceupdaterhostconfigs.all():
if (kind == 'ipv4' and hc.give_ipv4 and hc.service.accept_ipv4 if (kind == 'ipv4' and hc.give_ipv4 and hc.service.accept_ipv4
@ -351,23 +351,22 @@ def _update(host, hostname, ipaddr, secure=False, logger=None):
logger.exception("the dyndns2 updater raised an exception [%r]" % kwargs) logger.exception("the dyndns2 updater raised an exception [%r]" % kwargs)
return Response('good %s' % ipaddr) return Response('good %s' % ipaddr)
except SameIpError: except SameIpError:
logger.warning('%s - received no-change update, ip: %s tls: %r' % (hostname, ipaddr, secure)) logger.warning('%s - received no-change update, ip: %s tls: %r' % (fqdn, ipaddr, secure))
host.register_client_fault() host.register_client_fault()
return Response('nochg %s' % ipaddr) return Response('nochg %s' % ipaddr)
except (DnsUpdateError, NameServerNotAvailable) as e: except (DnsUpdateError, NameServerNotAvailable) as e:
msg = str(e) msg = str(e)
logger.error('%s - received update that resulted in a dns error [%s], ip: %s tls: %r' % ( logger.error('%s - received update that resulted in a dns error [%s], ip: %s tls: %r' % (
hostname, msg, ipaddr, secure)) fqdn, msg, ipaddr, secure))
host.register_server_fault() host.register_server_fault()
return Response('dnserr') return Response('dnserr')
def _delete(host, hostname, ipaddr, secure=False, logger=None): def _delete(host, ipaddr, secure=False, logger=None):
""" """
common code shared by the 2 delete views common code shared by the 2 delete views
:param host: host object :param host: host object
:param hostname: hostname (fqdn)
:param ipaddr: ip addr (to determine record type A or AAAA) :param ipaddr: ip addr (to determine record type A or AAAA)
:param secure: True if we use TLS/https :param secure: True if we use TLS/https
:param logger: a logger object :param logger: a logger object
@ -392,15 +391,16 @@ def _delete(host, hostname, ipaddr, secure=False, logger=None):
# some people manage to even give a non-ascii string instead of an ip addr # some people manage to even give a non-ascii string instead of an ip addr
return Response('dnserr') # there should be a better response code for this return Response('dnserr') # there should be a better response code for this
host.poke(kind, secure) host.poke(kind, secure)
fqdn = host.get_fqdn()
try: try:
rdtype = 'A' if kind == 'ipv4' else 'AAAA' rdtype = 'A' if kind == 'ipv4' else 'AAAA'
delete(hostname, rdtype) delete(fqdn, rdtype)
logger.info('%s - received delete for record %s, tls: %r' % (hostname, rdtype, secure)) logger.info('%s - received delete for record %s, tls: %r' % (fqdn, rdtype, secure))
# XXX unclear what to do for "other services" we relay updates to # XXX unclear what to do for "other services" we relay updates to
return Response('deleted %s' % rdtype) return Response('deleted %s' % rdtype)
except (DnsUpdateError, NameServerNotAvailable) as e: except (DnsUpdateError, NameServerNotAvailable) as e:
msg = str(e) msg = str(e)
logger.error('%s - received delete for record %s that resulted in a dns error [%s], tls: %r' % ( logger.error('%s - received delete for record %s that resulted in a dns error [%s], tls: %r' % (
hostname, rdtype, msg, secure)) fqdn, rdtype, msg, secure))
host.register_server_fault() host.register_server_fault()
return Response('dnserr') return Response('dnserr')

View File

@ -10,12 +10,12 @@ pytestmark = pytest.mark.django_db
from dns.resolver import NXDOMAIN, NoAnswer from dns.resolver import NXDOMAIN, NoAnswer
from ..dnstools import (add, delete, update, query_ns, rev_lookup, parse_name, update_ns, from ..dnstools import (add, delete, update, query_ns, rev_lookup, update_ns,
SameIpError, DnsUpdateError, FQDN) SameIpError, DnsUpdateError, FQDN)
# see also conftest.py # see also conftest.py
BASEDOMAIN = 'nsupdate.info' BASEDOMAIN = 'nsupdate.info'
INVALID_HOST = 'test999.' + BASEDOMAIN # this can't get updated INVALID_HOST = FQDN('test999', BASEDOMAIN) # this can't get updated
class TestFQDN(object): class TestFQDN(object):
@ -128,23 +128,6 @@ class TestReverseLookup(object):
class TestUpdate(object): class TestUpdate(object):
def test_parse1(self):
host, domain = 'test', BASEDOMAIN
origin, relname = parse_name(host + '.' + domain)
assert str(origin) == domain + '.'
assert str(relname) == host
def test_parse2(self):
host, domain = 'prefix.test', BASEDOMAIN
origin, relname = parse_name(host + '.' + domain)
assert str(origin) == domain + '.'
assert str(relname) == 'prefix.test'
def test_parse_with_origin(self):
origin, relname = parse_name('foo.bar.baz.org', 'bar.baz.org')
assert str(origin) == 'bar.baz.org' + '.'
assert str(relname) == 'foo'
def test_add_del_v4(self, ddns_fqdn): def test_add_del_v4(self, ddns_fqdn):
host, ip = ddns_fqdn, '1.1.1.1' host, ip = ddns_fqdn, '1.1.1.1'
remove_records(host) remove_records(host)

View File

@ -98,22 +98,22 @@ def check_ip(ipaddr, keys=('ipv4', 'ipv6')):
return keys[af == dns.inet.AF_INET6] return keys[af == dns.inet.AF_INET6]
def add(fqdn, ipaddr, ttl=60, origin=None): def add(fqdn, ipaddr, ttl=60):
""" """
intelligent dns adder - first does a lookup on the master server to find intelligent dns adder - first does a lookup on the master server to find
the current ip and only sends an 'add' if there is no such entry. the current ip and only sends an 'add' if there is no such entry.
otherwise send an 'upd' if the if we have a different ip. otherwise send an 'upd' if the if we have a different ip.
:param fqdn: fully qualified domain name (str) :param fqdn: fully qualified domain name (FQDN)
:param ipaddr: new ip address :param ipaddr: new ip address
:param ttl: time to live, default 60s (int) :param ttl: time to live, default 60s (int)
:param origin: origin zone (optional, str)
:raises: SameIpError if new and old IP is the same :raises: SameIpError if new and old IP is the same
:raises: ValueError if ipaddr is no valid ip address string :raises: ValueError if ipaddr is no valid ip address string
""" """
assert isinstance(fqdn, FQDN)
rdtype = check_ip(ipaddr, keys=('A', 'AAAA')) rdtype = check_ip(ipaddr, keys=('A', 'AAAA'))
try: try:
current_ipaddr = query_ns(fqdn, rdtype, origin=origin) current_ipaddr = query_ns(fqdn, rdtype)
# check if ip really changed # check if ip really changed
ok = ipaddr != current_ipaddr ok = ipaddr != current_ipaddr
action = 'upd' action = 'upd'
@ -125,43 +125,43 @@ def add(fqdn, ipaddr, ttl=60, origin=None):
# only send an add/update if the ip really changed as the update # only send an add/update if the ip really changed as the update
# causes write I/O on the nameserver and also traffic to the # causes write I/O on the nameserver and also traffic to the
# dns slaves (they get a notify if we update the zone). # dns slaves (they get a notify if we update the zone).
update_ns(fqdn, rdtype, ipaddr, action=action, ttl=ttl, origin=origin) update_ns(fqdn, rdtype, ipaddr, action=action, ttl=ttl)
else: else:
raise SameIpError raise SameIpError
def delete(fqdn, rdtype=None, origin=None): def delete(fqdn, rdtype=None):
""" """
dns deleter dns deleter
:param fqdn: fully qualified domain name (str) :param fqdn: fully qualified domain name (FQDN)
:param rdtype: 'A', 'AAAA' or None (deletes 'A' and 'AAAA') :param rdtype: 'A', 'AAAA' or None (deletes 'A' and 'AAAA')
:param origin: origin zone (optional, str)
""" """
assert isinstance(fqdn, FQDN)
if rdtype is not None: if rdtype is not None:
assert rdtype in ['A', 'AAAA', ] assert rdtype in ['A', 'AAAA', ]
rdtypes = [rdtype, ] rdtypes = [rdtype, ]
else: else:
rdtypes = ['A', 'AAAA'] rdtypes = ['A', 'AAAA']
for rdtype in rdtypes: for rdtype in rdtypes:
update_ns(fqdn, rdtype, action='del', origin=origin) update_ns(fqdn, rdtype, action='del')
def update(fqdn, ipaddr, ttl=60, origin=None): def update(fqdn, ipaddr, ttl=60):
""" """
intelligent dns updater - first does a lookup on the master server to find intelligent dns updater - first does a lookup on the master server to find
the current ip and only sends a dynamic update if we have a different ip. the current ip and only sends a dynamic update if we have a different ip.
:param fqdn: fully qualified domain name (str) :param fqdn: fully qualified domain name (FQDN)
:param ipaddr: new ip address :param ipaddr: new ip address
:param ttl: time to live, default 60s (int) :param ttl: time to live, default 60s (int)
:param origin: origin zone (optional, str)
:raises: SameIpError if new and old IP is the same :raises: SameIpError if new and old IP is the same
:raises: ValueError if ipaddr is no valid ip address string :raises: ValueError if ipaddr is no valid ip address string
""" """
assert isinstance(fqdn, FQDN)
rdtype = check_ip(ipaddr, keys=('A', 'AAAA')) rdtype = check_ip(ipaddr, keys=('A', 'AAAA'))
try: try:
current_ipaddr = query_ns(fqdn, rdtype, origin=origin) current_ipaddr = query_ns(fqdn, rdtype)
# check if ip really changed # check if ip really changed
ok = ipaddr != current_ipaddr ok = ipaddr != current_ipaddr
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
@ -171,27 +171,23 @@ def update(fqdn, ipaddr, ttl=60, origin=None):
# only send an update if the ip really changed as the update # only send an update if the ip really changed as the update
# causes write I/O on the nameserver and also traffic to the # causes write I/O on the nameserver and also traffic to the
# dns slaves (they get a notify if we update the zone). # dns slaves (they get a notify if we update the zone).
update_ns(fqdn, rdtype, ipaddr, action='upd', ttl=ttl, origin=origin) update_ns(fqdn, rdtype, ipaddr, action='upd', ttl=ttl)
else: else:
raise SameIpError raise SameIpError
def query_ns(qname, rdtype, origin=None): def query_ns(fqdn, rdtype):
""" """
query a dns name from our master server query a dns name from our master server
:param qname: the query name :param fqdn: fqdn to query the name server for
:type qname: dns.name.Name object or str :type fqdn: dnstools.FQDN
:param rdtype: the query type :param rdtype: the query type
:type rdtype: int or str :type rdtype: int or str
:param origin: origin zone
:type origin: str or None
:return: IP (as str) :return: IP (as str)
:raises: see dns.resolver.Resolver.query :raises: see dns.resolver.Resolver.query
""" """
origin, name = parse_name(qname, origin) assert isinstance(fqdn, FQDN)
fqdn = name + origin
assert fqdn.is_absolute()
nameserver, origin = get_ns_info(fqdn)[0:2] nameserver, origin = get_ns_info(fqdn)[0:2]
resolver = dns.resolver.Resolver(configure=False) resolver = dns.resolver.Resolver(configure=False)
# we do not configure it from resolv.conf, but patch in the values we # we do not configure it from resolv.conf, but patch in the values we
@ -204,13 +200,13 @@ def query_ns(qname, rdtype, origin=None):
# (used if flags = None is given). Thus, we explicitly give flags (all off): # (used if flags = None is given). Thus, we explicitly give flags (all off):
resolver.flags = 0 resolver.flags = 0
try: try:
answer = resolver.query(fqdn, rdtype) answer = resolver.query(str(fqdn), rdtype)
ip = str(list(answer)[0]) ip = str(list(answer)[0])
logger.debug("query: %s answer: %s" % (fqdn.to_text(), ip)) logger.debug("query: %s answer: %s" % (fqdn, ip))
return ip return ip
except (dns.resolver.Timeout, dns.resolver.NoNameservers): # socket.error also? except (dns.resolver.Timeout, dns.resolver.NoNameservers): # socket.error also?
logger.warning("timeout when querying for name '%s' in zone '%s' with rdtype '%s'." % ( logger.warning("timeout when querying for name '%s' in zone '%s' with rdtype '%s'." % (
name, origin, rdtype)) fqdn.host, origin, rdtype))
set_ns_availability(origin, False) set_ns_availability(origin, False)
raise raise
@ -233,53 +229,27 @@ def rev_lookup(ipaddr):
return name return name
def parse_name(fqdn, origin=None): def get_ns_info(fqdn):
""" """
Parse a fully qualified domain name into a relative name Get the master nameserver for fqdn, the key secret needed to update the zone and the key algorithm used.
and a origin zone. Please note that the origin return value will
have a trailing dot.
:param fqdn: fully qualified domain name (str)
:param origin: origin zone (optional, str)
:return: origin, relative name (both dns.name.Name)
"""
fqdn = dns.name.from_text(fqdn)
if origin is None:
origin = dns.resolver.zone_for_name(fqdn)
rel_name = fqdn.relativize(origin)
else:
origin = dns.name.from_text(origin)
rel_name = fqdn - origin
return origin, rel_name
def get_ns_info(fqdn, origin=None):
"""
Get the master nameserver for the <origin> zone, the key secret needed
to update the zone and the key algorithm used.
:param fqdn: the fully qualified hostname we are dealing with (str) :param fqdn: the fully qualified hostname we are dealing with (str)
:param origin: zone we are dealing with, must be with trailing dot (default:autodetect) (str)
:return: master nameserver, origin, domain, update keyname, update secret, update algo :return: master nameserver, origin, domain, update keyname, update secret, update algo
:raises: NameServerNotAvailable if ns was flagged unavailable in the db :raises: NameServerNotAvailable if ns was flagged unavailable in the db
""" """
fqdn_str = str(fqdn) assert isinstance(fqdn, FQDN)
origin, name = parse_name(fqdn_str, origin)
origin_str = str(origin)
from .models import Domain from .models import Domain
try: try:
# first we check if we have an entry for the fqdn # first we check if we have an entry for the fqdn
# single-host update secret use case # single-host update secret use case
# XXX we need 2 DB accesses for the usual case just to support this rare case # XXX we need 2 DB accesses for the usual case just to support this rare case
domain = fqdn_str.rstrip('.') domain = str(fqdn)
d = Domain.objects.get(domain=domain) d = Domain.objects.get(domain=domain)
keyname = fqdn_str
except Domain.DoesNotExist: except Domain.DoesNotExist:
# now check the base zone, the usual case # now check the base zone, the usual case
# zone update secret use case # zone update secret use case
domain = origin_str.rstrip('.') domain = fqdn.domain
d = Domain.objects.get(domain=domain) d = Domain.objects.get(domain=domain)
keyname = origin_str
if not d.available: if not d.available:
if d.last_update + timedelta(seconds=UNAVAILABLE_RETRY) > now(): if d.last_update + timedelta(seconds=UNAVAILABLE_RETRY) > now():
# if there are troubles with a nameserver, we set available=False # if there are troubles with a nameserver, we set available=False
@ -290,24 +260,24 @@ def get_ns_info(fqdn, origin=None):
# retry timeout is over, set it available again # retry timeout is over, set it available again
set_ns_availability(domain, True) set_ns_availability(domain, True)
algorithm = getattr(dns.tsig, d.nameserver_update_algorithm) algorithm = getattr(dns.tsig, d.nameserver_update_algorithm)
return d.nameserver_ip, origin, domain, name, keyname, d.nameserver_update_secret, algorithm return d.nameserver_ip, fqdn.domain, domain, fqdn.host, domain, d.nameserver_update_secret, algorithm
def update_ns(fqdn, rdtype='A', ipaddr=None, origin=None, action='upd', ttl=60): def update_ns(fqdn, rdtype='A', ipaddr=None, action='upd', ttl=60):
""" """
update the master server update the master server
:param fqdn: the fully qualified domain name to update (str) :param fqdn: the fully qualified domain name to update (FQDN)
:param rdtype: the record type (default: 'A') (str) :param rdtype: the record type (default: 'A') (str)
:param ipaddr: ip address (v4 or v6), if needed (str) :param ipaddr: ip address (v4 or v6), if needed (str)
:param origin: the origin zone to update (default; autodetect) (str)
:param action: 'add', 'del' or 'upd' :param action: 'add', 'del' or 'upd'
:param ttl: time to live for the added/updated resource, default 60s (int) :param ttl: time to live for the added/updated resource, default 60s (int)
:return: dns response :return: dns response
:raises: DnsUpdateError, Timeout :raises: DnsUpdateError, Timeout
""" """
assert isinstance(fqdn, FQDN)
assert action in ['add', 'del', 'upd', ] assert action in ['add', 'del', 'upd', ]
nameserver, origin, domain, name, keyname, key, algo = get_ns_info(fqdn, origin) nameserver, origin, domain, name, keyname, key, algo = get_ns_info(fqdn)
upd = dns.update.Update(origin, upd = dns.update.Update(origin,
keyring=dns.tsigkeyring.from_text({keyname: key}), keyring=dns.tsigkeyring.from_text({keyname: key}),
keyalgorithm=algo) keyalgorithm=algo)

View File

@ -181,7 +181,7 @@ class Host(models.Model):
index_together = (('subdomain', 'domain'), ) index_together = (('subdomain', 'domain'), )
def get_fqdn(self): def get_fqdn(self):
return '%s.%s' % (self.subdomain, self.domain.domain) return dnstools.FQDN(self.subdomain, self.domain.domain)
@classmethod @classmethod
def get_by_fqdn(cls, fqdn, **kwargs): def get_by_fqdn(cls, fqdn, **kwargs):
@ -202,7 +202,7 @@ class Host(models.Model):
def get_ip(self, kind): def get_ip(self, kind):
record = 'A' if kind == 'ipv4' else 'AAAA' record = 'A' if kind == 'ipv4' else 'AAAA'
try: try:
return dnstools.query_ns(self.get_fqdn(), record, origin=self.domain.domain) return dnstools.query_ns(self.get_fqdn(), record)
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
return 'none' return 'none'
except (dns.resolver.NoNameservers, dns.resolver.Timeout, dnstools.NameServerNotAvailable): except (dns.resolver.NoNameservers, dns.resolver.Timeout, dnstools.NameServerNotAvailable):
@ -250,7 +250,7 @@ class Host(models.Model):
def pre_delete_host(sender, **kwargs): def pre_delete_host(sender, **kwargs):
obj = kwargs['instance'] obj = kwargs['instance']
try: try:
dnstools.delete(obj.get_fqdn(), origin=obj.domain.domain) dnstools.delete(obj.get_fqdn())
except (dnstools.Timeout, dnstools.NameServerNotAvailable): except (dnstools.Timeout, dnstools.NameServerNotAvailable):
# well, we tried to clean up, but we didn't reach the nameserver # well, we tried to clean up, but we didn't reach the nameserver
pass pass

View File

@ -194,7 +194,7 @@ class OverviewView(CreateView):
def form_valid(self, form): def form_valid(self, form):
self.object = form.save(commit=False) self.object = form.save(commit=False)
try: try:
dnstools.add(self.object.get_fqdn(), self.request.META['REMOTE_ADDR'], origin=self.object.domain.domain) dnstools.add(self.object.get_fqdn(), self.request.META['REMOTE_ADDR'])
except dnstools.Timeout: except dnstools.Timeout:
success, level, msg = False, messages.ERROR, 'Timeout - communicating to name server failed.' success, level, msg = False, messages.ERROR, 'Timeout - communicating to name server failed.'
except dnstools.NameServerNotAvailable: except dnstools.NameServerNotAvailable: