implement intelligent updater (only sends ns update if IP really changed)
This commit is contained in:
parent
9be82a5d01
commit
be3a124fbc
@ -4,13 +4,29 @@ Tests for dnstools module.
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ..dnstools import (query_ns, parse_name, update_ns,
|
from ..dnstools import (update, query_ns, parse_name, update_ns, SameIpError,
|
||||||
BASEDOMAIN, NONEXISTING_HOST,
|
BASEDOMAIN, NONEXISTING_HOST,
|
||||||
WWW_HOST, WWW_IPV4_HOST, WWW_IPV4_IP, WWW_IPV6_HOST, WWW_IPV6_IP, )
|
WWW_HOST, WWW_IPV4_HOST, WWW_IPV4_IP, WWW_IPV6_HOST, WWW_IPV6_IP, )
|
||||||
|
|
||||||
from dns.resolver import NXDOMAIN
|
from dns.resolver import NXDOMAIN
|
||||||
|
|
||||||
|
|
||||||
|
class TestIntelligentUpdater(object):
|
||||||
|
def test_double_update(self):
|
||||||
|
host, ip = 'test0.' + BASEDOMAIN, '1.2.3.4'
|
||||||
|
# make sure the host is not there
|
||||||
|
try:
|
||||||
|
update_ns(host, 'A', action='del')
|
||||||
|
except NXDOMAIN:
|
||||||
|
# it is ok if it was never there
|
||||||
|
pass
|
||||||
|
# first update with this IP, should work without issue:
|
||||||
|
update(host, ip)
|
||||||
|
with pytest.raises(SameIpError):
|
||||||
|
# trying to update again with same IP should raise
|
||||||
|
update(host, ip)
|
||||||
|
|
||||||
|
|
||||||
class TestQuery(object):
|
class TestQuery(object):
|
||||||
def test_queries_ok(self):
|
def test_queries_ok(self):
|
||||||
assert query_ns(WWW_IPV4_HOST, 'A') == WWW_IPV4_IP # v4 ONLY
|
assert query_ns(WWW_IPV4_HOST, 'A') == WWW_IPV4_IP # v4 ONLY
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
"""
|
s"""
|
||||||
Misc. DNS related code: query, dynamic update, etc.
|
Misc. DNS related code: query, dynamic update, etc.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
import dns.inet
|
||||||
import dns.name
|
import dns.name
|
||||||
import dns.resolver
|
import dns.resolver
|
||||||
import dns.query
|
import dns.query
|
||||||
@ -25,6 +27,32 @@ UPDATE_ALGO = dns.tsig.HMAC_SHA512
|
|||||||
UPDATE_KEY = settings.UPDATE_KEY
|
UPDATE_KEY = settings.UPDATE_KEY
|
||||||
|
|
||||||
|
|
||||||
|
class SameIpError(ValueError):
|
||||||
|
"""
|
||||||
|
raised if an IP address is already present in DNS and and update was
|
||||||
|
requested, but is not needed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def update(fqdn, ipaddr, ttl=60):
|
||||||
|
af = dns.inet.af_for_address(ipaddr)
|
||||||
|
rdtype = 'A' if af == dns.inet.AF_INET else 'AAAA'
|
||||||
|
try:
|
||||||
|
current_ipaddr = query_ns(fqdn, rdtype)
|
||||||
|
# check if ip really changed
|
||||||
|
ok = ipaddr != current_ipaddr
|
||||||
|
except dns.resolver.NXDOMAIN:
|
||||||
|
# no dns entry yet, ok
|
||||||
|
ok = True
|
||||||
|
if ok:
|
||||||
|
# only send an update if the ip really changed as the update
|
||||||
|
# causes write I/O on the nameserver and also traffic to the
|
||||||
|
# dns slaves (they get a notify if we update the zone).
|
||||||
|
update_ns(fqdn, rdtype, ipaddr, action='upd', ttl=ttl)
|
||||||
|
else:
|
||||||
|
raise SameIpError
|
||||||
|
|
||||||
|
|
||||||
def query_ns(qname, rdtype):
|
def query_ns(qname, rdtype):
|
||||||
"""
|
"""
|
||||||
query a dns name from our master server
|
query a dns name from our master server
|
||||||
|
Loading…
x
Reference in New Issue
Block a user