add secondary nameserver, prefer it for queries, add migration, fixes #175
This commit is contained in:
parent
b6968fdb6f
commit
536a5f5d9d
@ -20,6 +20,7 @@ TEST_SECRET2 = "somethingelse"
|
|||||||
RELATED_HOST_NAME = 'rh'
|
RELATED_HOST_NAME = 'rh'
|
||||||
TEST_HOST_RELATED = FQDN(RELATED_HOST_NAME + '.' + TEST_HOST.host, TEST_HOST.domain)
|
TEST_HOST_RELATED = FQDN(RELATED_HOST_NAME + '.' + TEST_HOST.host, TEST_HOST.domain)
|
||||||
NAMESERVER_IP = "85.10.192.104"
|
NAMESERVER_IP = "85.10.192.104"
|
||||||
|
NAMESERVER2_IP = NAMESERVER_IP # use same server as tests query shortly after update, too quick for secondary
|
||||||
NAMESERVER_UPDATE_ALGORITHM = "HMAC_SHA512"
|
NAMESERVER_UPDATE_ALGORITHM = "HMAC_SHA512"
|
||||||
# no problem, you can ONLY update the TESTDOMAIN with this secret, nothing else:
|
# no problem, you can ONLY update the TESTDOMAIN with this secret, nothing else:
|
||||||
NAMESERVER_UPDATE_SECRET = "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYQ=="
|
NAMESERVER_UPDATE_SECRET = "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYQ=="
|
||||||
@ -75,6 +76,7 @@ def db_init(db): # note: db is a predefined fixture and required here to have t
|
|||||||
dt = Domain.objects.create(
|
dt = Domain.objects.create(
|
||||||
name=TESTDOMAIN, # special: test-domain update secret!
|
name=TESTDOMAIN, # special: test-domain update secret!
|
||||||
nameserver_ip=NAMESERVER_IP,
|
nameserver_ip=NAMESERVER_IP,
|
||||||
|
nameserver2_ip=NAMESERVER2_IP,
|
||||||
nameserver_update_algorithm=NAMESERVER_UPDATE_ALGORITHM,
|
nameserver_update_algorithm=NAMESERVER_UPDATE_ALGORITHM,
|
||||||
nameserver_update_secret=NAMESERVER_UPDATE_SECRET,
|
nameserver_update_secret=NAMESERVER_UPDATE_SECRET,
|
||||||
public=NAMESERVER_PUBLIC,
|
public=NAMESERVER_PUBLIC,
|
||||||
@ -84,6 +86,7 @@ def db_init(db): # note: db is a predefined fixture and required here to have t
|
|||||||
d = Domain.objects.create(
|
d = Domain.objects.create(
|
||||||
name=BASEDOMAIN,
|
name=BASEDOMAIN,
|
||||||
nameserver_ip=NAMESERVER_IP,
|
nameserver_ip=NAMESERVER_IP,
|
||||||
|
nameserver2_ip=NAMESERVER2_IP,
|
||||||
nameserver_update_algorithm=NAMESERVER_UPDATE_ALGORITHM,
|
nameserver_update_algorithm=NAMESERVER_UPDATE_ALGORITHM,
|
||||||
nameserver_update_secret='invalid=', # we don't send updates there (and the real key is really secret)
|
nameserver_update_secret='invalid=', # we don't send updates there (and the real key is really secret)
|
||||||
public=NAMESERVER_PUBLIC,
|
public=NAMESERVER_PUBLIC,
|
||||||
|
@ -197,11 +197,14 @@ def query_ns(fqdn, rdtype):
|
|||||||
:raises: see dns.resolver.Resolver.query
|
:raises: see dns.resolver.Resolver.query
|
||||||
"""
|
"""
|
||||||
assert isinstance(fqdn, FQDN)
|
assert isinstance(fqdn, FQDN)
|
||||||
nameserver, origin = get_ns_info(fqdn)[0:2]
|
nameserver, nameserver2, origin = get_ns_info(fqdn)[0:3]
|
||||||
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
|
||||||
# want into the documented attributes:
|
# want into the documented attributes:
|
||||||
resolver.nameservers = [nameserver, ]
|
resolver.nameservers = [nameserver, ]
|
||||||
|
if nameserver2:
|
||||||
|
# if we have a secondary ns, prefer it for queries
|
||||||
|
resolver.nameservers.insert(0, nameserver2)
|
||||||
resolver.search = []
|
resolver.search = []
|
||||||
resolver.lifetime = RESOLVER_TIMEOUT
|
resolver.lifetime = RESOLVER_TIMEOUT
|
||||||
# as we query directly the (authoritative) master dns, we do not desire
|
# as we query directly the (authoritative) master dns, we do not desire
|
||||||
@ -269,7 +272,7 @@ def get_ns_info(fqdn):
|
|||||||
# 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, fqdn.domain, domain, fqdn.host, domain, d.nameserver_update_secret, algorithm
|
return d.nameserver_ip, d.nameserver2_ip, fqdn.domain, domain, fqdn.host, domain, d.nameserver_update_secret, algorithm
|
||||||
|
|
||||||
|
|
||||||
def update_ns(fqdn, rdtype='A', ipaddr=None, action='upd', ttl=60):
|
def update_ns(fqdn, rdtype='A', ipaddr=None, action='upd', ttl=60):
|
||||||
@ -286,7 +289,7 @@ def update_ns(fqdn, rdtype='A', ipaddr=None, action='upd', ttl=60):
|
|||||||
"""
|
"""
|
||||||
assert isinstance(fqdn, FQDN)
|
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)
|
nameserver, nameserver2, 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)
|
||||||
|
@ -44,7 +44,7 @@ class EditRelatedHostForm(forms.ModelForm):
|
|||||||
class CreateDomainForm(forms.ModelForm):
|
class CreateDomainForm(forms.ModelForm):
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
model = Domain
|
model = Domain
|
||||||
fields = ['name', 'nameserver_ip', 'nameserver_update_algorithm',
|
fields = ['name', 'nameserver_ip', 'nameserver2_ip', 'nameserver_update_algorithm',
|
||||||
'public', 'available', 'comment']
|
'public', 'available', 'comment']
|
||||||
widgets = {
|
widgets = {
|
||||||
'name': forms.widgets.TextInput(attrs=dict(autofocus=None)),
|
'name': forms.widgets.TextInput(attrs=dict(autofocus=None)),
|
||||||
@ -54,7 +54,7 @@ class CreateDomainForm(forms.ModelForm):
|
|||||||
class EditDomainForm(forms.ModelForm):
|
class EditDomainForm(forms.ModelForm):
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
model = Domain
|
model = Domain
|
||||||
fields = ['comment', 'nameserver_ip', 'public', 'available',
|
fields = ['comment', 'nameserver_ip', 'nameserver2_ip', 'public', 'available',
|
||||||
'nameserver_update_algorithm', 'nameserver_update_secret']
|
'nameserver_update_algorithm', 'nameserver_update_secret']
|
||||||
|
|
||||||
|
|
||||||
|
26
nsupdate/main/migrations/0003_auto_20141115_2230.py
Normal file
26
nsupdate/main/migrations/0003_auto_20141115_2230.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('main', '0002_auto_20141115_2227'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='domain',
|
||||||
|
name='nameserver2_ip',
|
||||||
|
field=models.GenericIPAddressField(help_text='IP of additional nameserver (used for queries)', null=True, verbose_name='nameserver IP (secondary)', blank=True),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='domain',
|
||||||
|
name='nameserver_ip',
|
||||||
|
field=models.GenericIPAddressField(help_text='IP where the dynamic DNS updates for this zone will be sent to', verbose_name='nameserver IP (primary)'),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
]
|
@ -83,9 +83,14 @@ class Domain(models.Model):
|
|||||||
unique=True,
|
unique=True,
|
||||||
help_text=_("Name of the zone where dynamic hosts may get added"))
|
help_text=_("Name of the zone where dynamic hosts may get added"))
|
||||||
nameserver_ip = models.GenericIPAddressField(
|
nameserver_ip = models.GenericIPAddressField(
|
||||||
_("nameserver IP"),
|
_("nameserver IP (primary)"),
|
||||||
max_length=40, # ipv6 = 8 * 4 digits + 7 colons
|
max_length=40, # ipv6 = 8 * 4 digits + 7 colons
|
||||||
help_text=_("IP where the dynamic DNS updates for this zone will be sent to"))
|
help_text=_("IP where the dynamic DNS updates for this zone will be sent to"))
|
||||||
|
nameserver2_ip = models.GenericIPAddressField(
|
||||||
|
_("nameserver IP (secondary)"),
|
||||||
|
max_length=40, # ipv6 = 8 * 4 digits + 7 colons
|
||||||
|
blank=True, null=True,
|
||||||
|
help_text=_("IP of additional nameserver (used for queries)"))
|
||||||
nameserver_update_secret = models.CharField(
|
nameserver_update_secret = models.CharField(
|
||||||
_("nameserver update secret"),
|
_("nameserver update secret"),
|
||||||
max_length=88, # 512 bits base64 -> 88 bytes
|
max_length=88, # 512 bits base64 -> 88 bytes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user