netbox-plugin-dns 1.1.1__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 (88) hide show
  1. netbox_dns/__init__.py +8 -6
  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 +3 -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 +75 -34
  27. netbox_dns/forms/zone.py +167 -120
  28. netbox_dns/forms/zone_template.py +53 -43
  29. netbox_dns/graphql/schema.py +0 -10
  30. netbox_dns/graphql/types.py +1 -0
  31. netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
  32. netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
  33. netbox_dns/management/commands/rebuild_dnssync.py +14 -1
  34. netbox_dns/migrations/0010_view_ip_address_filter.py +18 -0
  35. netbox_dns/mixins/object_modification.py +30 -8
  36. netbox_dns/models/nameserver.py +6 -2
  37. netbox_dns/models/record.py +95 -40
  38. netbox_dns/models/record_template.py +16 -8
  39. netbox_dns/models/registrar.py +11 -7
  40. netbox_dns/models/registration_contact.py +23 -11
  41. netbox_dns/models/view.py +54 -5
  42. netbox_dns/models/zone.py +77 -50
  43. netbox_dns/models/zone_template.py +12 -10
  44. netbox_dns/navigation.py +30 -28
  45. netbox_dns/signals/ipam_dnssync.py +25 -18
  46. netbox_dns/tables/ipam_dnssync.py +2 -1
  47. netbox_dns/tables/nameserver.py +2 -0
  48. netbox_dns/tables/record.py +21 -11
  49. netbox_dns/tables/record_template.py +12 -5
  50. netbox_dns/tables/registrar.py +2 -0
  51. netbox_dns/tables/registration_contact.py +2 -0
  52. netbox_dns/tables/view.py +4 -2
  53. netbox_dns/tables/zone.py +15 -2
  54. netbox_dns/tables/zone_template.py +7 -0
  55. netbox_dns/templates/netbox_dns/nameserver.html +6 -5
  56. netbox_dns/templates/netbox_dns/record/managed.html +2 -1
  57. netbox_dns/templates/netbox_dns/record/related.html +26 -14
  58. netbox_dns/templates/netbox_dns/record.html +39 -20
  59. netbox_dns/templates/netbox_dns/recordtemplate.html +27 -15
  60. netbox_dns/templates/netbox_dns/registrar.html +11 -10
  61. netbox_dns/templates/netbox_dns/registrationcontact.html +16 -15
  62. netbox_dns/templates/netbox_dns/view/button.html +2 -1
  63. netbox_dns/templates/netbox_dns/view/prefix.html +7 -4
  64. netbox_dns/templates/netbox_dns/view/related.html +26 -10
  65. netbox_dns/templates/netbox_dns/view.html +22 -9
  66. netbox_dns/templates/netbox_dns/zone/base.html +2 -1
  67. netbox_dns/templates/netbox_dns/zone/child.html +3 -2
  68. netbox_dns/templates/netbox_dns/zone/record.html +3 -2
  69. netbox_dns/templates/netbox_dns/zone/registration.html +8 -7
  70. netbox_dns/templates/netbox_dns/zone.html +28 -30
  71. netbox_dns/templates/netbox_dns/zonetemplate.html +27 -17
  72. netbox_dns/utilities/ipam_dnssync.py +71 -28
  73. netbox_dns/validators/dns_name.py +11 -4
  74. netbox_dns/validators/dns_value.py +9 -4
  75. netbox_dns/validators/rfc2317.py +6 -3
  76. netbox_dns/views/nameserver.py +4 -2
  77. netbox_dns/views/record_template.py +4 -3
  78. netbox_dns/views/registrar.py +3 -1
  79. netbox_dns/views/registration_contact.py +2 -1
  80. netbox_dns/views/view.py +2 -1
  81. netbox_dns/views/zone.py +6 -4
  82. netbox_dns/views/zone_template.py +8 -7
  83. {netbox_plugin_dns-1.1.1.dist-info → netbox_plugin_dns-1.1.3.dist-info}/METADATA +1 -1
  84. netbox_plugin_dns-1.1.3.dist-info/RECORD +150 -0
  85. {netbox_plugin_dns-1.1.1.dist-info → netbox_plugin_dns-1.1.3.dist-info}/WHEEL +1 -1
  86. netbox_plugin_dns-1.1.1.dist-info/RECORD +0 -147
  87. {netbox_plugin_dns-1.1.1.dist-info → netbox_plugin_dns-1.1.3.dist-info}/LICENSE +0 -0
  88. {netbox_plugin_dns-1.1.1.dist-info → netbox_plugin_dns-1.1.3.dist-info}/top_level.txt +0 -0
netbox_dns/forms/view.py CHANGED
@@ -1,7 +1,9 @@
1
1
  from django import forms
2
2
  from django.conf import settings
3
- from django.core.exceptions import ValidationError
3
+ from django.core.exceptions import ValidationError, FieldError
4
4
  from django.db.models import Q, Count
5
+ from django.utils.translation import gettext_lazy as _
6
+ from django.utils.translation import pgettext_lazy as _p
5
7
 
6
8
  from netbox.forms import (
7
9
  NetBoxModelBulkEditForm,
@@ -18,9 +20,10 @@ from utilities.forms.fields import (
18
20
  )
19
21
  from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES
20
22
  from utilities.forms.rendering import FieldSet
21
- from tenancy.models import Tenant
23
+ from utilities.forms.fields import JSONField
24
+ from tenancy.models import Tenant, TenantGroup
22
25
  from tenancy.forms import TenancyForm, TenancyFilterForm
23
- from ipam.models import Prefix
26
+ from ipam.models import Prefix, IPAddress
24
27
  from netbox.context import current_request
25
28
 
26
29
  from netbox_dns.models import View
@@ -29,6 +32,7 @@ from netbox_dns.utilities import (
29
32
  check_dns_records,
30
33
  get_ip_addresses_by_prefix,
31
34
  get_views_by_prefix,
35
+ get_query_from_filter,
32
36
  )
33
37
 
34
38
 
@@ -45,7 +49,7 @@ class ViewPrefixUpdateMixin:
45
49
  def clean(self, *args, **kwargs):
46
50
  super().clean(*args, **kwargs)
47
51
 
48
- if self.instance.pk is None or "prefixes" not in self.changed_data:
52
+ if self.instance._state.adding or "prefixes" not in self.changed_data:
49
53
  return
50
54
 
51
55
  prefixes = self.cleaned_data.get("prefixes")
@@ -97,35 +101,36 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
97
101
 
98
102
  if settings.PLUGINS_CONFIG["netbox_dns"].get("dnssync_disabled"):
99
103
  del self.fields["prefixes"]
104
+ del self.fields["ip_address_filter"]
100
105
 
101
106
  if request := current_request.get():
102
107
  if not request.user.has_perm("ipam.view_prefix"):
103
108
  self._saved_prefixes = self.initial["prefixes"]
104
109
  self.initial["prefixes"] = []
105
110
  self.fields["prefixes"].disabled = True
106
- self.fields["prefixes"].widget.attrs[
107
- "placeholder"
108
- ] = "You do not have permission to modify assigned prefixes"
109
-
110
- def clean_prefixes(self):
111
- if hasattr(self, "_saved_prefixes"):
112
- return self._saved_prefixes
113
-
114
- return self.cleaned_data["prefixes"]
111
+ self.fields["prefixes"].widget.attrs["placeholder"] = _(
112
+ "You do not have permission to modify assigned prefixes"
113
+ )
115
114
 
116
115
  prefixes = PrefixDynamicModelMultipleChoiceField(
117
116
  queryset=Prefix.objects.all(),
118
117
  required=False,
119
- label="IPAM Prefixes",
120
118
  context={
121
119
  "depth": None,
122
120
  },
121
+ label=_("IPAM Prefixes"),
122
+ )
123
+ ip_address_filter = JSONField(
124
+ required=False,
125
+ help_text=_("Specify criteria for address record creation in JSON form"),
126
+ label=_("IP Address Filter"),
123
127
  )
124
128
 
125
129
  fieldsets = (
126
- FieldSet("name", "default_view", "description", "tags", name="View"),
127
- FieldSet("prefixes"),
128
- FieldSet("tenant_group", "tenant", name="Tenancy"),
130
+ FieldSet("name", "default_view", "description", name=_p("DNS", "View")),
131
+ FieldSet("prefixes", "ip_address_filter"),
132
+ FieldSet("tenant_group", "tenant", name=_("Tenancy")),
133
+ FieldSet("tags", name=_("Tags")),
129
134
  )
130
135
 
131
136
  class Meta:
@@ -134,11 +139,32 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
134
139
  "name",
135
140
  "default_view",
136
141
  "description",
137
- "tags",
138
- "tenant",
139
142
  "prefixes",
143
+ "ip_address_filter",
144
+ "tenant_group",
145
+ "tenant",
146
+ "tags",
140
147
  )
141
148
 
149
+ def clean_prefixes(self):
150
+ if hasattr(self, "_saved_prefixes"):
151
+ return self._saved_prefixes
152
+
153
+ return self.cleaned_data["prefixes"]
154
+
155
+ def clean_ip_address_filter(self):
156
+ ip_address_filter = self.cleaned_data.get("ip_address_filter")
157
+
158
+ try:
159
+ IPAddress.objects.filter(get_query_from_filter(ip_address_filter)).exists()
160
+ except (FieldError, ValueError) as exc:
161
+ self.add_error(
162
+ "ip_address_filter",
163
+ _("Invalid filter for IPAddress: {error}").format(error=exc),
164
+ )
165
+
166
+ return ip_address_filter
167
+
142
168
 
143
169
  class ViewFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
144
170
  def __init__(self, *args, **kwargs):
@@ -150,9 +176,9 @@ class ViewFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
150
176
  model = View
151
177
  fieldsets = (
152
178
  FieldSet("q", "filter_id", "tag"),
153
- FieldSet("name", "default_view", "description", name="Attributes"),
179
+ FieldSet("name", "default_view", "description", name=_("Attributes")),
154
180
  FieldSet("prefix_id"),
155
- FieldSet("tenant_group_id", "tenant_id", name="Tenancy"),
181
+ FieldSet("tenant_group_id", "tenant_id", name=_("Tenancy")),
156
182
  )
157
183
 
158
184
  name = forms.CharField(
@@ -168,10 +194,10 @@ class ViewFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
168
194
  prefix_id = PrefixDynamicModelMultipleChoiceField(
169
195
  queryset=Prefix.objects.all(),
170
196
  required=False,
171
- label="Prefix",
172
197
  context={
173
198
  "depth": None,
174
199
  },
200
+ label=_("Prefix"),
175
201
  )
176
202
  tag = TagFilterField(View)
177
203
 
@@ -187,13 +213,14 @@ class ViewImportForm(ViewPrefixUpdateMixin, NetBoxModelImportForm):
187
213
  queryset=Prefix.objects.all(),
188
214
  to_field_name="id",
189
215
  required=False,
190
- help_text="Prefix IDs assigned to the view",
216
+ help_text=_("Prefix IDs assigned to the view"),
217
+ label=_("Prefixes"),
191
218
  )
192
219
  tenant = CSVModelChoiceField(
193
220
  queryset=Tenant.objects.all(),
194
221
  to_field_name="name",
195
222
  required=False,
196
- help_text="Assigned tenant",
223
+ label=_("Tenant"),
197
224
  )
198
225
 
199
226
  class Meta:
@@ -204,16 +231,28 @@ class ViewImportForm(ViewPrefixUpdateMixin, NetBoxModelImportForm):
204
231
  class ViewBulkEditForm(NetBoxModelBulkEditForm):
205
232
  model = View
206
233
 
207
- description = forms.CharField(max_length=200, required=False)
208
- tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False)
234
+ description = forms.CharField(
235
+ max_length=200,
236
+ required=False,
237
+ label=_("Description"),
238
+ )
239
+ tenant_group = DynamicModelChoiceField(
240
+ queryset=TenantGroup.objects.all(),
241
+ required=False,
242
+ label=_("Tenant Group"),
243
+ )
244
+ tenant = DynamicModelChoiceField(
245
+ queryset=Tenant.objects.all(),
246
+ required=False,
247
+ label=_("Tenant"),
248
+ )
209
249
 
210
250
  fieldsets = (
211
251
  FieldSet(
212
- "name",
213
252
  "description",
214
- name="Attributes",
253
+ name=_("Attributes"),
215
254
  ),
216
- FieldSet("tenant", name="Tenancy"),
255
+ FieldSet("tenant_group", "tenant", name=_("Tenancy")),
217
256
  )
218
257
 
219
258
  nullable_fields = ("description", "tenant")
@@ -223,8 +262,10 @@ class ViewPrefixEditForm(forms.ModelForm):
223
262
  views = DynamicModelMultipleChoiceField(
224
263
  queryset=View.objects.all(),
225
264
  required=False,
226
- label="Assigned DNS Views",
227
- help_text="Explicitly assigning DNS views overrides all inherited views for this prefix",
265
+ help_text=_(
266
+ "Explicitly assigning DNS views overrides all inherited views for this prefix"
267
+ ),
268
+ label=_("Assigned DNS Views"),
228
269
  )
229
270
 
230
271
  class Meta:
@@ -242,9 +283,9 @@ class ViewPrefixEditForm(forms.ModelForm):
242
283
  self._permission_denied = True
243
284
  self.initial["views"] = []
244
285
  self.fields["views"].disabled = True
245
- self.fields["views"].widget.attrs[
246
- "placeholder"
247
- ] = "You do not have permission to modify assigned views"
286
+ self.fields["views"].widget.attrs["placeholder"] = _(
287
+ "You do not have permission to modify assigned views"
288
+ )
248
289
 
249
290
  def clean(self, *args, **kwargs):
250
291
  if self._permission_denied: