netbox-plugin-dns 1.1.2__py3-none-any.whl → 1.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of netbox-plugin-dns might be problematic. Click here for more details.
- netbox_dns/__init__.py +6 -5
- netbox_dns/api/nested_serializers.py +3 -2
- netbox_dns/api/serializers_/nameserver.py +2 -1
- netbox_dns/api/serializers_/record.py +5 -4
- netbox_dns/api/serializers_/record_template.py +2 -1
- netbox_dns/api/serializers_/view.py +2 -1
- netbox_dns/api/serializers_/zone.py +12 -11
- netbox_dns/api/serializers_/zone_template.py +8 -7
- netbox_dns/api/views.py +9 -4
- netbox_dns/choices/record.py +4 -2
- netbox_dns/choices/zone.py +6 -4
- netbox_dns/fields/address.py +2 -1
- netbox_dns/fields/network.py +2 -1
- netbox_dns/fields/rfc2317.py +7 -3
- netbox_dns/filtersets/nameserver.py +3 -2
- netbox_dns/filtersets/record.py +10 -9
- netbox_dns/filtersets/record_template.py +3 -2
- netbox_dns/filtersets/view.py +3 -2
- netbox_dns/filtersets/zone.py +24 -22
- netbox_dns/filtersets/zone_template.py +15 -14
- netbox_dns/forms/nameserver.py +41 -17
- netbox_dns/forms/record.py +43 -26
- netbox_dns/forms/record_template.py +49 -28
- netbox_dns/forms/registrar.py +21 -17
- netbox_dns/forms/registration_contact.py +37 -25
- netbox_dns/forms/view.py +49 -27
- netbox_dns/forms/zone.py +167 -120
- netbox_dns/forms/zone_template.py +53 -43
- netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
- netbox_dns/management/commands/rebuild_dnssync.py +14 -1
- netbox_dns/models/nameserver.py +6 -2
- netbox_dns/models/record.py +63 -30
- netbox_dns/models/record_template.py +16 -8
- netbox_dns/models/registrar.py +11 -7
- netbox_dns/models/registration_contact.py +23 -11
- netbox_dns/models/view.py +15 -6
- netbox_dns/models/zone.py +65 -43
- netbox_dns/models/zone_template.py +12 -10
- netbox_dns/navigation.py +30 -28
- netbox_dns/signals/ipam_dnssync.py +21 -14
- netbox_dns/tables/ipam_dnssync.py +2 -1
- netbox_dns/tables/nameserver.py +2 -0
- netbox_dns/tables/record.py +21 -11
- netbox_dns/tables/record_template.py +12 -5
- netbox_dns/tables/registrar.py +2 -0
- netbox_dns/tables/registration_contact.py +2 -0
- netbox_dns/tables/view.py +3 -1
- netbox_dns/tables/zone.py +15 -2
- netbox_dns/tables/zone_template.py +7 -0
- netbox_dns/templates/netbox_dns/nameserver.html +6 -5
- netbox_dns/templates/netbox_dns/record/managed.html +2 -1
- netbox_dns/templates/netbox_dns/record/related.html +26 -14
- netbox_dns/templates/netbox_dns/record.html +39 -20
- netbox_dns/templates/netbox_dns/recordtemplate.html +27 -15
- netbox_dns/templates/netbox_dns/registrar.html +11 -10
- netbox_dns/templates/netbox_dns/registrationcontact.html +16 -15
- netbox_dns/templates/netbox_dns/view/button.html +2 -1
- netbox_dns/templates/netbox_dns/view/prefix.html +7 -4
- netbox_dns/templates/netbox_dns/view/related.html +26 -10
- netbox_dns/templates/netbox_dns/view.html +11 -14
- netbox_dns/templates/netbox_dns/zone/base.html +2 -1
- netbox_dns/templates/netbox_dns/zone/child.html +3 -2
- netbox_dns/templates/netbox_dns/zone/record.html +3 -2
- netbox_dns/templates/netbox_dns/zone/registration.html +8 -7
- netbox_dns/templates/netbox_dns/zone.html +28 -30
- netbox_dns/templates/netbox_dns/zonetemplate.html +27 -17
- netbox_dns/utilities/ipam_dnssync.py +15 -4
- netbox_dns/validators/dns_name.py +11 -4
- netbox_dns/validators/dns_value.py +9 -4
- netbox_dns/validators/rfc2317.py +6 -3
- netbox_dns/views/nameserver.py +4 -2
- netbox_dns/views/record_template.py +4 -3
- netbox_dns/views/registrar.py +3 -1
- netbox_dns/views/registration_contact.py +2 -1
- netbox_dns/views/view.py +2 -1
- netbox_dns/views/zone.py +6 -4
- netbox_dns/views/zone_template.py +8 -7
- {netbox_plugin_dns-1.1.2.dist-info → netbox_plugin_dns-1.1.3.dist-info}/METADATA +1 -1
- netbox_plugin_dns-1.1.3.dist-info/RECORD +150 -0
- netbox_plugin_dns-1.1.2.dist-info/RECORD +0 -148
- {netbox_plugin_dns-1.1.2.dist-info → netbox_plugin_dns-1.1.3.dist-info}/LICENSE +0 -0
- {netbox_plugin_dns-1.1.2.dist-info → netbox_plugin_dns-1.1.3.dist-info}/WHEEL +0 -0
- {netbox_plugin_dns-1.1.2.dist-info → netbox_plugin_dns-1.1.3.dist-info}/top_level.txt +0 -0
|
@@ -4,6 +4,7 @@ from dns import name as dns_name
|
|
|
4
4
|
from django.core.exceptions import ValidationError
|
|
5
5
|
from django.db import models
|
|
6
6
|
from django.urls import reverse
|
|
7
|
+
from django.utils.translation import gettext_lazy as _
|
|
7
8
|
|
|
8
9
|
from netbox.models import NetBoxModel
|
|
9
10
|
from netbox.search import SearchIndex, register_search
|
|
@@ -23,40 +24,45 @@ __all__ = (
|
|
|
23
24
|
|
|
24
25
|
class RecordTemplate(NetBoxModel):
|
|
25
26
|
name = models.CharField(
|
|
26
|
-
verbose_name="Template
|
|
27
|
+
verbose_name=_("Template Name"),
|
|
27
28
|
unique=True,
|
|
28
29
|
max_length=200,
|
|
29
30
|
)
|
|
30
31
|
record_name = models.CharField(
|
|
31
|
-
verbose_name="Name",
|
|
32
|
+
verbose_name=_("Name"),
|
|
32
33
|
max_length=255,
|
|
33
34
|
)
|
|
34
35
|
description = models.CharField(
|
|
36
|
+
verbose_name=_("Description"),
|
|
35
37
|
max_length=200,
|
|
36
38
|
blank=True,
|
|
37
39
|
)
|
|
38
40
|
type = models.CharField(
|
|
41
|
+
verbose_name=_("Type"),
|
|
39
42
|
choices=RecordTypeChoices,
|
|
40
43
|
)
|
|
41
44
|
value = models.CharField(
|
|
45
|
+
verbose_name=_("Value"),
|
|
42
46
|
max_length=65535,
|
|
43
47
|
)
|
|
44
48
|
status = models.CharField(
|
|
49
|
+
verbose_name=_("Status"),
|
|
45
50
|
choices=RecordStatusChoices,
|
|
46
51
|
default=RecordStatusChoices.STATUS_ACTIVE,
|
|
47
52
|
blank=False,
|
|
48
53
|
)
|
|
49
54
|
ttl = models.PositiveIntegerField(
|
|
50
|
-
verbose_name="TTL",
|
|
55
|
+
verbose_name=_("TTL"),
|
|
51
56
|
null=True,
|
|
52
57
|
blank=True,
|
|
53
58
|
)
|
|
54
59
|
disable_ptr = models.BooleanField(
|
|
55
|
-
verbose_name="Disable PTR",
|
|
56
|
-
help_text="Disable PTR record creation",
|
|
60
|
+
verbose_name=_("Disable PTR"),
|
|
61
|
+
help_text=_("Disable PTR record creation"),
|
|
57
62
|
default=False,
|
|
58
63
|
)
|
|
59
64
|
tenant = models.ForeignKey(
|
|
65
|
+
verbose_name=_("Tenant"),
|
|
60
66
|
to="tenancy.Tenant",
|
|
61
67
|
on_delete=models.PROTECT,
|
|
62
68
|
related_name="+",
|
|
@@ -85,8 +91,8 @@ class RecordTemplate(NetBoxModel):
|
|
|
85
91
|
)
|
|
86
92
|
|
|
87
93
|
class Meta:
|
|
88
|
-
verbose_name = "Record Template"
|
|
89
|
-
verbose_name_plural = "Record Templates"
|
|
94
|
+
verbose_name = _("Record Template")
|
|
95
|
+
verbose_name_plural = _("Record Templates")
|
|
90
96
|
|
|
91
97
|
ordering = ("name",)
|
|
92
98
|
|
|
@@ -155,7 +161,9 @@ class RecordTemplate(NetBoxModel):
|
|
|
155
161
|
record = Record.objects.create(**record_data)
|
|
156
162
|
except ValidationError as exc:
|
|
157
163
|
raise ValidationError(
|
|
158
|
-
|
|
164
|
+
_("Error while processing record template {template}: {error}").format(
|
|
165
|
+
template=self, error=exc.messages[0]
|
|
166
|
+
)
|
|
159
167
|
)
|
|
160
168
|
|
|
161
169
|
if tags := self.tags.all():
|
netbox_dns/models/registrar.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
from django.urls import reverse
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
3
4
|
|
|
4
5
|
from netbox.models import NetBoxModel
|
|
5
6
|
from netbox.search import SearchIndex, register_search
|
|
@@ -16,38 +17,41 @@ class Registrar(NetBoxModel):
|
|
|
16
17
|
# Data fields according to https://www.icann.org/resources/pages/rdds-labeling-policy-2017-02-01-en
|
|
17
18
|
# -
|
|
18
19
|
name = models.CharField(
|
|
20
|
+
verbose_name=_("Name"),
|
|
19
21
|
unique=True,
|
|
20
22
|
max_length=255,
|
|
21
23
|
)
|
|
22
24
|
description = models.CharField(
|
|
25
|
+
verbose_name=_("Description"),
|
|
23
26
|
blank=True,
|
|
24
27
|
max_length=200,
|
|
25
28
|
)
|
|
26
29
|
iana_id = models.IntegerField(
|
|
27
|
-
verbose_name="IANA ID",
|
|
30
|
+
verbose_name=_("IANA ID"),
|
|
28
31
|
null=True,
|
|
29
32
|
blank=True,
|
|
30
33
|
)
|
|
31
34
|
referral_url = models.URLField(
|
|
32
|
-
verbose_name="Referral URL",
|
|
35
|
+
verbose_name=_("Referral URL"),
|
|
33
36
|
max_length=255,
|
|
34
37
|
blank=True,
|
|
35
38
|
)
|
|
36
39
|
whois_server = models.CharField(
|
|
37
|
-
verbose_name="WHOIS Server",
|
|
40
|
+
verbose_name=_("WHOIS Server"),
|
|
38
41
|
max_length=255,
|
|
39
42
|
blank=True,
|
|
40
43
|
)
|
|
41
44
|
address = models.CharField(
|
|
45
|
+
verbose_name=_("Address"),
|
|
42
46
|
max_length=200,
|
|
43
47
|
blank=True,
|
|
44
48
|
)
|
|
45
49
|
abuse_email = models.EmailField(
|
|
46
|
-
verbose_name="Abuse Email",
|
|
50
|
+
verbose_name=_("Abuse Email"),
|
|
47
51
|
blank=True,
|
|
48
52
|
)
|
|
49
53
|
abuse_phone = models.CharField(
|
|
50
|
-
verbose_name="Abuse Phone",
|
|
54
|
+
verbose_name=_("Abuse Phone"),
|
|
51
55
|
max_length=50,
|
|
52
56
|
blank=True,
|
|
53
57
|
)
|
|
@@ -59,8 +63,8 @@ class Registrar(NetBoxModel):
|
|
|
59
63
|
return str(self.name)
|
|
60
64
|
|
|
61
65
|
class Meta:
|
|
62
|
-
verbose_name = "Registrar"
|
|
63
|
-
verbose_name_plural = "Registrars"
|
|
66
|
+
verbose_name = _("Registrar")
|
|
67
|
+
verbose_name_plural = _("Registrars")
|
|
64
68
|
|
|
65
69
|
ordering = (
|
|
66
70
|
"name",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
from django.urls import reverse
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
3
4
|
|
|
4
5
|
from netbox.models import NetBoxModel
|
|
5
6
|
from netbox.search import SearchIndex, register_search
|
|
@@ -18,70 +19,81 @@ class RegistrationContact(NetBoxModel):
|
|
|
18
19
|
# Data fields according to https://www.icann.org/resources/pages/rdds-labeling-policy-2017-02-01-en
|
|
19
20
|
# -
|
|
20
21
|
contact_id = models.CharField(
|
|
21
|
-
verbose_name="Contact ID",
|
|
22
|
+
verbose_name=_("Contact ID"),
|
|
22
23
|
max_length=50,
|
|
23
24
|
unique=True,
|
|
24
25
|
)
|
|
25
26
|
name = models.CharField(
|
|
27
|
+
verbose_name=_("Name"),
|
|
26
28
|
blank=True,
|
|
27
29
|
max_length=100,
|
|
28
30
|
)
|
|
29
31
|
description = models.CharField(
|
|
32
|
+
verbose_name=_("Description"),
|
|
30
33
|
blank=True,
|
|
31
34
|
max_length=200,
|
|
32
35
|
)
|
|
33
36
|
organization = models.CharField(
|
|
37
|
+
verbose_name=_("Organization"),
|
|
34
38
|
blank=True,
|
|
35
39
|
max_length=200,
|
|
36
40
|
)
|
|
37
41
|
street = models.CharField(
|
|
42
|
+
verbose_name=_("Street"),
|
|
38
43
|
blank=True,
|
|
39
44
|
max_length=50,
|
|
40
45
|
)
|
|
41
46
|
city = models.CharField(
|
|
47
|
+
verbose_name=_("City"),
|
|
42
48
|
blank=True,
|
|
43
49
|
max_length=50,
|
|
44
50
|
)
|
|
45
51
|
state_province = models.CharField(
|
|
46
|
-
verbose_name="State/Province",
|
|
52
|
+
verbose_name=_("State/Province"),
|
|
47
53
|
blank=True,
|
|
48
54
|
max_length=255,
|
|
49
55
|
)
|
|
50
56
|
postal_code = models.CharField(
|
|
51
|
-
verbose_name="Postal Code",
|
|
57
|
+
verbose_name=_("Postal Code"),
|
|
52
58
|
blank=True,
|
|
53
59
|
max_length=20,
|
|
54
60
|
)
|
|
55
61
|
country = models.CharField(
|
|
56
|
-
verbose_name="Country (ISO 3166)",
|
|
62
|
+
verbose_name=_("Country (ISO 3166)"),
|
|
57
63
|
blank=True,
|
|
58
64
|
max_length=2,
|
|
59
65
|
)
|
|
60
66
|
phone = models.CharField(
|
|
61
|
-
verbose_name="Phone",
|
|
67
|
+
verbose_name=_("Phone"),
|
|
62
68
|
blank=True,
|
|
63
69
|
max_length=50,
|
|
64
70
|
)
|
|
65
71
|
phone_ext = models.CharField(
|
|
66
|
-
verbose_name="Phone Extension",
|
|
72
|
+
verbose_name=_("Phone Extension"),
|
|
67
73
|
blank=True,
|
|
68
74
|
max_length=50,
|
|
69
75
|
)
|
|
70
76
|
fax = models.CharField(
|
|
71
|
-
verbose_name="Fax",
|
|
77
|
+
verbose_name=_("Fax"),
|
|
72
78
|
blank=True,
|
|
73
79
|
max_length=50,
|
|
74
80
|
)
|
|
75
81
|
fax_ext = models.CharField(
|
|
76
|
-
verbose_name="Fax Extension",
|
|
82
|
+
verbose_name=_("Fax Extension"),
|
|
77
83
|
blank=True,
|
|
78
84
|
max_length=50,
|
|
79
85
|
)
|
|
80
86
|
email = models.EmailField(
|
|
81
|
-
verbose_name="Email",
|
|
87
|
+
verbose_name=_("Email"),
|
|
82
88
|
blank=True,
|
|
83
89
|
)
|
|
84
90
|
|
|
91
|
+
# +
|
|
92
|
+
# TODO: Retained for backwards compatibility with older versions where
|
|
93
|
+
# 'RegistrationContact' was still ambiguously named 'Contact'.
|
|
94
|
+
#
|
|
95
|
+
# Removing it requires a data migration.
|
|
96
|
+
# -
|
|
85
97
|
tags = TaggableManager(
|
|
86
98
|
through="extras.TaggedItem",
|
|
87
99
|
related_name="netbox_dns_contact_set",
|
|
@@ -114,8 +126,8 @@ class RegistrationContact(NetBoxModel):
|
|
|
114
126
|
return self.contact_id
|
|
115
127
|
|
|
116
128
|
class Meta:
|
|
117
|
-
verbose_name = "Registration Contact"
|
|
118
|
-
verbose_name_plural = "Registration Contacts"
|
|
129
|
+
verbose_name = _("Registration Contact")
|
|
130
|
+
verbose_name_plural = _("Registration Contacts")
|
|
119
131
|
|
|
120
132
|
ordering = (
|
|
121
133
|
"name",
|
netbox_dns/models/view.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
from django.urls import reverse
|
|
3
3
|
from django.core.exceptions import ValidationError
|
|
4
|
+
from django.utils.translation import gettext_lazy as _
|
|
5
|
+
from django.utils.translation import pgettext_lazy as _p
|
|
4
6
|
|
|
5
7
|
from netbox.models import NetBoxModel
|
|
6
8
|
from netbox.models.features import ContactsMixin
|
|
@@ -26,27 +28,32 @@ __all__ = (
|
|
|
26
28
|
|
|
27
29
|
class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
28
30
|
name = models.CharField(
|
|
31
|
+
verbose_name=_("Name"),
|
|
29
32
|
unique=True,
|
|
30
33
|
max_length=255,
|
|
31
34
|
)
|
|
32
35
|
description = models.CharField(
|
|
36
|
+
verbose_name=_("Description"),
|
|
33
37
|
max_length=200,
|
|
34
38
|
blank=True,
|
|
35
39
|
)
|
|
36
40
|
default_view = models.BooleanField(
|
|
41
|
+
verbose_name=_("Default View"),
|
|
37
42
|
default=False,
|
|
38
43
|
)
|
|
39
44
|
prefixes = models.ManyToManyField(
|
|
45
|
+
verbose_name=_("IPAM Prefixes"),
|
|
40
46
|
to="ipam.Prefix",
|
|
41
47
|
related_name="netbox_dns_views",
|
|
42
48
|
blank=True,
|
|
43
49
|
)
|
|
44
50
|
ip_address_filter = models.JSONField(
|
|
45
|
-
verbose_name="IP Address Filter",
|
|
51
|
+
verbose_name=_("IP Address Filter"),
|
|
46
52
|
blank=True,
|
|
47
53
|
null=True,
|
|
48
54
|
)
|
|
49
55
|
tenant = models.ForeignKey(
|
|
56
|
+
verbose_name=_("Tenant"),
|
|
50
57
|
to="tenancy.Tenant",
|
|
51
58
|
on_delete=models.PROTECT,
|
|
52
59
|
related_name="netbox_dns_views",
|
|
@@ -70,17 +77,17 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
70
77
|
return str(self.name)
|
|
71
78
|
|
|
72
79
|
class Meta:
|
|
73
|
-
verbose_name = "View"
|
|
74
|
-
verbose_name_plural = "Views"
|
|
80
|
+
verbose_name = _p("DNS", "View")
|
|
81
|
+
verbose_name_plural = _p("DNS", "Views")
|
|
75
82
|
|
|
76
83
|
ordering = ("name",)
|
|
77
84
|
|
|
78
85
|
def delete(self, *args, **kwargs):
|
|
79
86
|
if self.default_view:
|
|
80
87
|
if current_request.get() is not None:
|
|
81
|
-
raise AbortRequest("The default view cannot be deleted")
|
|
88
|
+
raise AbortRequest(_("The default view cannot be deleted"))
|
|
82
89
|
|
|
83
|
-
raise ValidationError("The default view cannot be deleted")
|
|
90
|
+
raise ValidationError(_("The default view cannot be deleted"))
|
|
84
91
|
|
|
85
92
|
super().delete(*args, **kwargs)
|
|
86
93
|
|
|
@@ -95,7 +102,9 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
95
102
|
):
|
|
96
103
|
raise ValidationError(
|
|
97
104
|
{
|
|
98
|
-
"default_view":
|
|
105
|
+
"default_view": _(
|
|
106
|
+
"Please select a different view as default view to change this setting!"
|
|
107
|
+
)
|
|
99
108
|
}
|
|
100
109
|
)
|
|
101
110
|
|
netbox_dns/models/zone.py
CHANGED
|
@@ -16,6 +16,8 @@ from django.urls import reverse
|
|
|
16
16
|
from django.db.models.signals import m2m_changed
|
|
17
17
|
from django.dispatch import receiver
|
|
18
18
|
from django.conf import settings
|
|
19
|
+
from django.utils.translation import gettext_lazy as _
|
|
20
|
+
from django.utils.translation import pgettext_lazy as _p
|
|
19
21
|
|
|
20
22
|
from netbox.models import NetBoxModel
|
|
21
23
|
from netbox.models.features import ContactsMixin
|
|
@@ -81,95 +83,101 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
81
83
|
self._ip_addresses_checked = False
|
|
82
84
|
|
|
83
85
|
view = models.ForeignKey(
|
|
86
|
+
verbose_name=_p("DNS", "View"),
|
|
84
87
|
to="View",
|
|
85
88
|
on_delete=models.PROTECT,
|
|
86
89
|
null=False,
|
|
87
90
|
)
|
|
88
91
|
name = models.CharField(
|
|
92
|
+
verbose_name=_("Name"),
|
|
89
93
|
max_length=255,
|
|
90
94
|
)
|
|
91
95
|
status = models.CharField(
|
|
96
|
+
verbose_name=_("Status"),
|
|
92
97
|
max_length=50,
|
|
93
98
|
choices=ZoneStatusChoices,
|
|
94
99
|
default=ZoneStatusChoices.STATUS_ACTIVE,
|
|
95
100
|
blank=True,
|
|
96
101
|
)
|
|
97
102
|
nameservers = models.ManyToManyField(
|
|
103
|
+
verbose_name=_("Nameserver"),
|
|
98
104
|
to="NameServer",
|
|
99
105
|
related_name="zones",
|
|
100
106
|
blank=True,
|
|
101
107
|
)
|
|
102
108
|
default_ttl = models.PositiveIntegerField(
|
|
109
|
+
verbose_name=_("Default TTL"),
|
|
103
110
|
blank=True,
|
|
104
|
-
verbose_name="Default TTL",
|
|
105
111
|
validators=[MinValueValidator(1)],
|
|
106
112
|
)
|
|
107
113
|
soa_ttl = models.PositiveIntegerField(
|
|
114
|
+
verbose_name=_("SOA TTL"),
|
|
108
115
|
blank=False,
|
|
109
116
|
null=False,
|
|
110
|
-
verbose_name="SOA TTL",
|
|
111
117
|
validators=[MinValueValidator(1)],
|
|
112
118
|
)
|
|
113
119
|
soa_mname = models.ForeignKey(
|
|
120
|
+
verbose_name=_("SOA MName"),
|
|
114
121
|
to="NameServer",
|
|
115
122
|
related_name="zones_soa",
|
|
116
|
-
verbose_name="SOA MName",
|
|
117
123
|
on_delete=models.PROTECT,
|
|
118
124
|
blank=False,
|
|
119
125
|
null=False,
|
|
120
126
|
)
|
|
121
127
|
soa_rname = models.CharField(
|
|
128
|
+
verbose_name=_("SOA RName"),
|
|
122
129
|
max_length=255,
|
|
123
130
|
blank=False,
|
|
124
131
|
null=False,
|
|
125
|
-
verbose_name="SOA RName",
|
|
126
132
|
)
|
|
127
133
|
soa_serial = models.BigIntegerField(
|
|
134
|
+
verbose_name=_("SOA Serial"),
|
|
128
135
|
blank=True,
|
|
129
136
|
null=True,
|
|
130
|
-
verbose_name="SOA Serial",
|
|
131
137
|
validators=[MinValueValidator(1), MaxValueValidator(4294967295)],
|
|
132
138
|
)
|
|
133
139
|
soa_refresh = models.PositiveIntegerField(
|
|
140
|
+
verbose_name=_("SOA Refresh"),
|
|
134
141
|
blank=False,
|
|
135
142
|
null=False,
|
|
136
|
-
verbose_name="SOA Refresh",
|
|
137
143
|
validators=[MinValueValidator(1)],
|
|
138
144
|
)
|
|
139
145
|
soa_retry = models.PositiveIntegerField(
|
|
146
|
+
verbose_name=_("SOA Retry"),
|
|
140
147
|
blank=False,
|
|
141
148
|
null=False,
|
|
142
|
-
verbose_name="SOA Retry",
|
|
143
149
|
validators=[MinValueValidator(1)],
|
|
144
150
|
)
|
|
145
151
|
soa_expire = models.PositiveIntegerField(
|
|
152
|
+
verbose_name=_("SOA Expire"),
|
|
146
153
|
blank=False,
|
|
147
154
|
null=False,
|
|
148
|
-
verbose_name="SOA Expire",
|
|
149
155
|
validators=[MinValueValidator(1)],
|
|
150
156
|
)
|
|
151
157
|
soa_minimum = models.PositiveIntegerField(
|
|
158
|
+
verbose_name=_("SOA Minimum TTL"),
|
|
152
159
|
blank=False,
|
|
153
160
|
null=False,
|
|
154
|
-
verbose_name="SOA Minimum TTL",
|
|
155
161
|
validators=[MinValueValidator(1)],
|
|
156
162
|
)
|
|
157
163
|
soa_serial_auto = models.BooleanField(
|
|
158
|
-
verbose_name="Generate SOA Serial",
|
|
159
|
-
help_text="Automatically generate the SOA
|
|
164
|
+
verbose_name=_("Generate SOA Serial"),
|
|
165
|
+
help_text=_("Automatically generate the SOA serial number"),
|
|
160
166
|
default=True,
|
|
161
167
|
)
|
|
162
168
|
description = models.CharField(
|
|
169
|
+
verbose_name=_("Description"),
|
|
163
170
|
max_length=200,
|
|
164
171
|
blank=True,
|
|
165
172
|
)
|
|
166
173
|
arpa_network = NetworkField(
|
|
167
|
-
verbose_name="ARPA Network",
|
|
168
|
-
help_text="Network related to a reverse lookup zone (.arpa)",
|
|
174
|
+
verbose_name=_("ARPA Network"),
|
|
175
|
+
help_text=_("Network related to a reverse lookup zone (.arpa)"),
|
|
169
176
|
blank=True,
|
|
170
177
|
null=True,
|
|
171
178
|
)
|
|
172
179
|
tenant = models.ForeignKey(
|
|
180
|
+
verbose_name=_("Tenant"),
|
|
173
181
|
to="tenancy.Tenant",
|
|
174
182
|
on_delete=models.PROTECT,
|
|
175
183
|
related_name="netbox_dns_zones",
|
|
@@ -177,72 +185,66 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
177
185
|
null=True,
|
|
178
186
|
)
|
|
179
187
|
registrar = models.ForeignKey(
|
|
188
|
+
verbose_name=_("Registrar"),
|
|
180
189
|
to="Registrar",
|
|
181
190
|
on_delete=models.SET_NULL,
|
|
182
|
-
verbose_name="Registrar",
|
|
183
|
-
help_text="The external registrar the domain is registered with",
|
|
184
191
|
blank=True,
|
|
185
192
|
null=True,
|
|
186
193
|
)
|
|
187
194
|
registry_domain_id = models.CharField(
|
|
188
|
-
verbose_name="Registry Domain ID",
|
|
189
|
-
help_text="The ID of the domain assigned by the registry",
|
|
195
|
+
verbose_name=_("Registry Domain ID"),
|
|
190
196
|
max_length=50,
|
|
191
197
|
blank=True,
|
|
192
198
|
null=True,
|
|
193
199
|
)
|
|
194
200
|
registrant = models.ForeignKey(
|
|
201
|
+
verbose_name=_("Registrant"),
|
|
195
202
|
to="RegistrationContact",
|
|
196
203
|
on_delete=models.SET_NULL,
|
|
197
|
-
verbose_name="Registrant",
|
|
198
|
-
help_text="The owner of the domain",
|
|
199
204
|
blank=True,
|
|
200
205
|
null=True,
|
|
201
206
|
)
|
|
202
207
|
admin_c = models.ForeignKey(
|
|
208
|
+
verbose_name="Administrative Contact",
|
|
203
209
|
to="RegistrationContact",
|
|
204
210
|
on_delete=models.SET_NULL,
|
|
205
|
-
verbose_name="Admin Contact",
|
|
206
211
|
related_name="admin_c_zones",
|
|
207
|
-
help_text="The administrative contact for the domain",
|
|
208
212
|
blank=True,
|
|
209
213
|
null=True,
|
|
210
214
|
)
|
|
211
215
|
tech_c = models.ForeignKey(
|
|
216
|
+
verbose_name=_("Technical Contact"),
|
|
212
217
|
to="RegistrationContact",
|
|
213
218
|
on_delete=models.SET_NULL,
|
|
214
|
-
verbose_name="Technical Contact",
|
|
215
219
|
related_name="tech_c_zones",
|
|
216
|
-
help_text="The technical contact for the domain",
|
|
217
220
|
blank=True,
|
|
218
221
|
null=True,
|
|
219
222
|
)
|
|
220
223
|
billing_c = models.ForeignKey(
|
|
224
|
+
verbose_name=_("Billing Contact"),
|
|
221
225
|
to="RegistrationContact",
|
|
222
226
|
on_delete=models.SET_NULL,
|
|
223
|
-
verbose_name="Billing Contact",
|
|
224
227
|
related_name="billing_c_zones",
|
|
225
|
-
help_text="The billing contact for the domain",
|
|
226
228
|
blank=True,
|
|
227
229
|
null=True,
|
|
228
230
|
)
|
|
229
231
|
rfc2317_prefix = RFC2317NetworkField(
|
|
230
|
-
verbose_name="
|
|
231
|
-
help_text="RFC2317 IPv4 prefix
|
|
232
|
+
verbose_name=_("RFC2317 Prefix"),
|
|
233
|
+
help_text=_("RFC2317 IPv4 prefix with a length of at least 25 bits"),
|
|
232
234
|
blank=True,
|
|
233
235
|
null=True,
|
|
234
236
|
)
|
|
235
237
|
rfc2317_parent_managed = models.BooleanField(
|
|
236
|
-
verbose_name="RFC2317 Parent Managed",
|
|
237
|
-
help_text="The parent zone for the RFC2317 zone is managed by NetBox DNS",
|
|
238
|
+
verbose_name=_("RFC2317 Parent Managed"),
|
|
239
|
+
help_text=_("The parent zone for the RFC2317 zone is managed by NetBox DNS"),
|
|
238
240
|
default=False,
|
|
239
241
|
)
|
|
240
242
|
rfc2317_parent_zone = models.ForeignKey(
|
|
243
|
+
verbose_name=_("RFC2317 Parent Zone"),
|
|
241
244
|
to="self",
|
|
242
245
|
on_delete=models.SET_NULL,
|
|
243
|
-
verbose_name="RFC2317 Parent Zone",
|
|
244
246
|
related_name="rfc2317_child_zones",
|
|
245
|
-
help_text="Parent zone for RFC2317 reverse zones",
|
|
247
|
+
help_text=_("Parent zone for RFC2317 reverse zones"),
|
|
246
248
|
blank=True,
|
|
247
249
|
null=True,
|
|
248
250
|
)
|
|
@@ -266,8 +268,8 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
266
268
|
)
|
|
267
269
|
|
|
268
270
|
class Meta:
|
|
269
|
-
verbose_name = "Zone"
|
|
270
|
-
verbose_name_plural = "Zones"
|
|
271
|
+
verbose_name = _("Zone")
|
|
272
|
+
verbose_name_plural = _("Zones")
|
|
271
273
|
|
|
272
274
|
ordering = (
|
|
273
275
|
"view",
|
|
@@ -453,7 +455,9 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
453
455
|
ns_errors = []
|
|
454
456
|
|
|
455
457
|
if not nameservers:
|
|
456
|
-
ns_errors.append(
|
|
458
|
+
ns_errors.append(
|
|
459
|
+
_("No nameservers are configured for zone {zone}").format(zone=self)
|
|
460
|
+
)
|
|
457
461
|
|
|
458
462
|
for _nameserver in nameservers:
|
|
459
463
|
name = dns_name.from_text(_nameserver.name, origin=None)
|
|
@@ -477,7 +481,9 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
477
481
|
|
|
478
482
|
if not address_records:
|
|
479
483
|
ns_warnings.append(
|
|
480
|
-
|
|
484
|
+
_(
|
|
485
|
+
"Nameserver {nameserver} does not have an active address record in zone {zone}"
|
|
486
|
+
).format(nameserver=_nameserver.name, zone=ns_zone)
|
|
481
487
|
)
|
|
482
488
|
|
|
483
489
|
return ns_warnings, ns_errors
|
|
@@ -491,7 +497,11 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
491
497
|
|
|
492
498
|
if (new_serial - old_serial) % SOA_SERIAL_WRAP > MAX_SOA_SERIAL_INCREMENT:
|
|
493
499
|
raise ValidationError(
|
|
494
|
-
{
|
|
500
|
+
{
|
|
501
|
+
"soa_serial": _(
|
|
502
|
+
"soa_serial must not decrease for zone {zone}."
|
|
503
|
+
).format(zone=self.name)
|
|
504
|
+
}
|
|
495
505
|
)
|
|
496
506
|
|
|
497
507
|
def get_auto_serial(self):
|
|
@@ -602,7 +612,9 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
602
612
|
self.soa_mname = NameServer.objects.get(name=default_soa_mname)
|
|
603
613
|
except NameServer.DoesNotExist:
|
|
604
614
|
raise ValidationError(
|
|
605
|
-
|
|
615
|
+
_("Default soa_mname instance {nameserver} does not exist").format(
|
|
616
|
+
nameserver=default_soa_mname
|
|
617
|
+
)
|
|
606
618
|
)
|
|
607
619
|
|
|
608
620
|
super().clean_fields(exclude=exclude)
|
|
@@ -630,7 +642,7 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
630
642
|
) from None
|
|
631
643
|
|
|
632
644
|
if self.soa_rname in (None, ""):
|
|
633
|
-
raise ValidationError("soa_rname not set and no default value defined")
|
|
645
|
+
raise ValidationError(_("soa_rname not set and no default value defined"))
|
|
634
646
|
try:
|
|
635
647
|
dns_name.from_text(self.soa_rname, origin=dns_name.root)
|
|
636
648
|
validate_rname(self.soa_rname)
|
|
@@ -645,7 +657,9 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
645
657
|
if self.soa_serial is None:
|
|
646
658
|
raise ValidationError(
|
|
647
659
|
{
|
|
648
|
-
"soa_serial":
|
|
660
|
+
"soa_serial": _(
|
|
661
|
+
"soa_serial is not defined and soa_serial_auto is disabled for zone {zone}."
|
|
662
|
+
).format(zone=self.name)
|
|
649
663
|
}
|
|
650
664
|
)
|
|
651
665
|
|
|
@@ -663,7 +677,9 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
663
677
|
except ValidationError:
|
|
664
678
|
raise ValidationError(
|
|
665
679
|
{
|
|
666
|
-
"soa_serial_auto":
|
|
680
|
+
"soa_serial_auto": _(
|
|
681
|
+
"Enabling soa_serial_auto would decrease soa_serial for zone {zone}."
|
|
682
|
+
).format(zone=self.name)
|
|
667
683
|
}
|
|
668
684
|
)
|
|
669
685
|
|
|
@@ -697,7 +713,9 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
697
713
|
if self.arpa_network is not None:
|
|
698
714
|
raise ValidationError(
|
|
699
715
|
{
|
|
700
|
-
"rfc2317_prefix":
|
|
716
|
+
"rfc2317_prefix": _(
|
|
717
|
+
"A regular reverse zone can not be used as an RFC2317 zone."
|
|
718
|
+
)
|
|
701
719
|
}
|
|
702
720
|
)
|
|
703
721
|
|
|
@@ -707,7 +725,9 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
707
725
|
if rfc2317_parent_zone is None:
|
|
708
726
|
raise ValidationError(
|
|
709
727
|
{
|
|
710
|
-
"rfc2317_parent_managed":
|
|
728
|
+
"rfc2317_parent_managed": _(
|
|
729
|
+
"Parent zone not found in view {view}."
|
|
730
|
+
).format(view=self.view)
|
|
711
731
|
}
|
|
712
732
|
)
|
|
713
733
|
|
|
@@ -724,7 +744,9 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
724
744
|
if overlapping_zones.exists():
|
|
725
745
|
raise ValidationError(
|
|
726
746
|
{
|
|
727
|
-
"rfc2317_prefix":
|
|
747
|
+
"rfc2317_prefix": _(
|
|
748
|
+
"RFC2317 prefix overlaps with zone {zone}."
|
|
749
|
+
).format(zone=overlapping_zones.first())
|
|
728
750
|
}
|
|
729
751
|
)
|
|
730
752
|
|