Improve DNS table models
This commit adds Meta information and __str__ methods to all DNS table models. The new methods are now covered with new tests. The new constants DNS_DOMAIN_METADATA_KINDS and DNS_TSIG_KEY_ALGORITHMS are defined and used in the DNSDomainMetadata and DNSTSIGKey models. A matching database schema migration is added. Addresses #17
This commit is contained in:
parent
1df2534cf3
commit
c058cc7b1d
3 changed files with 193 additions and 7 deletions
44
gnuviechadmin/domains/migrations/0004_auto_20151107_1708.py
Normal file
44
gnuviechadmin/domains/migrations/0004_auto_20151107_1708.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('domains', '0003_auto_20151105_2133'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='dnscomment',
|
||||
options={'verbose_name': 'DNS comment', 'verbose_name_plural': 'DNS comments'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='dnscryptokey',
|
||||
options={'verbose_name': 'DNS crypto key', 'verbose_name_plural': 'DNS crypto keys'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='dnsdomainmetadata',
|
||||
options={'verbose_name': 'DNS domain metadata item', 'verbose_name_plural': 'DNS domain metadata items'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='dnssupermaster',
|
||||
options={'verbose_name': 'DNS supermaster', 'verbose_name_plural': 'DNS supermasters'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='dnstsigkey',
|
||||
options={'verbose_name': 'DNS TSIG key', 'verbose_name_plural': 'DNS TSIG keys'},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='dnsdomainmetadata',
|
||||
name='kind',
|
||||
field=models.CharField(max_length=32, choices=[('ALLOW-DNSUPDATE-FROM', 'ALLOW-DNSUPDATE-FROM'), ('ALSO-NOTIFY', 'ALSO-NOTIFY'), ('AXFR-MASTER-TSIG', 'AXFR-MASTER-TSIG'), ('AXFR-SOURCE', 'AXFR-SOURCE'), ('FORWARD-DNSUPDATE', 'FORWARD-DNSUPDATE'), ('GSS-ACCEPTOR-PRINCIPAL', 'GSS-ACCEPTOR-PRINCIPAL'), ('GSS-ALLOW-AXFR-PRINCIPAL', 'GSS-ALLOW-AXFR-PRINCIPAL'), ('LUA-AXFR-SCRIPT', 'LUA-AXFR-SCRIPT'), ('NSEC3NARROW', 'NSEC3NARROW'), ('NSEC3PARAM', 'NSEC3PARAM'), ('PRESIGNED', 'PRESIGNED'), ('PUBLISH_CDNSKEY', 'PUBLISH_CDNSKEY'), ('PUBLISH_CDS', 'PUBLISH_CDS'), ('SOA-EDIT', 'SOA-EDIT'), ('SOA-EDIT-DNSUPDATE', 'SOA-EDIT-DNSUPDATE'), ('TSIG-ALLOW-AXFR', 'TSIG-ALLOW-AXFR'), ('TSIG-ALLOW-DNSUPDATE', 'TSIG-ALLOW-DNSUPDATE')]),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='dnstsigkey',
|
||||
name='algorithm',
|
||||
field=models.CharField(max_length=50, choices=[('hmac-md5', 'HMAC MD5'), ('hmac-sha1', 'HMAC SHA1'), ('hmac-sha224', 'HMAC SHA224'), ('hmac-sha256', 'HMAC SHA256'), ('hmac-sha384', 'HMAC SHA384'), ('hmac-sha512', 'HMAC SHA512')]),
|
||||
),
|
||||
]
|
|
@ -19,6 +19,36 @@ DNS_DOMAIN_TYPES = Choices(
|
|||
('NATIVE', _('Native')),
|
||||
)
|
||||
|
||||
# see https://doc.powerdns.com/md/authoritative/domainmetadata/
|
||||
DNS_DOMAIN_METADATA_KINDS = Choices(
|
||||
'ALLOW-DNSUPDATE-FROM',
|
||||
'ALSO-NOTIFY',
|
||||
'AXFR-MASTER-TSIG',
|
||||
'AXFR-SOURCE',
|
||||
'FORWARD-DNSUPDATE',
|
||||
'GSS-ACCEPTOR-PRINCIPAL',
|
||||
'GSS-ALLOW-AXFR-PRINCIPAL',
|
||||
'LUA-AXFR-SCRIPT',
|
||||
'NSEC3NARROW',
|
||||
'NSEC3PARAM',
|
||||
'PRESIGNED',
|
||||
'PUBLISH_CDNSKEY',
|
||||
'PUBLISH_CDS',
|
||||
'SOA-EDIT',
|
||||
'SOA-EDIT-DNSUPDATE',
|
||||
'TSIG-ALLOW-AXFR',
|
||||
'TSIG-ALLOW-DNSUPDATE',
|
||||
)
|
||||
|
||||
DNS_TSIG_KEY_ALGORITHMS = Choices(
|
||||
('hmac-md5', _('HMAC MD5')),
|
||||
('hmac-sha1', _('HMAC SHA1')),
|
||||
('hmac-sha224', _('HMAC SHA224')),
|
||||
('hmac-sha256', _('HMAC SHA256')),
|
||||
('hmac-sha384', _('HMAC SHA384')),
|
||||
('hmac-sha512', _('HMAC SHA512')),
|
||||
)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DomainBase(TimeStampedModel):
|
||||
|
@ -144,6 +174,7 @@ class DNSDomain(DomainBase):
|
|||
return self.domain
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DNSRecord(models.Model):
|
||||
"""
|
||||
This model represents a DNS record. The model is similar to the record
|
||||
|
@ -195,7 +226,12 @@ class DNSRecord(models.Model):
|
|||
['name', 'recordtype']
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return "{name} IN {type} {content}".format(
|
||||
name=self.name, type=self.recordtype, content=self.content)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DNSSupermaster(models.Model):
|
||||
"""
|
||||
This model represents the supermasters table in the PowerDNS schema
|
||||
|
@ -217,15 +253,24 @@ class DNSSupermaster(models.Model):
|
|||
settings.AUTH_USER_MODEL, verbose_name=_('customer'))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('DNS supermaster')
|
||||
verbose_name_plural = _('DNS supermasters')
|
||||
unique_together = (
|
||||
('ip', 'nameserver')
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return "{ip} {nameserver}".format(
|
||||
ip=self.ip, nameserver=self.nameserver)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DNSComment(models.Model):
|
||||
"""
|
||||
This model represents the comments table in the PowerDNS schema specified
|
||||
in https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/.
|
||||
in https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/. The
|
||||
comments table is used to store user comments related to individual DNS
|
||||
records.
|
||||
|
||||
CREATE TABLE comments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
@ -257,17 +302,26 @@ class DNSComment(models.Model):
|
|||
# check constraint is added via RunSQL in migration
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('DNS comment')
|
||||
verbose_name_plural = _('DNS comments')
|
||||
index_together = [
|
||||
['name', 'commenttype'],
|
||||
['domain', 'modified_at']
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return "{name} IN {type}: {comment}".format(
|
||||
name=self.name, type=self.commenttype, comment=self.comment)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DNSDomainMetadata(models.Model):
|
||||
"""
|
||||
This model represents the domainmetadata table in the PowerDNS schema
|
||||
specified in
|
||||
https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/.
|
||||
The domainmetadata table is used to store domain meta data as described in
|
||||
https://doc.powerdns.com/md/authoritative/domainmetadata/.
|
||||
|
||||
CREATE TABLE domainmetadata (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
@ -279,10 +333,19 @@ class DNSDomainMetadata(models.Model):
|
|||
CREATE INDEX domainidmetaindex ON domainmetadata(domain_id);
|
||||
"""
|
||||
domain = models.ForeignKey('DNSDomain')
|
||||
kind = models.CharField(max_length=32)
|
||||
kind = models.CharField(max_length=32, choices=DNS_DOMAIN_METADATA_KINDS)
|
||||
content = models.TextField()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('DNS domain metadata item')
|
||||
verbose_name_plural = _('DNS domain metadata items')
|
||||
|
||||
def __str__(self):
|
||||
return "{domain} {kind} {content}".format(
|
||||
domain=self.domain.domain, kind=self.kind, content=self.content)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DNSCryptoKey(models.Model):
|
||||
"""
|
||||
This model represents the cryptokeys table in the PowerDNS schema
|
||||
|
@ -304,7 +367,16 @@ class DNSCryptoKey(models.Model):
|
|||
active = models.BooleanField(default=True)
|
||||
content = models.TextField()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('DNS crypto key')
|
||||
verbose_name_plural = _('DNS crypto keys')
|
||||
|
||||
def __str__(self):
|
||||
return "{domain} {content}".format(
|
||||
domain=self.domain.domain, content=self.content)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DNSTSIGKey(models.Model):
|
||||
"""
|
||||
This model represents the tsigkeys table in the PowerDNS schema specified
|
||||
|
@ -321,11 +393,17 @@ class DNSTSIGKey(models.Model):
|
|||
CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);
|
||||
"""
|
||||
name = models.CharField(max_length=255)
|
||||
algorithm = models.CharField(max_length=50)
|
||||
algorithm = models.CharField(max_length=50, choices=DNS_TSIG_KEY_ALGORITHMS)
|
||||
secret = models.CharField(max_length=255)
|
||||
# check constraint is added via RunSQL in migration
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('DNS TSIG key')
|
||||
verbose_name_plural = _('DNS TSIG keys')
|
||||
unique_together = [
|
||||
['name', 'algorithm']
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return "{name} {algorithm} XXXX".format(
|
||||
name=self.name, algorithm=self.algorithm)
|
||||
|
|
|
@ -10,9 +10,16 @@ from django.test import TestCase
|
|||
from django.contrib.auth import get_user_model
|
||||
|
||||
from domains.models import (
|
||||
DNSComment,
|
||||
DNSCryptoKey,
|
||||
DNSDomain,
|
||||
DNSDomainMetadata,
|
||||
DNSRecord,
|
||||
DNSSupermaster,
|
||||
DNSTSIGKey,
|
||||
DomainBase,
|
||||
MailDomain,
|
||||
HostingDomain,
|
||||
MailDomain,
|
||||
)
|
||||
from hostingpackages.models import (
|
||||
CustomerHostingPackage,
|
||||
|
@ -27,14 +34,14 @@ TEST_USER = 'test'
|
|||
|
||||
class DomainBaseTest(TestCase):
|
||||
|
||||
def test__str__(self):
|
||||
def test___str__(self):
|
||||
db = DomainBase(domain='test')
|
||||
self.assertEqual(str(db), 'test')
|
||||
|
||||
|
||||
class MailDomainTest(TestCase):
|
||||
|
||||
def test__str__(self):
|
||||
def test___str__(self):
|
||||
md = MailDomain.objects.create(domain='example.org')
|
||||
self.assertEqual(str(md), 'example.org')
|
||||
|
||||
|
@ -77,8 +84,65 @@ class HostingDomainManagerTest(TestCase):
|
|||
self.assertIsNotNone(hostingdomain)
|
||||
self.assertTrue(hostingdomain.customer, package.customer)
|
||||
|
||||
|
||||
class HostingDomainTest(TestCase):
|
||||
|
||||
def test__str__(self):
|
||||
def test___str__(self):
|
||||
hostingdomain = HostingDomain(domain='test')
|
||||
self.assertEqual(str(hostingdomain), 'test')
|
||||
|
||||
|
||||
class DNSDomainTest(TestCase):
|
||||
|
||||
def test___str__(self):
|
||||
dnsdomain = DNSDomain(domain='test')
|
||||
self.assertEqual(str(dnsdomain), 'test')
|
||||
|
||||
|
||||
class DNSRecordTest(TestCase):
|
||||
|
||||
def test___str__(self):
|
||||
dnsrecord = DNSRecord(
|
||||
name='localhost', recordtype='A', content='127.0.0.1')
|
||||
self.assertEqual(str(dnsrecord), 'localhost IN A 127.0.0.1')
|
||||
|
||||
|
||||
class DNSSupermasterTest(TestCase):
|
||||
|
||||
def test___str__(self):
|
||||
dnssupermaster = DNSSupermaster(
|
||||
ip='127.0.0.1', nameserver='dns.example.org')
|
||||
self.assertEqual(str(dnssupermaster), '127.0.0.1 dns.example.org')
|
||||
|
||||
|
||||
class DNSCommentTest(TestCase):
|
||||
|
||||
def test___str__(self):
|
||||
dnscomment = DNSComment(
|
||||
name='localhost', commenttype='A', comment='good stuff')
|
||||
self.assertEqual(str(dnscomment), 'localhost IN A: good stuff')
|
||||
|
||||
|
||||
class DNSDomainMetadataTest(TestCase):
|
||||
|
||||
def test___str__(self):
|
||||
dnsdomain = DNSDomain(domain='test')
|
||||
dnsdomainmetadata = DNSDomainMetadata(
|
||||
domain=dnsdomain, kind='SOA-EDIT', content='INCEPTION')
|
||||
self.assertEqual(str(dnsdomainmetadata), 'test SOA-EDIT INCEPTION')
|
||||
|
||||
|
||||
class DNSCryptoKeyTest(TestCase):
|
||||
|
||||
def test___str__(self):
|
||||
dnsdomain = DNSDomain(domain='test')
|
||||
dnscryptokey = DNSCryptoKey(domain=dnsdomain, content='testvalue')
|
||||
self.assertEqual(str(dnscryptokey), 'test testvalue')
|
||||
|
||||
|
||||
class DNSTSIGKeyTest(TestCase):
|
||||
|
||||
def test___str__(self):
|
||||
dnstsigkey = DNSTSIGKey(
|
||||
name='testkey', algorithm='hmac-md5', secret='dummykey')
|
||||
self.assertEqual(str(dnstsigkey), 'testkey hmac-md5 XXXX')
|
||||
|
|
Loading…
Reference in a new issue