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.

Files changed (84) hide show
  1. netbox_dns/__init__.py +6 -5
  2. netbox_dns/api/nested_serializers.py +3 -2
  3. netbox_dns/api/serializers_/nameserver.py +2 -1
  4. netbox_dns/api/serializers_/record.py +5 -4
  5. netbox_dns/api/serializers_/record_template.py +2 -1
  6. netbox_dns/api/serializers_/view.py +2 -1
  7. netbox_dns/api/serializers_/zone.py +12 -11
  8. netbox_dns/api/serializers_/zone_template.py +8 -7
  9. netbox_dns/api/views.py +9 -4
  10. netbox_dns/choices/record.py +4 -2
  11. netbox_dns/choices/zone.py +6 -4
  12. netbox_dns/fields/address.py +2 -1
  13. netbox_dns/fields/network.py +2 -1
  14. netbox_dns/fields/rfc2317.py +7 -3
  15. netbox_dns/filtersets/nameserver.py +3 -2
  16. netbox_dns/filtersets/record.py +10 -9
  17. netbox_dns/filtersets/record_template.py +3 -2
  18. netbox_dns/filtersets/view.py +3 -2
  19. netbox_dns/filtersets/zone.py +24 -22
  20. netbox_dns/filtersets/zone_template.py +15 -14
  21. netbox_dns/forms/nameserver.py +41 -17
  22. netbox_dns/forms/record.py +43 -26
  23. netbox_dns/forms/record_template.py +49 -28
  24. netbox_dns/forms/registrar.py +21 -17
  25. netbox_dns/forms/registration_contact.py +37 -25
  26. netbox_dns/forms/view.py +49 -27
  27. netbox_dns/forms/zone.py +167 -120
  28. netbox_dns/forms/zone_template.py +53 -43
  29. netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
  30. netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
  31. netbox_dns/management/commands/rebuild_dnssync.py +14 -1
  32. netbox_dns/models/nameserver.py +6 -2
  33. netbox_dns/models/record.py +63 -30
  34. netbox_dns/models/record_template.py +16 -8
  35. netbox_dns/models/registrar.py +11 -7
  36. netbox_dns/models/registration_contact.py +23 -11
  37. netbox_dns/models/view.py +15 -6
  38. netbox_dns/models/zone.py +65 -43
  39. netbox_dns/models/zone_template.py +12 -10
  40. netbox_dns/navigation.py +30 -28
  41. netbox_dns/signals/ipam_dnssync.py +21 -14
  42. netbox_dns/tables/ipam_dnssync.py +2 -1
  43. netbox_dns/tables/nameserver.py +2 -0
  44. netbox_dns/tables/record.py +21 -11
  45. netbox_dns/tables/record_template.py +12 -5
  46. netbox_dns/tables/registrar.py +2 -0
  47. netbox_dns/tables/registration_contact.py +2 -0
  48. netbox_dns/tables/view.py +3 -1
  49. netbox_dns/tables/zone.py +15 -2
  50. netbox_dns/tables/zone_template.py +7 -0
  51. netbox_dns/templates/netbox_dns/nameserver.html +6 -5
  52. netbox_dns/templates/netbox_dns/record/managed.html +2 -1
  53. netbox_dns/templates/netbox_dns/record/related.html +26 -14
  54. netbox_dns/templates/netbox_dns/record.html +39 -20
  55. netbox_dns/templates/netbox_dns/recordtemplate.html +27 -15
  56. netbox_dns/templates/netbox_dns/registrar.html +11 -10
  57. netbox_dns/templates/netbox_dns/registrationcontact.html +16 -15
  58. netbox_dns/templates/netbox_dns/view/button.html +2 -1
  59. netbox_dns/templates/netbox_dns/view/prefix.html +7 -4
  60. netbox_dns/templates/netbox_dns/view/related.html +26 -10
  61. netbox_dns/templates/netbox_dns/view.html +11 -14
  62. netbox_dns/templates/netbox_dns/zone/base.html +2 -1
  63. netbox_dns/templates/netbox_dns/zone/child.html +3 -2
  64. netbox_dns/templates/netbox_dns/zone/record.html +3 -2
  65. netbox_dns/templates/netbox_dns/zone/registration.html +8 -7
  66. netbox_dns/templates/netbox_dns/zone.html +28 -30
  67. netbox_dns/templates/netbox_dns/zonetemplate.html +27 -17
  68. netbox_dns/utilities/ipam_dnssync.py +15 -4
  69. netbox_dns/validators/dns_name.py +11 -4
  70. netbox_dns/validators/dns_value.py +9 -4
  71. netbox_dns/validators/rfc2317.py +6 -3
  72. netbox_dns/views/nameserver.py +4 -2
  73. netbox_dns/views/record_template.py +4 -3
  74. netbox_dns/views/registrar.py +3 -1
  75. netbox_dns/views/registration_contact.py +2 -1
  76. netbox_dns/views/view.py +2 -1
  77. netbox_dns/views/zone.py +6 -4
  78. netbox_dns/views/zone_template.py +8 -7
  79. {netbox_plugin_dns-1.1.2.dist-info → netbox_plugin_dns-1.1.3.dist-info}/METADATA +1 -1
  80. netbox_plugin_dns-1.1.3.dist-info/RECORD +150 -0
  81. netbox_plugin_dns-1.1.2.dist-info/RECORD +0 -148
  82. {netbox_plugin_dns-1.1.2.dist-info → netbox_plugin_dns-1.1.3.dist-info}/LICENSE +0 -0
  83. {netbox_plugin_dns-1.1.2.dist-info → netbox_plugin_dns-1.1.3.dist-info}/WHEEL +0 -0
  84. {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 name",
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
- f"Error while processing record template {self}: {exc.messages[0]}"
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():
@@ -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": "Please select a different view as default view to change this setting!"
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 Serial field",
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="RCF2317 Prefix",
231
- help_text="RFC2317 IPv4 prefix prefix with a length of at least 25 bits",
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(f"No nameservers are configured for zone {self}")
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
- f"Nameserver {_nameserver.name} does not have an active address record in zone {ns_zone}"
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
- {"soa_serial": f"soa_serial must not decrease for zone {self.name}."}
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
- f"Default soa_mname instance {default_soa_mname} does not exist"
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": f"soa_serial is not defined and soa_serial_auto is disabled for zone {self.name}."
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": f"Enabling soa_serial_auto would decrease soa_serial for zone {self.name}."
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": "A regular reverse zone can not be used as an RFC2317 zone."
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": f"Parent zone not found in view {self.view}."
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": f"RFC2317 prefix overlaps with zone {overlapping_zones.first()}."
747
+ "rfc2317_prefix": _(
748
+ "RFC2317 prefix overlaps with zone {zone}."
749
+ ).format(zone=overlapping_zones.first())
728
750
  }
729
751
  )
730
752