Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import ipaddress
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _
class Prefix(models.Model):
name = models.SlugField(
unique=True,
verbose_name=_("name"),
)
prefix = models.GenericIPAddressField(
protocol='IPv6',
unique=True,
verbose_name=_("prefix"),
)
length = models.PositiveSmallIntegerField(
verbose_name=_("length"),
)
delegated_length = models.PositiveSmallIntegerField(
verbose_name=_("length of delegated prefixes"),
)
def network(self):
return ipaddress.IPv6Network(f'{self.prefix}/{self.length}')
def clean(self):
try:
self.network()
except:
raise ValidationError(f"{self.prefix}/{self.length} is not a valid network.")
if self.length >= self.delegated_length:
raise ValidationError(f"length ({self.length}) must be lower than delegated_length ({self.delegated_length}).")
if self.delegated_length > 128:
raise ValidationError(f"delegated_length {self.delegated_length} must be lower than or equal to 128.")
def __str__(self):
return str(self.network())
class Meta:
verbose_name = _("Prefix")
verbose_name_plural = _("Prefixes")
class DelegatedPrefix(models.Model):
prefix = models.ForeignKey(
Prefix,
on_delete=models.PROTECT,
related_name='delegated_prefixes',
verbose_name=_("prefix"),
)
delegated_prefix = models.GenericIPAddressField(
protocol='IPv6',
unique=True,
verbose_name=_("delegated prefix"),
)
gateway = models.GenericIPAddressField(
protocol='IPv6',
verbose_name=_("gateway"),
)
owner = models.ForeignKey(
settings.PREFIX_DELEGATION_OWNER,
on_delete=models.CASCADE,
verbose_name=_("owner"),
)
def network(self):
return ipaddress.IPv6Network(f'{self.delegated_prefix}/{self.prefix.delegated_length}')
def clean(self):
try:
network = self.network()
except:
raise ValidationError(f"{self.delegated_prefix}/{self.prefix.delegated_length} is not a valid network.")
prefix_network = self.prefix.network()
if not network.subnet_of(prefix_network):
raise ValidationError(f"{network} must be a subnet of {prefix_network}.")
def __str__(self):
return str(self.network())
class Meta:
verbose_name = "Delegated prefix"
verbose_name_plural = "Delegated prefixes"
class Nameserver(models.Model):
name = models.CharField(
max_length=253,
unique=True,
)
def __str__(self):
return self.name
class Meta:
verbose_name = "Name server"
verbose_name_plural = "Name servers"
class DelegatedReverseDns(models.Model):

Benjamin Graillot
committed
delegated_prefix = models.OneToOneField(
DelegatedPrefix,
on_delete=models.CASCADE,
related_name='delegated_reverse_dns'
)
nameservers = models.ManyToManyField(
Nameserver
)
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
def owner(self):
return self.delegated_prefix.owner
def clean(self):
if self.delegated_prefix.prefix.delegated_length % 4:
raise ValidationError(f"delegated_length must be a multiple of 4 in order to delegate a reverse DNS.")
def __str__(self):
network = self.delegated_prefix.network()
zone = network.network_address.exploded.replace(':', '')[network.prefixlen//4-1::-1]
zone = '.'.join(list(zone)) + '.ip6.arpa'
return zone
class Meta:
verbose_name = "Delegated reverse DNS"
verbose_name_plural = "Delegated reverse DNS"
class DsRecord(models.Model):
delegated_reverse_dns = models.ForeignKey(
DelegatedReverseDns,
on_delete=models.CASCADE,
related_name='ds_records'
)
key_tag = models.PositiveIntegerField()
algorithm = models.PositiveSmallIntegerField()
digest_type = models.PositiveSmallIntegerField()
digest = models.TextField()
def __str__(self):
return f"{self.ket_tag} {self.algorithm} {self.digest_type} {self.digest}"
class Meta:
verbose_name = "DS record"
verbose_name_plural = "DS records"