netbox-plugin-dns 0.22.8__py3-none-any.whl → 1.0.0__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 (115) hide show
  1. netbox_dns/__init__.py +4 -15
  2. netbox_dns/api/nested_serializers.py +4 -60
  3. netbox_dns/api/serializers.py +8 -314
  4. netbox_dns/api/serializers_/__init__.py +0 -0
  5. netbox_dns/api/serializers_/contact.py +37 -0
  6. netbox_dns/api/serializers_/nameserver.py +39 -0
  7. netbox_dns/api/serializers_/record.py +90 -0
  8. netbox_dns/api/serializers_/registrar.py +31 -0
  9. netbox_dns/api/serializers_/view.py +34 -0
  10. netbox_dns/api/serializers_/zone.py +159 -0
  11. netbox_dns/api/views.py +13 -13
  12. netbox_dns/fields/network.py +21 -22
  13. netbox_dns/fields/rfc2317.py +3 -3
  14. netbox_dns/{filters → filtersets}/contact.py +2 -1
  15. netbox_dns/filtersets/nameserver.py +37 -0
  16. netbox_dns/{filters → filtersets}/record.py +51 -6
  17. netbox_dns/{filters → filtersets}/registrar.py +2 -1
  18. netbox_dns/{filters → filtersets}/view.py +2 -2
  19. netbox_dns/filtersets/zone.py +205 -0
  20. netbox_dns/forms/contact.py +61 -33
  21. netbox_dns/forms/nameserver.py +21 -8
  22. netbox_dns/forms/record.py +65 -38
  23. netbox_dns/forms/registrar.py +45 -15
  24. netbox_dns/forms/view.py +23 -9
  25. netbox_dns/forms/zone.py +182 -188
  26. netbox_dns/graphql/__init__.py +17 -27
  27. netbox_dns/graphql/filters.py +49 -0
  28. netbox_dns/graphql/schema.py +66 -7
  29. netbox_dns/graphql/types.py +143 -0
  30. netbox_dns/management/commands/cleanup_database.py +0 -4
  31. netbox_dns/management/commands/cleanup_rrset_ttl.py +3 -5
  32. netbox_dns/management/commands/setup_coupling.py +15 -15
  33. netbox_dns/management/commands/update_soa.py +1 -1
  34. netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -27
  35. netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +558 -0
  36. netbox_dns/migrations/{0013_add_nameserver_zone_record_description.py → 0002_contact_description_registrar_description.py} +4 -9
  37. netbox_dns/migrations/0003_default_view.py +15 -0
  38. netbox_dns/migrations/0004_create_and_assign_default_view.py +26 -0
  39. netbox_dns/migrations/0005_alter_zone_view_not_null.py +18 -0
  40. netbox_dns/migrations/0020_netbox_3_4.py +1 -1
  41. netbox_dns/models/contact.py +6 -1
  42. netbox_dns/models/nameserver.py +5 -1
  43. netbox_dns/models/record.py +32 -34
  44. netbox_dns/models/registrar.py +5 -1
  45. netbox_dns/models/view.py +54 -1
  46. netbox_dns/models/zone.py +68 -54
  47. netbox_dns/navigation.py +1 -15
  48. netbox_dns/signals/ipam_coupling.py +3 -9
  49. netbox_dns/tables/contact.py +1 -0
  50. netbox_dns/tables/nameserver.py +0 -2
  51. netbox_dns/tables/registrar.py +1 -0
  52. netbox_dns/tables/view.py +9 -2
  53. netbox_dns/template_content.py +4 -8
  54. netbox_dns/templates/netbox_dns/contact.html +60 -56
  55. netbox_dns/templates/netbox_dns/nameserver.html +27 -27
  56. netbox_dns/templates/netbox_dns/record.html +92 -94
  57. netbox_dns/templates/netbox_dns/registrar.html +38 -36
  58. netbox_dns/templates/netbox_dns/view.html +25 -21
  59. netbox_dns/templates/netbox_dns/zone/base.html +5 -3
  60. netbox_dns/templates/netbox_dns/zone/child.html +3 -3
  61. netbox_dns/templates/netbox_dns/zone/managed_record.html +1 -1
  62. netbox_dns/templates/netbox_dns/zone/record.html +3 -3
  63. netbox_dns/templates/netbox_dns/zone/registration.html +26 -27
  64. netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +1 -1
  65. netbox_dns/templates/netbox_dns/zone.html +148 -149
  66. netbox_dns/urls/__init__.py +17 -0
  67. netbox_dns/urls/contact.py +51 -0
  68. netbox_dns/urls/nameserver.py +69 -0
  69. netbox_dns/urls/record.py +41 -0
  70. netbox_dns/urls/registrar.py +63 -0
  71. netbox_dns/urls/view.py +39 -0
  72. netbox_dns/urls/zone.py +57 -0
  73. netbox_dns/utilities/__init__.py +1 -6
  74. netbox_dns/utilities/ipam_coupling.py +2 -7
  75. netbox_dns/validators/dns_name.py +4 -9
  76. netbox_dns/validators/rfc2317.py +2 -2
  77. netbox_dns/views/contact.py +4 -4
  78. netbox_dns/views/nameserver.py +5 -5
  79. netbox_dns/views/record.py +14 -29
  80. netbox_dns/views/registrar.py +4 -4
  81. netbox_dns/views/view.py +4 -4
  82. netbox_dns/views/zone.py +7 -8
  83. {netbox_plugin_dns-0.22.8.dist-info → netbox_plugin_dns-1.0.0.dist-info}/METADATA +27 -13
  84. netbox_plugin_dns-1.0.0.dist-info/RECORD +112 -0
  85. netbox_dns/filters/nameserver.py +0 -18
  86. netbox_dns/filters/zone.py +0 -112
  87. netbox_dns/graphql/contact.py +0 -19
  88. netbox_dns/graphql/nameserver.py +0 -19
  89. netbox_dns/graphql/record.py +0 -19
  90. netbox_dns/graphql/registrar.py +0 -19
  91. netbox_dns/graphql/view.py +0 -19
  92. netbox_dns/graphql/zone.py +0 -19
  93. netbox_dns/migrations/0001_initial.py +0 -115
  94. netbox_dns/migrations/0002_zone_default_ttl.py +0 -18
  95. netbox_dns/migrations/0003_soa_managed_records.py +0 -112
  96. netbox_dns/migrations/0004_create_ptr_for_a_aaaa_records.py +0 -80
  97. netbox_dns/migrations/0005_update_ns_records.py +0 -41
  98. netbox_dns/migrations/0006_zone_soa_serial_auto.py +0 -29
  99. netbox_dns/migrations/0007_alter_zone_soa_serial_auto.py +0 -17
  100. netbox_dns/migrations/0008_zone_status_names.py +0 -21
  101. netbox_dns/migrations/0009_netbox32.py +0 -71
  102. netbox_dns/migrations/0010_update_soa_records.py +0 -58
  103. netbox_dns/migrations/0011_add_view_model.py +0 -70
  104. netbox_dns/migrations/0012_adjust_zone_and_record.py +0 -17
  105. netbox_dns/migrations/0014_add_view_description.py +0 -16
  106. netbox_dns/migrations/0015_add_record_status.py +0 -17
  107. netbox_dns/migrations/0016_cleanup_ptr_records.py +0 -38
  108. netbox_dns/migrations/0017_alter_record_ttl.py +0 -17
  109. netbox_dns/migrations/0018_zone_arpa_network.py +0 -51
  110. netbox_dns/migrations/0019_update_ns_ttl.py +0 -19
  111. netbox_dns/urls.py +0 -297
  112. netbox_plugin_dns-0.22.8.dist-info/RECORD +0 -117
  113. /netbox_dns/{filters → filtersets}/__init__.py +0 -0
  114. {netbox_plugin_dns-0.22.8.dist-info → netbox_plugin_dns-1.0.0.dist-info}/LICENSE +0 -0
  115. {netbox_plugin_dns-0.22.8.dist-info → netbox_plugin_dns-1.0.0.dist-info}/WHEEL +0 -0
@@ -7,6 +7,7 @@ from netbox.forms import (
7
7
  NetBoxModelForm,
8
8
  )
9
9
  from utilities.forms.fields import TagFilterField
10
+ from utilities.forms.rendering import FieldSet
10
11
 
11
12
  from netbox_dns.models import Registrar
12
13
 
@@ -14,9 +15,24 @@ from netbox_dns.models import Registrar
14
15
  class RegistrarForm(NetBoxModelForm):
15
16
  class Meta:
16
17
  model = Registrar
18
+ fieldsets = (
19
+ FieldSet(
20
+ "name",
21
+ "iana_id",
22
+ "description",
23
+ "address",
24
+ "referral_url",
25
+ "whois_server",
26
+ "abuse_email",
27
+ "abuse_phone",
28
+ name="Registrar",
29
+ ),
30
+ FieldSet("tags", name="Tags"),
31
+ )
17
32
  fields = (
18
33
  "name",
19
34
  "iana_id",
35
+ "description",
20
36
  "address",
21
37
  "referral_url",
22
38
  "whois_server",
@@ -29,10 +45,15 @@ class RegistrarForm(NetBoxModelForm):
29
45
  class RegistrarFilterForm(NetBoxModelFilterSetForm):
30
46
  model = Registrar
31
47
  fieldsets = (
32
- (None, ("q", "name", "iana_id", "tags")),
33
- (
34
- "Contact",
35
- ("address", "referral_url", "whois_server", "abuse_email", "abuse_phone"),
48
+ FieldSet("q", "filter_id", "tag"),
49
+ FieldSet("name", "iana_id", "description", name="Attributes"),
50
+ FieldSet(
51
+ "address",
52
+ "referral_url",
53
+ "whois_server",
54
+ "abuse_email",
55
+ "abuse_phone",
56
+ name="Contact",
36
57
  ),
37
58
  )
38
59
 
@@ -42,6 +63,9 @@ class RegistrarFilterForm(NetBoxModelFilterSetForm):
42
63
  address = forms.CharField(
43
64
  required=False,
44
65
  )
66
+ description = forms.CharField(
67
+ required=False,
68
+ )
45
69
  iana_id = forms.IntegerField(
46
70
  required=False,
47
71
  label="IANA ID",
@@ -62,7 +86,7 @@ class RegistrarFilterForm(NetBoxModelFilterSetForm):
62
86
  required=False,
63
87
  label="Abuse Phone",
64
88
  )
65
- tags = TagFilterField(Registrar)
89
+ tag = TagFilterField(Registrar)
66
90
 
67
91
 
68
92
  class RegistrarImportForm(NetBoxModelImportForm):
@@ -71,6 +95,7 @@ class RegistrarImportForm(NetBoxModelImportForm):
71
95
  fields = (
72
96
  "name",
73
97
  "iana_id",
98
+ "description",
74
99
  "address",
75
100
  "referral_url",
76
101
  "whois_server",
@@ -87,8 +112,13 @@ class RegistrarBulkEditForm(NetBoxModelBulkEditForm):
87
112
  required=False,
88
113
  label="IANA ID",
89
114
  )
115
+ description = forms.CharField(
116
+ required=False,
117
+ label="Description",
118
+ )
90
119
  address = forms.CharField(
91
120
  required=False,
121
+ label="Address",
92
122
  )
93
123
  referral_url = forms.CharField(
94
124
  required=False,
@@ -108,21 +138,21 @@ class RegistrarBulkEditForm(NetBoxModelBulkEditForm):
108
138
  )
109
139
 
110
140
  fieldsets = (
111
- (
112
- None,
113
- (
114
- "iana_id",
115
- "address",
116
- "referral_url",
117
- "whois_server",
118
- "abuse_email",
119
- "abuse_phone",
120
- ),
141
+ FieldSet(
142
+ "iana_id",
143
+ "description",
144
+ "address",
145
+ "referral_url",
146
+ "whois_server",
147
+ "abuse_email",
148
+ "abuse_phone",
149
+ name="Attributes",
121
150
  ),
122
151
  )
123
152
 
124
153
  nullable_fields = (
125
154
  "iana_id",
155
+ "description",
126
156
  "address",
127
157
  "referral_url",
128
158
  "whois_server",
netbox_dns/forms/view.py CHANGED
@@ -11,6 +11,7 @@ from utilities.forms.fields import (
11
11
  CSVModelChoiceField,
12
12
  DynamicModelChoiceField,
13
13
  )
14
+ from utilities.forms.rendering import FieldSet
14
15
  from tenancy.models import Tenant
15
16
  from tenancy.forms import TenancyForm, TenancyFilterForm
16
17
 
@@ -19,26 +20,31 @@ from netbox_dns.models import View
19
20
 
20
21
  class ViewForm(TenancyForm, NetBoxModelForm):
21
22
  fieldsets = (
22
- ("View", ("name", "description", "tags")),
23
- ("Tenancy", ("tenant_group", "tenant")),
23
+ FieldSet("name", "default_view", "description", "tags", name="View"),
24
+ FieldSet("tenant_group", "tenant", name="Tenancy"),
24
25
  )
25
26
 
26
27
  class Meta:
27
28
  model = View
28
- fields = ("name", "description", "tags", "tenant")
29
+ fields = ("name", "default_view", "description", "tags", "tenant")
29
30
 
30
31
 
31
32
  class ViewFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
32
33
  model = View
33
34
  fieldsets = (
34
- (None, ("q", "filter_id", "tag")),
35
- ("Attributes", ("name",)),
36
- ("Tenant", ("tenant_group_id", "tenant_id")),
35
+ FieldSet("q", "filter_id", "tag"),
36
+ FieldSet("name", "default_view", "description", name="Attributes"),
37
+ FieldSet("tenant_group_id", "tenant_id", name="Tenancy"),
37
38
  )
38
39
 
39
40
  name = forms.CharField(
40
41
  required=False,
41
- label="Name",
42
+ )
43
+ default_view = forms.NullBooleanField(
44
+ required=False,
45
+ )
46
+ description = forms.CharField(
47
+ required=False,
42
48
  )
43
49
  tag = TagFilterField(View)
44
50
 
@@ -62,5 +68,13 @@ class ViewBulkEditForm(NetBoxModelBulkEditForm):
62
68
  description = forms.CharField(max_length=200, required=False)
63
69
  tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False)
64
70
 
65
- class Meta:
66
- nullable_fields = ("description", "tenant")
71
+ fieldsets = (
72
+ FieldSet(
73
+ "name",
74
+ "description",
75
+ name="Attributes",
76
+ ),
77
+ FieldSet("tenant", name="Tenancy"),
78
+ )
79
+
80
+ nullable_fields = ("description", "tenant")
netbox_dns/forms/zone.py CHANGED
@@ -1,6 +1,5 @@
1
1
  from django import forms
2
2
  from django.conf import settings
3
- from django.core.exceptions import ValidationError
4
3
  from django.core.validators import MinValueValidator, MaxValueValidator
5
4
  from django.urls import reverse_lazy
6
5
 
@@ -19,6 +18,7 @@ from utilities.forms.fields import (
19
18
  DynamicModelChoiceField,
20
19
  )
21
20
  from utilities.forms.widgets import BulkEditNullBooleanSelect, APISelect
21
+ from utilities.forms.rendering import FieldSet
22
22
  from utilities.forms import add_blank_choice
23
23
  from tenancy.models import Tenant
24
24
  from tenancy.forms import TenancyForm, TenancyFilterForm
@@ -55,7 +55,7 @@ class ZoneForm(TenancyForm, NetBoxModelForm):
55
55
  )
56
56
  soa_rname = forms.CharField(
57
57
  required=True,
58
- label="SOA Responsible",
58
+ label="SOA RName",
59
59
  help_text="Mailbox of the zone's administrator",
60
60
  )
61
61
  soa_serial_auto = forms.BooleanField(
@@ -106,67 +106,56 @@ class ZoneForm(TenancyForm, NetBoxModelForm):
106
106
  )
107
107
 
108
108
  fieldsets = (
109
- (
110
- "Zone",
111
- (
112
- "view",
113
- "name",
114
- "status",
115
- "nameservers",
116
- "default_ttl",
117
- "description",
118
- ),
109
+ FieldSet(
110
+ "view",
111
+ "name",
112
+ "status",
113
+ "nameservers",
114
+ "default_ttl",
115
+ "description",
116
+ name="Zone",
119
117
  ),
120
- (
121
- "SOA",
122
- (
123
- "soa_ttl",
124
- "soa_mname",
125
- "soa_rname",
126
- "soa_refresh",
127
- "soa_retry",
128
- "soa_expire",
129
- "soa_minimum",
130
- "soa_serial_auto",
131
- "soa_serial",
132
- ),
118
+ FieldSet(
119
+ "soa_ttl",
120
+ "soa_mname",
121
+ "soa_rname",
122
+ "soa_refresh",
123
+ "soa_retry",
124
+ "soa_expire",
125
+ "soa_minimum",
126
+ "soa_serial_auto",
127
+ "soa_serial",
128
+ name="SOA",
133
129
  ),
134
- (
135
- "RFC2317",
136
- (
137
- "rfc2317_prefix",
138
- "rfc2317_parent_managed",
139
- ),
130
+ FieldSet(
131
+ "rfc2317_prefix",
132
+ "rfc2317_parent_managed",
133
+ name="RFC 2317",
140
134
  ),
141
- (
142
- "Domain Registration",
143
- (
144
- "registrar",
145
- "registry_domain_id",
146
- "registrant",
147
- "admin_c",
148
- "tech_c",
149
- "billing_c",
150
- ),
135
+ FieldSet(
136
+ "registrar",
137
+ "registry_domain_id",
138
+ "registrant",
139
+ "admin_c",
140
+ "tech_c",
141
+ "billing_c",
142
+ name="Domain Registration",
151
143
  ),
152
- ("Tags", ("tags",)),
153
- ("Tenancy", ("tenant_group", "tenant")),
144
+ FieldSet("tags", name="Tags"),
145
+ FieldSet("tenant", name="Tenancy"),
154
146
  )
155
147
 
156
148
  def __init__(self, *args, **kwargs):
157
- """Override the __init__ method in order to provide the initial value for the default fields"""
158
149
  super().__init__(*args, **kwargs)
159
150
 
160
151
  initial_name = self.initial.get("name")
161
152
  if initial_name:
162
153
  self.initial["name"] = name_to_unicode(initial_name)
163
154
 
164
- defaults = settings.PLUGINS_CONFIG.get("netbox_dns")
165
-
166
- def _initialize(initial, setting):
167
- if initial.get(setting, None) in (None, ""):
168
- initial[setting] = defaults.get(f"zone_{setting}", None)
155
+ if self.initial.get("view") is None:
156
+ self.initial["view"] = View.get_default_view()
169
157
 
158
+ defaults = settings.PLUGINS_CONFIG.get("netbox_dns")
170
159
  for setting in (
171
160
  "default_ttl",
172
161
  "soa_ttl",
@@ -177,16 +166,17 @@ class ZoneForm(TenancyForm, NetBoxModelForm):
177
166
  "soa_expire",
178
167
  "soa_minimum",
179
168
  ):
180
- _initialize(self.initial, setting)
169
+ if self.initial.get(setting) in (None, ""):
170
+ self.initial[setting] = defaults.get(f"zone_{setting}")
181
171
 
182
- if self.initial.get("soa_ttl", None) is None:
183
- self.initial["soa_ttl"] = self.initial.get("default_ttl", None)
172
+ if self.initial.get("soa_ttl") is None:
173
+ self.initial["soa_ttl"] = self.initial.get("default_ttl")
184
174
 
185
175
  if self.initial.get("soa_serial_auto"):
186
176
  self.initial["soa_serial"] = None
187
177
 
188
- if self.initial.get("soa_mname", None) in (None, ""):
189
- default_soa_mname = defaults.get("zone_soa_mname", None)
178
+ if self.initial.get("soa_mname") is None:
179
+ default_soa_mname = defaults.get("zone_soa_mname")
190
180
  if default_soa_mname is not None:
191
181
  try:
192
182
  self.initial["soa_mname"] = NameServer.objects.get(
@@ -248,9 +238,32 @@ class ZoneForm(TenancyForm, NetBoxModelForm):
248
238
  class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
249
239
  model = Zone
250
240
  fieldsets = (
251
- (None, ("q", "filter_id", "tag")),
252
- ("Attributes", ("view_id", "status", "name", "nameservers")),
253
- ("Tenant", ("tenant_group_id", "tenant_id")),
241
+ FieldSet("q", "filter_id", "tag"),
242
+ FieldSet(
243
+ "view_id", "status", "name", "nameservers", "description", name="Attributes"
244
+ ),
245
+ FieldSet(
246
+ "soa_mname_id",
247
+ "soa_rname",
248
+ "soa_serial_auto",
249
+ name="SOA",
250
+ ),
251
+ FieldSet(
252
+ "rfc2317_prefix",
253
+ "rfc2317_parent_managed",
254
+ "rfc2317_parent_zone_id",
255
+ name="RFC2317",
256
+ ),
257
+ FieldSet(
258
+ "registrar_id",
259
+ "registry_domain_id",
260
+ "registrant_id",
261
+ "admin_c_id",
262
+ "tech_c_id",
263
+ "billing_c_id",
264
+ name="Registration",
265
+ ),
266
+ FieldSet("tenant_group_id", "tenant_id", name="Tenancy"),
254
267
  )
255
268
 
256
269
  view_id = DynamicModelMultipleChoiceField(
@@ -264,12 +277,69 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
264
277
  )
265
278
  name = forms.CharField(
266
279
  required=False,
267
- label="Name",
268
280
  )
269
281
  nameservers = DynamicModelMultipleChoiceField(
270
282
  queryset=NameServer.objects.all(),
271
283
  required=False,
272
284
  )
285
+ description = forms.CharField(
286
+ required=False,
287
+ )
288
+ soa_mname_id = DynamicModelMultipleChoiceField(
289
+ queryset=NameServer.objects.all(),
290
+ label="MName",
291
+ required=False,
292
+ )
293
+ soa_rname = forms.CharField(
294
+ required=False,
295
+ label="RName",
296
+ )
297
+ soa_serial_auto = forms.NullBooleanField(
298
+ required=False,
299
+ label="Generate Serial",
300
+ )
301
+ rfc2317_prefix = RFC2317NetworkFormField(
302
+ required=False,
303
+ label="Prefix",
304
+ )
305
+ rfc2317_parent_managed = forms.NullBooleanField(
306
+ required=False,
307
+ label="Parent Managed",
308
+ )
309
+ rfc2317_parent_zone_id = DynamicModelMultipleChoiceField(
310
+ queryset=Zone.objects.all(),
311
+ required=False,
312
+ label="Parent Zone",
313
+ )
314
+ registrar_id = DynamicModelMultipleChoiceField(
315
+ queryset=Registrar.objects.all(),
316
+ required=False,
317
+ label="Registrar",
318
+ )
319
+ registry_domain_id = forms.CharField(
320
+ required=False,
321
+ label="Registry Domain ID",
322
+ )
323
+ registrant_id = DynamicModelMultipleChoiceField(
324
+ queryset=Contact.objects.all(),
325
+ required=False,
326
+ label="Registrant",
327
+ )
328
+ admin_c_id = DynamicModelMultipleChoiceField(
329
+ queryset=Contact.objects.all(),
330
+ required=False,
331
+ label="Admin-C",
332
+ )
333
+ tech_c_id = DynamicModelMultipleChoiceField(
334
+ queryset=Contact.objects.all(),
335
+ required=False,
336
+ label="Tech-C",
337
+ )
338
+ billing_c_id = DynamicModelMultipleChoiceField(
339
+ queryset=Contact.objects.all(),
340
+ required=False,
341
+ label="Billing-C",
342
+ )
273
343
  tag = TagFilterField(Zone)
274
344
 
275
345
 
@@ -404,87 +474,6 @@ class ZoneImportForm(NetBoxModelImportForm):
404
474
  help_text="Assigned tenant",
405
475
  )
406
476
 
407
- def _get_default_value(self, field):
408
- _default_values = settings.PLUGINS_CONFIG.get("netbox_dns", {})
409
- if _default_values.get("zone_soa_ttl", None) is None:
410
- _default_values["zone_soa_ttl"] = _default_values.get(
411
- "zone_default_ttl", None
412
- )
413
-
414
- return _default_values.get(f"zone_{field}", None)
415
-
416
- def _clean_field_with_defaults(self, field):
417
- if self.cleaned_data[field]:
418
- value = self.cleaned_data[field]
419
- else:
420
- value = self._get_default_value(field)
421
-
422
- if value is None:
423
- raise ValidationError(f"{field} not set and no default value available")
424
-
425
- return value
426
-
427
- def clean_default_ttl(self):
428
- return self._clean_field_with_defaults("default_ttl")
429
-
430
- def clean_soa_ttl(self):
431
- return self._clean_field_with_defaults("soa_ttl")
432
-
433
- def clean_soa_mname(self):
434
- soa_mname = self._clean_field_with_defaults("soa_mname")
435
- if isinstance(soa_mname, str):
436
- try:
437
- soa_mname = NameServer.objects.get(name=soa_mname)
438
- except NameServer.DoesNotExist:
439
- raise ValidationError(f"Default name server {soa_mname} does not exist")
440
-
441
- return soa_mname
442
-
443
- def clean_soa_rname(self):
444
- return self._clean_field_with_defaults("soa_rname")
445
-
446
- def clean_soa_refresh(self):
447
- return self._clean_field_with_defaults("soa_refresh")
448
-
449
- def clean_soa_retry(self):
450
- return self._clean_field_with_defaults("soa_retry")
451
-
452
- def clean_soa_expire(self):
453
- return self._clean_field_with_defaults("soa_expire")
454
-
455
- def clean_soa_minimum(self):
456
- return self._clean_field_with_defaults("soa_minimum")
457
-
458
- def clean(self, *args, **kwargs):
459
- super().clean(*args, **kwargs)
460
-
461
- soa_serial_auto = self.cleaned_data.get("soa_serial_auto")
462
- soa_serial = self.cleaned_data.get("soa_serial")
463
-
464
- if soa_serial is None:
465
- soa_serial = self._get_default_value("soa_serial")
466
-
467
- if soa_serial_auto is None:
468
- if self._get_default_value("soa_serial_auto") is not None:
469
- soa_serial_auto = self._get_default_value("soa_serial_auto")
470
-
471
- elif soa_serial is not None:
472
- soa_serial_auto = False
473
-
474
- else:
475
- raise ValidationError(
476
- "SOA Serial Auto not set and no default value and SOA Serial available"
477
- )
478
-
479
- if "soa_serial_auto" in self.cleaned_data:
480
- self.cleaned_data["soa_serial_auto"] = soa_serial_auto
481
-
482
- if "soa_serial" in self.cleaned_data:
483
- if soa_serial_auto:
484
- self.cleaned_data["soa_serial"] = None
485
- else:
486
- self.cleaned_data["soa_serial"] = soa_serial
487
-
488
477
  class Meta:
489
478
  model = Zone
490
479
 
@@ -516,6 +505,27 @@ class ZoneImportForm(NetBoxModelImportForm):
516
505
  "tags",
517
506
  )
518
507
 
508
+ def clean_view(self):
509
+ view = self.cleaned_data.get("view")
510
+ if view is None:
511
+ return View.get_default_view()
512
+
513
+ return view
514
+
515
+ def clean_nameservers(self):
516
+ nameservers = self.cleaned_data.get("nameservers")
517
+ zone_defaults = settings.PLUGINS_CONFIG.get("netbox_dns")
518
+
519
+ if (
520
+ self.data.get("nameservers") is None
521
+ and zone_defaults.get("zone_nameservers") is not None
522
+ ):
523
+ nameservers = NameServer.objects.filter(
524
+ name__in=zone_defaults.get("zone_nameservers")
525
+ )
526
+
527
+ return nameservers
528
+
519
529
 
520
530
  class ZoneBulkEditForm(NetBoxModelBulkEditForm):
521
531
  view = DynamicModelChoiceField(
@@ -557,7 +567,7 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
557
567
  )
558
568
  soa_rname = forms.CharField(
559
569
  required=False,
560
- label="SOA Responsible",
570
+ label="SOA RName",
561
571
  )
562
572
  soa_serial_auto = forms.NullBooleanField(
563
573
  required=False,
@@ -656,52 +666,44 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
656
666
  model = Zone
657
667
 
658
668
  fieldsets = (
659
- (
660
- None,
661
- (
662
- "view",
663
- "status",
664
- "nameservers",
665
- "default_ttl",
666
- "description",
667
- "tenant",
668
- ),
669
+ FieldSet(
670
+ "view",
671
+ "status",
672
+ "nameservers",
673
+ "default_ttl",
674
+ "description",
675
+ name="Attributes",
669
676
  ),
670
- (
671
- "SOA",
672
- (
673
- "soa_ttl",
674
- "soa_mname",
675
- "soa_rname",
676
- "soa_serial_auto",
677
- "soa_serial",
678
- "soa_refresh",
679
- "soa_retry",
680
- "soa_expire",
681
- "soa_minimum",
682
- ),
677
+ FieldSet(
678
+ "soa_ttl",
679
+ "soa_mname",
680
+ "soa_rname",
681
+ "soa_refresh",
682
+ "soa_retry",
683
+ "soa_expire",
684
+ "soa_minimum",
685
+ "soa_serial_auto",
686
+ "soa_serial",
687
+ name="SOA",
683
688
  ),
684
- (
685
- "RFC2317",
686
- (
687
- "rfc2317_prefix",
688
- "rfc2317_parent_managed",
689
- ),
689
+ FieldSet(
690
+ "rfc2317_prefix",
691
+ "rfc2317_parent_managed",
692
+ name="RFC 2317",
690
693
  ),
691
- (
692
- "Domain Registration",
693
- (
694
- "registrar",
695
- "registry_domain_id",
696
- "registrant",
697
- "admin_c",
698
- "tech_c",
699
- "billing_c",
700
- ),
694
+ FieldSet(
695
+ "registrar",
696
+ "registry_domain_id",
697
+ "registrant",
698
+ "admin_c",
699
+ "tech_c",
700
+ "billing_c",
701
+ name="Domain Registration",
701
702
  ),
703
+ FieldSet("tenant_group", "tenant", name="Tenancy"),
702
704
  )
705
+
703
706
  nullable_fields = (
704
- "view",
705
707
  "description",
706
708
  "rfc2317_prefix",
707
709
  "registrar",
@@ -711,11 +713,3 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
711
713
  "tech_c",
712
714
  "billing_c",
713
715
  )
714
-
715
- def clean(self):
716
- """
717
- If soa_serial_auto is True, set soa_serial to None.
718
- """
719
- cleaned_data = super().clean()
720
- if cleaned_data.get("soa_serial_auto"):
721
- cleaned_data["soa_serial"] = None