netbox-plugin-dns 1.2.6__py3-none-any.whl → 1.2.7__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 (76) hide show
  1. netbox_dns/__init__.py +16 -8
  2. netbox_dns/api/field_serializers.py +25 -0
  3. netbox_dns/api/nested_serializers.py +19 -1
  4. netbox_dns/api/serializers.py +3 -0
  5. netbox_dns/api/serializers_/dnssec_key_template.py +59 -0
  6. netbox_dns/api/serializers_/dnssec_policy.py +113 -0
  7. netbox_dns/api/serializers_/record.py +2 -0
  8. netbox_dns/api/serializers_/record_template.py +2 -0
  9. netbox_dns/api/serializers_/zone.py +20 -1
  10. netbox_dns/api/serializers_/zone_template.py +13 -4
  11. netbox_dns/api/urls.py +4 -0
  12. netbox_dns/api/views.py +18 -0
  13. netbox_dns/choices/__init__.py +2 -0
  14. netbox_dns/choices/dnssec_key_template.py +63 -0
  15. netbox_dns/choices/dnssec_policy.py +40 -0
  16. netbox_dns/choices/record.py +2 -25
  17. netbox_dns/choices/utilities.py +26 -0
  18. netbox_dns/choices/zone.py +96 -1
  19. netbox_dns/fields/__init__.py +1 -0
  20. netbox_dns/fields/choice_array.py +33 -0
  21. netbox_dns/fields/timeperiod.py +15 -13
  22. netbox_dns/filtersets/__init__.py +3 -0
  23. netbox_dns/filtersets/dnssec_key_template.py +51 -0
  24. netbox_dns/filtersets/dnssec_policy.py +97 -0
  25. netbox_dns/filtersets/zone.py +30 -6
  26. netbox_dns/filtersets/zone_template.py +13 -2
  27. netbox_dns/forms/__init__.py +2 -0
  28. netbox_dns/forms/dnssec_key_template.py +189 -0
  29. netbox_dns/forms/dnssec_policy.py +593 -0
  30. netbox_dns/forms/nameserver.py +2 -0
  31. netbox_dns/forms/record_template.py +1 -0
  32. netbox_dns/forms/zone.py +120 -9
  33. netbox_dns/forms/zone_template.py +38 -0
  34. netbox_dns/graphql/__init__.py +7 -3
  35. netbox_dns/graphql/filters.py +16 -0
  36. netbox_dns/graphql/schema.py +20 -0
  37. netbox_dns/graphql/types.py +67 -3
  38. netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
  39. netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
  40. netbox_dns/migrations/0015_dnssec.py +168 -0
  41. netbox_dns/migrations/0016_dnssec_policy_status.py +18 -0
  42. netbox_dns/migrations/0017_dnssec_policy_zone_zone_template.py +41 -0
  43. netbox_dns/migrations/0018_zone_domain_status_zone_expiration_date.py +23 -0
  44. netbox_dns/models/__init__.py +2 -0
  45. netbox_dns/models/dnssec_key_template.py +114 -0
  46. netbox_dns/models/dnssec_policy.py +203 -0
  47. netbox_dns/models/record.py +1 -1
  48. netbox_dns/models/zone.py +74 -19
  49. netbox_dns/models/zone_template.py +17 -7
  50. netbox_dns/navigation.py +49 -0
  51. netbox_dns/signals/dnssec.py +32 -0
  52. netbox_dns/tables/__init__.py +2 -0
  53. netbox_dns/tables/dnssec_key_template.py +48 -0
  54. netbox_dns/tables/dnssec_policy.py +131 -0
  55. netbox_dns/tables/zone.py +23 -2
  56. netbox_dns/tables/zone_template.py +4 -0
  57. netbox_dns/template_content.py +2 -1
  58. netbox_dns/templates/netbox_dns/dnsseckeytemplate.html +70 -0
  59. netbox_dns/templates/netbox_dns/dnssecpolicy.html +155 -0
  60. netbox_dns/templates/netbox_dns/zone/registration.html +19 -0
  61. netbox_dns/templates/netbox_dns/zone.html +16 -0
  62. netbox_dns/templates/netbox_dns/zonetemplate/child.html +46 -0
  63. netbox_dns/templates/netbox_dns/zonetemplate.html +12 -0
  64. netbox_dns/urls.py +23 -0
  65. netbox_dns/utilities/conversions.py +13 -0
  66. netbox_dns/validators/__init__.py +1 -0
  67. netbox_dns/validators/dnssec.py +148 -0
  68. netbox_dns/views/__init__.py +2 -0
  69. netbox_dns/views/dnssec_key_template.py +87 -0
  70. netbox_dns/views/dnssec_policy.py +155 -0
  71. netbox_dns/views/zone.py +11 -1
  72. {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7.dist-info}/METADATA +3 -2
  73. {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7.dist-info}/RECORD +76 -50
  74. {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7.dist-info}/WHEEL +1 -1
  75. {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7.dist-info/licenses}/LICENSE +0 -0
  76. {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,593 @@
1
+ from packaging.version import Version
2
+
3
+ from django import forms
4
+ from django.utils.translation import gettext_lazy as _
5
+
6
+ from netbox.forms import (
7
+ NetBoxModelBulkEditForm,
8
+ NetBoxModelFilterSetForm,
9
+ NetBoxModelImportForm,
10
+ NetBoxModelForm,
11
+ )
12
+ from utilities.forms.fields import (
13
+ TagFilterField,
14
+ CSVModelChoiceField,
15
+ CSVChoiceField,
16
+ DynamicModelChoiceField,
17
+ DynamicModelMultipleChoiceField,
18
+ )
19
+ from utilities.release import load_release_data
20
+ from utilities.forms.rendering import FieldSet
21
+ from utilities.forms.widgets import BulkEditNullBooleanSelect
22
+ from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, add_blank_choice
23
+ from tenancy.models import Tenant, TenantGroup
24
+ from tenancy.forms import TenancyForm, TenancyFilterForm
25
+
26
+ from netbox_dns.models import DNSSECPolicy, DNSSECKeyTemplate, Zone, ZoneTemplate
27
+ from netbox_dns.choices import DNSSECPolicyDigestChoices, DNSSECPolicyStatusChoices
28
+ from netbox_dns.fields import TimePeriodField
29
+
30
+
31
+ __all__ = (
32
+ "DNSSECPolicyForm",
33
+ "DNSSECPolicyFilterForm",
34
+ "DNSSECPolicyImportForm",
35
+ "DNSSECPolicyBulkEditForm",
36
+ )
37
+
38
+ QUICK_ADD = Version(load_release_data().version) >= Version("4.2.5")
39
+
40
+
41
+ class DNSSECPolicyForm(TenancyForm, NetBoxModelForm):
42
+ fieldsets = (
43
+ FieldSet(
44
+ "name",
45
+ "description",
46
+ "status",
47
+ "key_templates",
48
+ name=_("Attributes"),
49
+ ),
50
+ FieldSet(
51
+ "dnskey_ttl",
52
+ "purge_keys",
53
+ "publish_safety",
54
+ "retire_safety",
55
+ "signatures_jitter",
56
+ "signatures_refresh",
57
+ "signatures_validity",
58
+ "signatures_validity_dnskey",
59
+ "max_zone_ttl",
60
+ "zone_propagation_delay",
61
+ name=_("Timing"),
62
+ ),
63
+ FieldSet(
64
+ "create_cdnskey",
65
+ "cds_digest_types",
66
+ "parent_ds_ttl",
67
+ "parent_propagation_delay",
68
+ name=_("Parent Delegation"),
69
+ ),
70
+ FieldSet(
71
+ "use_nsec3",
72
+ "nsec3_iterations",
73
+ "nsec3_opt_out",
74
+ "nsec3_salt_size",
75
+ name=_("Proof of Non-Existence"),
76
+ ),
77
+ FieldSet("tenant_group", "tenant", name=_("Tenancy")),
78
+ FieldSet("tags", name=_("Tags")),
79
+ )
80
+
81
+ key_templates = DynamicModelMultipleChoiceField(
82
+ queryset=DNSSECKeyTemplate.objects.all(),
83
+ required=False,
84
+ label=_("Key Templates"),
85
+ help_text=_("Select CSK or KSK/ZSK templates for signing"),
86
+ quick_add=QUICK_ADD,
87
+ )
88
+
89
+ class Meta:
90
+ model = DNSSECPolicy
91
+ fields = (
92
+ "name",
93
+ "description",
94
+ "status",
95
+ "key_templates",
96
+ "dnskey_ttl",
97
+ "purge_keys",
98
+ "publish_safety",
99
+ "retire_safety",
100
+ "signatures_jitter",
101
+ "signatures_refresh",
102
+ "signatures_validity",
103
+ "signatures_validity_dnskey",
104
+ "max_zone_ttl",
105
+ "zone_propagation_delay",
106
+ "create_cdnskey",
107
+ "cds_digest_types",
108
+ "parent_ds_ttl",
109
+ "parent_propagation_delay",
110
+ "use_nsec3",
111
+ "nsec3_iterations",
112
+ "nsec3_opt_out",
113
+ "nsec3_salt_size",
114
+ "tenant_group",
115
+ "tenant",
116
+ "tags",
117
+ )
118
+
119
+ dnskey_ttl = TimePeriodField(
120
+ required=False,
121
+ label=_("DNSKEY TTL"),
122
+ placeholder=DNSSECPolicy.get_fallback_setting("dnskey_ttl"),
123
+ )
124
+ purge_keys = TimePeriodField(
125
+ required=False,
126
+ label=_("Purge Keys"),
127
+ placeholder=DNSSECPolicy.get_fallback_setting("purge_keys"),
128
+ )
129
+ publish_safety = TimePeriodField(
130
+ required=False,
131
+ label=_("Publish Safety"),
132
+ placeholder=DNSSECPolicy.get_fallback_setting("publish_safety"),
133
+ )
134
+ retire_safety = TimePeriodField(
135
+ required=False,
136
+ label=_("Retire Safety"),
137
+ placeholder=DNSSECPolicy.get_fallback_setting("retire_safety"),
138
+ )
139
+ signatures_jitter = TimePeriodField(
140
+ required=False,
141
+ label=_("Signatures Jitter"),
142
+ placeholder=DNSSECPolicy.get_fallback_setting("signatures_jitter"),
143
+ )
144
+ signatures_refresh = TimePeriodField(
145
+ required=False,
146
+ label=_("Signatures Refresh"),
147
+ placeholder=DNSSECPolicy.get_fallback_setting("signatures_refresh"),
148
+ )
149
+ signatures_validity = TimePeriodField(
150
+ required=False,
151
+ label=_("Signatures Validity"),
152
+ placeholder=DNSSECPolicy.get_fallback_setting("signatures_validity"),
153
+ )
154
+ signatures_validity_dnskey = TimePeriodField(
155
+ required=False,
156
+ label=_("Signatures Validity (DNSKEY)"),
157
+ placeholder=DNSSECPolicy.get_fallback_setting("signatures_validity_dnskey"),
158
+ )
159
+ max_zone_ttl = TimePeriodField(
160
+ required=False,
161
+ label=_("Max Zone TTL"),
162
+ placeholder=DNSSECPolicy.get_fallback_setting("max_zone_ttl"),
163
+ )
164
+ zone_propagation_delay = TimePeriodField(
165
+ required=False,
166
+ label=_("Zone Propagation Delay"),
167
+ placeholder=DNSSECPolicy.get_fallback_setting("zone_propagation_delay"),
168
+ )
169
+ parent_ds_ttl = TimePeriodField(
170
+ required=False,
171
+ label=_("Parent DS TTL"),
172
+ placeholder=DNSSECPolicy.get_fallback_setting("parent_ds_ttl"),
173
+ )
174
+ parent_propagation_delay = TimePeriodField(
175
+ required=False,
176
+ label=_("Parent Propagation Delay"),
177
+ placeholder=DNSSECPolicy.get_fallback_setting("parent_propagation_delay"),
178
+ )
179
+
180
+
181
+ class DNSSECPolicyFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
182
+ model = DNSSECPolicy
183
+ fieldsets = (
184
+ FieldSet("q", "filter_id", "tag"),
185
+ FieldSet(
186
+ "name",
187
+ "description",
188
+ "status",
189
+ "key_template_id",
190
+ name=_("Attributes"),
191
+ ),
192
+ FieldSet(
193
+ "zone_id",
194
+ "zone_template_id",
195
+ name=_("Assignments"),
196
+ ),
197
+ FieldSet(
198
+ "dnskey_ttl",
199
+ "purge_keys",
200
+ "publish_safety",
201
+ "retire_safety",
202
+ "signatures_jitter",
203
+ "signatures_refresh",
204
+ "signatures_validity",
205
+ "signatures_validity_dnskey",
206
+ "max_zone_ttl",
207
+ "zone_propagation_delay",
208
+ name=_("Timing"),
209
+ ),
210
+ FieldSet(
211
+ "create_cdnskey",
212
+ "cds_digest_types",
213
+ "parent_ds_ttl",
214
+ "parent_propagation_delay",
215
+ name=_("Parent Delegation"),
216
+ ),
217
+ FieldSet(
218
+ "use_nsec3",
219
+ "nsec3_iterations",
220
+ "nsec3_opt_out",
221
+ "nsec3_salt_size",
222
+ name=_("Proof of Non-Existence"),
223
+ ),
224
+ FieldSet("tenant_group_id", "tenant_id", name=_("Tenancy")),
225
+ FieldSet("tags", name=_("Tags")),
226
+ )
227
+
228
+ name = forms.CharField(
229
+ required=False,
230
+ )
231
+ description = forms.CharField(
232
+ required=False,
233
+ )
234
+ status = forms.MultipleChoiceField(
235
+ choices=DNSSECPolicyStatusChoices,
236
+ required=False,
237
+ label=_("Status"),
238
+ )
239
+ key_template_id = DynamicModelMultipleChoiceField(
240
+ queryset=DNSSECKeyTemplate.objects.all(),
241
+ required=False,
242
+ null_option=_("None"),
243
+ label=_("Key Templates"),
244
+ )
245
+ zone_id = DynamicModelMultipleChoiceField(
246
+ queryset=Zone.objects.all(),
247
+ required=False,
248
+ null_option=_("None"),
249
+ label=_("Zones"),
250
+ )
251
+ zone_template_id = DynamicModelMultipleChoiceField(
252
+ queryset=ZoneTemplate.objects.all(),
253
+ required=False,
254
+ null_option=_("None"),
255
+ label=_("Zone Templates"),
256
+ )
257
+ dnskey_ttl = TimePeriodField(
258
+ required=False,
259
+ label=_("DNSKEY TTL"),
260
+ )
261
+ purge_keys = TimePeriodField(
262
+ required=False,
263
+ label=_("Purge Keys"),
264
+ )
265
+ publish_safety = TimePeriodField(
266
+ required=False,
267
+ label=_("Publish Safety"),
268
+ )
269
+ retire_safety = TimePeriodField(
270
+ required=False,
271
+ label=_("Retire Safety"),
272
+ )
273
+ signatures_jitter = TimePeriodField(
274
+ required=False,
275
+ label=_("Signatures Jitter"),
276
+ )
277
+ signatures_refresh = TimePeriodField(
278
+ required=False,
279
+ label=_("Signatures Refresh"),
280
+ )
281
+ signatures_validity = TimePeriodField(
282
+ required=False,
283
+ label=_("Signatures Validity"),
284
+ )
285
+ signatures_validity_dnskey = TimePeriodField(
286
+ required=False,
287
+ label=_("Signatures Validity (DNSKEY)"),
288
+ )
289
+ max_zone_ttl = TimePeriodField(
290
+ required=False,
291
+ label=_("Max Zone TTL"),
292
+ )
293
+ zone_propagation_delay = TimePeriodField(
294
+ required=False,
295
+ label=_("Zone Propagation Delay"),
296
+ )
297
+ create_cdnskey = forms.NullBooleanField(
298
+ required=False,
299
+ widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
300
+ label=_("Create CDNSKEY"),
301
+ )
302
+ cds_digest_types = forms.MultipleChoiceField(
303
+ required=False,
304
+ choices=DNSSECPolicyDigestChoices,
305
+ label=_("CDS Digest Types"),
306
+ )
307
+ parent_ds_ttl = TimePeriodField(
308
+ required=False,
309
+ label=_("Parent DS TTL"),
310
+ )
311
+ parent_propagation_delay = TimePeriodField(
312
+ required=False,
313
+ label=_("Parent Propagation Delay"),
314
+ )
315
+ use_nsec3 = forms.NullBooleanField(
316
+ required=False,
317
+ widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
318
+ label=_("Use NSEC3"),
319
+ )
320
+ nsec3_iterations = forms.IntegerField(
321
+ required=False,
322
+ label=_("NSEC3 Iterations"),
323
+ )
324
+ nsec3_opt_out = forms.NullBooleanField(
325
+ required=False,
326
+ widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
327
+ label=_("NSEC3 Opt-Out"),
328
+ )
329
+ nsec3_salt_size = forms.IntegerField(
330
+ required=False,
331
+ label=_("NSEC3 Salt Size"),
332
+ )
333
+
334
+ tag = TagFilterField(DNSSECPolicy)
335
+
336
+
337
+ class DNSSECPolicyImportForm(NetBoxModelImportForm):
338
+ status = CSVChoiceField(
339
+ choices=DNSSECPolicyStatusChoices,
340
+ required=False,
341
+ label=_("Status"),
342
+ )
343
+ dnskey_ttl = TimePeriodField(
344
+ required=False,
345
+ label=_("DNSKEY TTL"),
346
+ )
347
+ purge_keys = TimePeriodField(
348
+ required=False,
349
+ label=_("Purge Keys"),
350
+ )
351
+ publish_safety = TimePeriodField(
352
+ required=False,
353
+ label=_("Publish Safety"),
354
+ )
355
+ retire_safety = TimePeriodField(
356
+ required=False,
357
+ label=_("Retire Safety"),
358
+ )
359
+ signatures_jitter = TimePeriodField(
360
+ required=False,
361
+ label=_("Signatures Jitter"),
362
+ )
363
+ signatures_refresh = TimePeriodField(
364
+ required=False,
365
+ label=_("Signatures Refresh"),
366
+ )
367
+ signatures_validity = TimePeriodField(
368
+ required=False,
369
+ label=_("Signatures Validity"),
370
+ )
371
+ signatures_validity_dnskey = TimePeriodField(
372
+ required=False,
373
+ label=_("Signatures Validity (DNSKEY)"),
374
+ )
375
+ max_zone_ttl = TimePeriodField(
376
+ required=False,
377
+ label=_("Max Zone TTL"),
378
+ )
379
+ zone_propagation_delay = TimePeriodField(
380
+ required=False,
381
+ label=_("Zone Propagation Delay"),
382
+ )
383
+ parent_ds_ttl = TimePeriodField(
384
+ required=False,
385
+ label=_("Parent DS TTL"),
386
+ )
387
+ parent_propagation_delay = TimePeriodField(
388
+ required=False,
389
+ label=_("Parent Propagation Delay"),
390
+ )
391
+ tenant = CSVModelChoiceField(
392
+ queryset=Tenant.objects.all(),
393
+ to_field_name="name",
394
+ required=False,
395
+ label=_("Tenant"),
396
+ )
397
+
398
+ class Meta:
399
+ model = DNSSECPolicy
400
+ fields = (
401
+ "name",
402
+ "description",
403
+ "key_templates",
404
+ "dnskey_ttl",
405
+ "purge_keys",
406
+ "publish_safety",
407
+ "retire_safety",
408
+ "signatures_jitter",
409
+ "signatures_refresh",
410
+ "signatures_validity",
411
+ "signatures_validity_dnskey",
412
+ "max_zone_ttl",
413
+ "zone_propagation_delay",
414
+ "create_cdnskey",
415
+ "cds_digest_types",
416
+ "parent_ds_ttl",
417
+ "parent_propagation_delay",
418
+ "use_nsec3",
419
+ "nsec3_iterations",
420
+ "nsec3_opt_out",
421
+ "nsec3_salt_size",
422
+ "tenant",
423
+ "tags",
424
+ )
425
+
426
+
427
+ class DNSSECPolicyBulkEditForm(NetBoxModelBulkEditForm):
428
+ model = DNSSECPolicy
429
+
430
+ description = forms.CharField(
431
+ max_length=200,
432
+ required=False,
433
+ label=_("Description"),
434
+ )
435
+ status = forms.ChoiceField(
436
+ choices=add_blank_choice(DNSSECPolicyStatusChoices),
437
+ required=False,
438
+ label=_("Status"),
439
+ )
440
+ dnskey_ttl = TimePeriodField(
441
+ required=False,
442
+ label=_("DNSKEY TTL"),
443
+ )
444
+ purge_keys = TimePeriodField(
445
+ required=False,
446
+ label=_("Purge Keys"),
447
+ )
448
+ publish_safety = TimePeriodField(
449
+ required=False,
450
+ label=_("Publish Safety"),
451
+ )
452
+ retire_safety = TimePeriodField(
453
+ required=False,
454
+ label=_("Retire Safety"),
455
+ )
456
+ signatures_jitter = TimePeriodField(
457
+ required=False,
458
+ label=_("Signatures Jitter"),
459
+ )
460
+ signatures_refresh = TimePeriodField(
461
+ required=False,
462
+ label=_("Signatures Refresh"),
463
+ )
464
+ signatures_validity = TimePeriodField(
465
+ required=False,
466
+ label=_("Signatures Validity"),
467
+ )
468
+ signatures_validity_dnskey = TimePeriodField(
469
+ required=False,
470
+ label=_("Signatures Validity (DNSKEY)"),
471
+ )
472
+ max_zone_ttl = TimePeriodField(
473
+ required=False,
474
+ label=_("Max Zone TTL"),
475
+ )
476
+ zone_propagation_delay = TimePeriodField(
477
+ required=False,
478
+ label=_("Zone Propagation Delay"),
479
+ )
480
+ create_cdnskey = forms.NullBooleanField(
481
+ required=False,
482
+ widget=BulkEditNullBooleanSelect(),
483
+ label=_("Create CDNSKEY"),
484
+ )
485
+ cds_digest_types = forms.MultipleChoiceField(
486
+ choices=DNSSECPolicyDigestChoices,
487
+ required=False,
488
+ label=_("CDS Digest Types"),
489
+ )
490
+ parent_ds_ttl = TimePeriodField(
491
+ required=False,
492
+ label=_("Parent DS TTL"),
493
+ )
494
+ parent_propagation_delay = TimePeriodField(
495
+ required=False,
496
+ label=_("Parent Propagation Delay"),
497
+ )
498
+ use_nsec3 = forms.NullBooleanField(
499
+ required=False,
500
+ widget=BulkEditNullBooleanSelect(),
501
+ label=_("Use NSEC3"),
502
+ )
503
+ nsec3_iterations = forms.IntegerField(
504
+ required=False,
505
+ label=_("NSEC3 Iterations"),
506
+ )
507
+ nsec3_opt_out = forms.NullBooleanField(
508
+ required=False,
509
+ widget=BulkEditNullBooleanSelect(),
510
+ label=_("NSEC3 Opt-Out"),
511
+ )
512
+ nsec3_salt_size = forms.IntegerField(
513
+ required=False,
514
+ label=_("NSEC3 Salt Size"),
515
+ )
516
+ tenant_group = DynamicModelChoiceField(
517
+ queryset=TenantGroup.objects.all(),
518
+ required=False,
519
+ label=_("Tenant Group"),
520
+ )
521
+ tenant = DynamicModelChoiceField(
522
+ queryset=Tenant.objects.all(),
523
+ required=False,
524
+ label=_("Tenant"),
525
+ )
526
+
527
+ fieldsets = (
528
+ FieldSet(
529
+ "description",
530
+ "key_templates",
531
+ name=_("Attributes"),
532
+ ),
533
+ FieldSet(
534
+ "dnskey_ttl",
535
+ "purge_keys",
536
+ "publish_safety",
537
+ "retire_safety",
538
+ "signatures_jitter",
539
+ "signatures_refresh",
540
+ "signatures_validity",
541
+ "signatures_validity_dnskey",
542
+ "max_zone_ttl",
543
+ "zone_propagation_delay",
544
+ name=_("Timing"),
545
+ ),
546
+ FieldSet(
547
+ "create_cdnskey",
548
+ "cds_digest_types",
549
+ "parent_ds_ttl",
550
+ "parent_propagation_delay",
551
+ name=_("Parent Delegation"),
552
+ ),
553
+ FieldSet(
554
+ "use_nsec3",
555
+ "nsec3_iterations",
556
+ "nsec3_opt_out",
557
+ "nsec3_salt_size",
558
+ name=_("Proof of Non-Existence"),
559
+ ),
560
+ FieldSet("tenant_group", "tenant", name=_("Tenancy")),
561
+ )
562
+
563
+ nullable_fields = (
564
+ "description",
565
+ "tenant",
566
+ "dnskey_ttl",
567
+ "purge_keys",
568
+ "publish_safety",
569
+ "retire_safety",
570
+ "signatures_jitter",
571
+ "signatures_refresh",
572
+ "signatures_validity",
573
+ "signatures_validity_dnskey",
574
+ "max_zone_ttl",
575
+ "zone_propagation_delay",
576
+ "cds_digest_types",
577
+ "parent_ds_ttl",
578
+ "parent_propagation_delay",
579
+ "nsec3_iterations",
580
+ "nsec3_opt_out",
581
+ "nsec3_salt_size",
582
+ "cds_digest_types",
583
+ "parent_ds_ttl",
584
+ "parent_propagation_delay",
585
+ )
586
+
587
+ def clean_cds_digest_types(self, *args, **kwargs):
588
+ if not (
589
+ cds_digest_types := self.cleaned_data.get("cds_digest_types")
590
+ ) and "cds_digest_types" not in self.data.get("_nullify", []):
591
+ return self.initial.get("cds_digest_types")
592
+
593
+ return cds_digest_types
@@ -64,11 +64,13 @@ class NameServerFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
64
64
  zone_id = DynamicModelMultipleChoiceField(
65
65
  queryset=Zone.objects.all(),
66
66
  required=False,
67
+ null_option=_("None"),
67
68
  label=_("Zones"),
68
69
  )
69
70
  soa_zone_id = DynamicModelMultipleChoiceField(
70
71
  queryset=Zone.objects.all(),
71
72
  required=False,
73
+ null_option=_("None"),
72
74
  label=_("SOA Zones"),
73
75
  )
74
76
  description = forms.CharField(
@@ -146,6 +146,7 @@ class RecordTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
146
146
  zone_template_id = DynamicModelMultipleChoiceField(
147
147
  queryset=ZoneTemplate.objects.all(),
148
148
  required=False,
149
+ null_option=_("None"),
149
150
  label=_("Zone Templates"),
150
151
  )
151
152
  tag = TagFilterField(RecordTemplate)