Merge progress from production system
This commit is contained in:
commit
a3b6209e0a
16
bin/dns-sync
16
bin/dns-sync
|
@ -25,10 +25,7 @@ __VERSION__ = '0.1'
|
||||||
|
|
||||||
|
|
||||||
def _parser():
|
def _parser():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser()
|
||||||
#prog='foo',
|
|
||||||
#description='do some awesome foo',
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument("--pdns-host", default="127.0.0.1", help="PDNS host")
|
parser.add_argument("--pdns-host", default="127.0.0.1", help="PDNS host")
|
||||||
parser.add_argument("--pdns-port", default=8081, help="PDNS port")
|
parser.add_argument("--pdns-port", default=8081, help="PDNS port")
|
||||||
|
@ -38,6 +35,7 @@ def _parser():
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def mergeDomains(zoneData, pdnsData):
|
def mergeDomains(zoneData, pdnsData):
|
||||||
rrAdd = []
|
rrAdd = []
|
||||||
rrData = pdnsData['rrsets']
|
rrData = pdnsData['rrsets']
|
||||||
|
@ -46,8 +44,8 @@ def mergeDomains(zoneData, pdnsData):
|
||||||
found = False
|
found = False
|
||||||
pdnsDom = list(filter(lambda _x: _x['name'] == domain and _x['type'] == rrType, rrData))
|
pdnsDom = list(filter(lambda _x: _x['name'] == domain and _x['type'] == rrType, rrData))
|
||||||
if len(pdnsDom) > 0:
|
if len(pdnsDom) > 0:
|
||||||
rrSet = set(_x['content'] for _x in pdnsDom[0]['records'])
|
rrSet = set(_x['content'].lower() for _x in pdnsDom[0]['records'])
|
||||||
if rrSet == set(records):
|
if rrSet == set(record.lower() for record in records):
|
||||||
found = True
|
found = True
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
|
@ -80,6 +78,7 @@ def removeOldDomains(zoneData, pdnsData):
|
||||||
|
|
||||||
return rrDel
|
return rrDel
|
||||||
|
|
||||||
|
|
||||||
def handleNameserver(ns, servers, usedNameservers, domains):
|
def handleNameserver(ns, servers, usedNameservers, domains):
|
||||||
servers.append(ns.name)
|
servers.append(ns.name)
|
||||||
|
|
||||||
|
@ -106,6 +105,9 @@ def getDomainsFromQueryset(qs, zone, glueRecords, usedNameservers, v4reverse=Fal
|
||||||
|
|
||||||
zone.append((domain.getZone(), "NS", servers))
|
zone.append((domain.getZone(), "NS", servers))
|
||||||
|
|
||||||
|
if domain.ds_records:
|
||||||
|
zone.append((domain.getZone(), "DS", domain.ds_records.split("\n")))
|
||||||
|
|
||||||
if v4reverse:
|
if v4reverse:
|
||||||
# for ipv4 reverse we have to do some extra work in case of classless delegations
|
# for ipv4 reverse we have to do some extra work in case of classless delegations
|
||||||
# see RFC2317
|
# see RFC2317
|
||||||
|
@ -121,6 +123,7 @@ def getDomainsFromQueryset(qs, zone, glueRecords, usedNameservers, v4reverse=Fal
|
||||||
no = startNo + i
|
no = startNo + i
|
||||||
zone.append(("%d.%s" % (no, baseZone), "CNAME", ["%d.%s" % (no, revZone)]))
|
zone.append(("%d.%s" % (no, baseZone), "CNAME", ["%d.%s" % (no, revZone)]))
|
||||||
|
|
||||||
|
|
||||||
def mergeDomainsWithPdns(s, args, zone, zoneData, protectedRecords=[]):
|
def mergeDomainsWithPdns(s, args, zone, zoneData, protectedRecords=[]):
|
||||||
url = "http://%s:%s/api/v1/servers/localhost/zones/%s" % (args.pdns_host, args.pdns_port, zone,)
|
url = "http://%s:%s/api/v1/servers/localhost/zones/%s" % (args.pdns_host, args.pdns_port, zone,)
|
||||||
pdnsData = s.get(url).json()
|
pdnsData = s.get(url).json()
|
||||||
|
@ -198,6 +201,5 @@ def main():
|
||||||
mergeDomainsWithPdns(s, args, "3.2.7.c.3.a.d.f.ip6.arpa.", rzone6)
|
mergeDomainsWithPdns(s, args, "3.2.7.c.3.a.d.f.ip6.arpa.", rzone6)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -15,10 +15,41 @@ import re
|
||||||
import ipaddress
|
import ipaddress
|
||||||
|
|
||||||
|
|
||||||
class DomainForm(MntFormMixin, WhoisObjectFormMixin, forms.ModelForm):
|
class DSRecordMixin(object):
|
||||||
|
ds_re = re.compile(r"^(?P<id>\d+)\s+(?P<crypto>\d+)\s+(?P<hashtype>\d+)\s+(?P<hash>[0-9a-fA-F]+)$")
|
||||||
|
HASH_SUPPORTED = (1, 2)
|
||||||
|
CRYPTO_SUPPORTED = (3, 5, 6, 8, 10, 13, 15)
|
||||||
|
|
||||||
|
def clean_ds_records(self):
|
||||||
|
ds_records = self.cleaned_data['ds_records'].strip()
|
||||||
|
result = []
|
||||||
|
|
||||||
|
if not ds_records:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
for n, rec in enumerate(ds_records.split("\n"), 1):
|
||||||
|
rec = rec.strip()
|
||||||
|
m = self.ds_re.match(rec)
|
||||||
|
if not m:
|
||||||
|
raise forms.ValidationError("Could not parse records {} - needs to be in format "
|
||||||
|
"'<id> <crypto> <hashtype> <hash>'".format(n))
|
||||||
|
|
||||||
|
if int(m.group('hashtype')) not in self.HASH_SUPPORTED:
|
||||||
|
raise forms.ValidationError("Record {} has an invalid hashtype of {}, supported are {}"
|
||||||
|
"".format(n, m.group('hashtype'), " ".join(map(str, self.HASH_SUPPORTED))))
|
||||||
|
if int(m.group('crypto')) not in self.CRYPTO_SUPPORTED:
|
||||||
|
raise forms.ValidationError("Record {} has unsupported crypto {}, supported are {}"
|
||||||
|
"".format(n, m.group('crypto'), " ".join(map(str, self.CRYPTO_SUPPORTED))))
|
||||||
|
|
||||||
|
result.append("{id} {crypto} {hashtype} {hash}".format(**m.groupdict()))
|
||||||
|
|
||||||
|
return "\n".join(result)
|
||||||
|
|
||||||
|
|
||||||
|
class DomainForm(MntFormMixin, WhoisObjectFormMixin, DSRecordMixin, forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Domain
|
model = Domain
|
||||||
fields = ['name', 'nameservers', 'mnt_by', 'admin_c']
|
fields = ['name', 'nameservers', 'mnt_by', 'admin_c', 'ds_records']
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(DomainForm, self).__init__(*args, **kwargs)
|
super(DomainForm, self).__init__(*args, **kwargs)
|
||||||
|
@ -179,7 +210,7 @@ class NameserverForm(MntFormMixin, WhoisObjectFormMixin, forms.ModelForm):
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
|
|
||||||
class ReverseZoneForm(forms.ModelForm):
|
class ReverseZoneForm(DSRecordMixin, forms.ModelForm):
|
||||||
prefix = forms.CharField(validators=[IP46CIDRValidator])
|
prefix = forms.CharField(validators=[IP46CIDRValidator])
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-04-03 05:33
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('domains', '0003_auto_20170322_1801'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='domain',
|
||||||
|
name='mnt_by',
|
||||||
|
field=models.ManyToManyField(help_text='You can select multiple maintainers here', to='whoisdb.Maintainer'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='nameserver',
|
||||||
|
name='mnt_by',
|
||||||
|
field=models.ManyToManyField(help_text='You can select multiple maintainers here', to='whoisdb.Maintainer'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-05-30 21:18
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('domains', '0004_auto_20170403_0533'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='domain',
|
||||||
|
name='ds_records',
|
||||||
|
field=models.TextField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -13,6 +13,13 @@ import ipaddress
|
||||||
# allow owners of a subnet to create reverse dns record?
|
# allow owners of a subnet to create reverse dns record?
|
||||||
|
|
||||||
|
|
||||||
|
class DSRecordModelMixin(models.Model):
|
||||||
|
class Meta:
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
ds_records = models.TextField(blank=True, verbose_name='DS Records',
|
||||||
|
help_text='DS Records in the format of [id] [crypto-algo] [hash-algo] [hash]')
|
||||||
|
|
||||||
class Nameserver(MntdObject):
|
class Nameserver(MntdObject):
|
||||||
handleSuffix = "NS"
|
handleSuffix = "NS"
|
||||||
# dns name
|
# dns name
|
||||||
|
@ -42,7 +49,7 @@ class Nameserver(MntdObject):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
class Domain(MntdObject):
|
class Domain(DSRecordModelMixin, MntdObject):
|
||||||
handle = None
|
handle = None
|
||||||
handleSuffix = "DOM"
|
handleSuffix = "DOM"
|
||||||
name = models.CharField(max_length=67, unique=True, db_index=True)
|
name = models.CharField(max_length=67, unique=True, db_index=True)
|
||||||
|
@ -82,7 +89,7 @@ class Domain(MntdObject):
|
||||||
return name.lower()
|
return name.lower()
|
||||||
|
|
||||||
|
|
||||||
class ReverseZone(WhoisObject):
|
class ReverseZone(DSRecordModelMixin, WhoisObject):
|
||||||
handle = None
|
handle = None
|
||||||
|
|
||||||
parentNet = models.ForeignKey(InetNum)
|
parentNet = models.ForeignKey(InetNum)
|
||||||
|
|
|
@ -39,7 +39,7 @@ def getWhoisObjectFields(obj, owner):
|
||||||
fields.append(("Address CIDR", obj.prefix()))
|
fields.append(("Address CIDR", obj.prefix()))
|
||||||
_addFields(fields, obj, ["description", "parent_range", "origin_as", "mnt_by", "mnt_lower", "admin_c"])
|
_addFields(fields, obj, ["description", "parent_range", "origin_as", "mnt_by", "mnt_lower", "admin_c"])
|
||||||
elif c == domains.models.Domain:
|
elif c == domains.models.Domain:
|
||||||
_addFields(fields, obj, ["name", "nameservers", "mnt_by", "admin_c"])
|
_addFields(fields, obj, ["name", "nameservers", "mnt_by", "admin_c", "ds_records"])
|
||||||
elif c == domains.models.Nameserver:
|
elif c == domains.models.Nameserver:
|
||||||
_addFields(fields, obj, ["name", "glueIPv4", "glueIPv6", "mnt_by", "admin_c"])
|
_addFields(fields, obj, ["name", "glueIPv4", "glueIPv6", "mnt_by", "admin_c"])
|
||||||
elif c == domains.models.ReverseZone:
|
elif c == domains.models.ReverseZone:
|
||||||
|
|
Loading…
Reference in New Issue