netbox-plugin-dns 1.0.4__py3-none-any.whl → 1.0.6__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 +1 -1
- netbox_dns/api/nested_serializers.py +46 -1
- netbox_dns/api/serializers.py +2 -0
- netbox_dns/api/serializers_/contact.py +3 -0
- netbox_dns/api/serializers_/nameserver.py +4 -1
- netbox_dns/api/serializers_/record.py +5 -4
- netbox_dns/api/serializers_/record_template.py +58 -0
- netbox_dns/api/serializers_/registrar.py +3 -0
- netbox_dns/api/serializers_/view.py +3 -0
- netbox_dns/api/serializers_/zone.py +31 -6
- netbox_dns/api/serializers_/zone_template.py +130 -0
- netbox_dns/api/urls.py +4 -0
- netbox_dns/api/views.py +41 -1
- netbox_dns/choices/__init__.py +2 -0
- netbox_dns/choices/record.py +49 -0
- netbox_dns/choices/zone.py +20 -0
- netbox_dns/fields/address.py +6 -0
- netbox_dns/fields/network.py +3 -0
- netbox_dns/fields/rfc2317.py +6 -0
- netbox_dns/filtersets/__init__.py +3 -0
- netbox_dns/filtersets/contact.py +3 -0
- netbox_dns/filtersets/nameserver.py +3 -0
- netbox_dns/filtersets/record.py +5 -1
- netbox_dns/filtersets/record_template.py +54 -0
- netbox_dns/filtersets/registrar.py +3 -0
- netbox_dns/filtersets/view.py +3 -0
- netbox_dns/filtersets/zone.py +5 -8
- netbox_dns/filtersets/zone_template.py +116 -0
- netbox_dns/forms/__init__.py +2 -0
- netbox_dns/forms/contact.py +8 -0
- netbox_dns/forms/nameserver.py +21 -2
- netbox_dns/forms/record.py +24 -10
- netbox_dns/forms/record_template.py +220 -0
- netbox_dns/forms/registrar.py +8 -0
- netbox_dns/forms/view.py +10 -0
- netbox_dns/forms/zone.py +125 -41
- netbox_dns/forms/zone_template.py +298 -0
- netbox_dns/graphql/__init__.py +4 -0
- netbox_dns/graphql/filters.py +24 -1
- netbox_dns/graphql/schema.py +34 -1
- netbox_dns/graphql/types.py +70 -1
- netbox_dns/management/commands/cleanup_database.py +2 -6
- netbox_dns/management/commands/cleanup_rrset_ttl.py +2 -4
- netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +1 -2
- netbox_dns/migrations/0006_templating.py +172 -0
- netbox_dns/migrations/0021_record_ip_address.py +1 -1
- netbox_dns/mixins/object_modification.py +5 -0
- netbox_dns/models/__init__.py +7 -0
- netbox_dns/models/contact.py +6 -0
- netbox_dns/models/nameserver.py +8 -1
- netbox_dns/models/record.py +13 -122
- netbox_dns/models/record_template.py +180 -0
- netbox_dns/models/registrar.py +6 -0
- netbox_dns/models/view.py +7 -1
- netbox_dns/models/zone.py +63 -71
- netbox_dns/models/zone_template.py +150 -0
- netbox_dns/navigation.py +47 -0
- netbox_dns/tables/__init__.py +2 -0
- netbox_dns/tables/contact.py +3 -0
- netbox_dns/tables/nameserver.py +3 -2
- netbox_dns/tables/record.py +7 -3
- netbox_dns/tables/record_template.py +91 -0
- netbox_dns/tables/registrar.py +3 -0
- netbox_dns/tables/view.py +3 -0
- netbox_dns/tables/zone.py +3 -2
- netbox_dns/tables/zone_template.py +70 -0
- netbox_dns/template_content.py +2 -8
- netbox_dns/templates/netbox_dns/recordtemplate.html +84 -0
- netbox_dns/templates/netbox_dns/zonetemplate.html +86 -0
- netbox_dns/urls/__init__.py +4 -0
- netbox_dns/urls/record_template.py +65 -0
- netbox_dns/urls/zone_template.py +57 -0
- netbox_dns/utilities/ipam_coupling.py +2 -1
- netbox_dns/validators/__init__.py +1 -0
- netbox_dns/validators/dns_name.py +14 -9
- netbox_dns/validators/dns_value.py +83 -0
- netbox_dns/validators/rfc2317.py +7 -0
- netbox_dns/views/__init__.py +2 -0
- netbox_dns/views/contact.py +12 -0
- netbox_dns/views/nameserver.py +13 -0
- netbox_dns/views/record.py +14 -1
- netbox_dns/views/record_template.py +83 -0
- netbox_dns/views/registrar.py +12 -0
- netbox_dns/views/view.py +12 -0
- netbox_dns/views/zone.py +16 -0
- netbox_dns/views/zone_template.py +73 -0
- {netbox_plugin_dns-1.0.4.dist-info → netbox_plugin_dns-1.0.6.dist-info}/METADATA +2 -1
- netbox_plugin_dns-1.0.6.dist-info/RECORD +136 -0
- netbox_plugin_dns-1.0.4.dist-info/RECORD +0 -115
- {netbox_plugin_dns-1.0.4.dist-info → netbox_plugin_dns-1.0.6.dist-info}/LICENSE +0 -0
- {netbox_plugin_dns-1.0.4.dist-info → netbox_plugin_dns-1.0.6.dist-info}/WHEEL +0 -0
netbox_dns/forms/zone.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from django import forms
|
|
2
|
+
from django.db import transaction
|
|
2
3
|
from django.conf import settings
|
|
3
4
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
|
4
|
-
from django.
|
|
5
|
+
from django.core.exceptions import ValidationError
|
|
5
6
|
|
|
6
7
|
from netbox.forms import (
|
|
7
8
|
NetBoxModelBulkEditForm,
|
|
@@ -9,6 +10,7 @@ from netbox.forms import (
|
|
|
9
10
|
NetBoxModelImportForm,
|
|
10
11
|
NetBoxModelForm,
|
|
11
12
|
)
|
|
13
|
+
from netbox.context import events_queue
|
|
12
14
|
from utilities.forms.fields import (
|
|
13
15
|
DynamicModelMultipleChoiceField,
|
|
14
16
|
TagFilterField,
|
|
@@ -17,26 +19,115 @@ from utilities.forms.fields import (
|
|
|
17
19
|
CSVModelMultipleChoiceField,
|
|
18
20
|
DynamicModelChoiceField,
|
|
19
21
|
)
|
|
20
|
-
from utilities.forms.widgets import BulkEditNullBooleanSelect
|
|
22
|
+
from utilities.forms.widgets import BulkEditNullBooleanSelect
|
|
21
23
|
from utilities.forms.rendering import FieldSet
|
|
22
|
-
from utilities.forms import add_blank_choice
|
|
24
|
+
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, add_blank_choice
|
|
23
25
|
from tenancy.models import Tenant
|
|
24
26
|
from tenancy.forms import TenancyForm, TenancyFilterForm
|
|
25
27
|
|
|
26
28
|
from netbox_dns.models import (
|
|
27
29
|
View,
|
|
28
30
|
Zone,
|
|
29
|
-
ZoneStatusChoices,
|
|
30
31
|
NameServer,
|
|
31
32
|
Registrar,
|
|
32
33
|
Contact,
|
|
34
|
+
ZoneTemplate,
|
|
33
35
|
)
|
|
36
|
+
from netbox_dns.choices import ZoneStatusChoices
|
|
34
37
|
from netbox_dns.utilities import name_to_unicode
|
|
35
38
|
from netbox_dns.fields import RFC2317NetworkFormField
|
|
36
39
|
from netbox_dns.validators import validate_ipv4, validate_prefix, validate_rfc2317
|
|
37
40
|
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
__all__ = (
|
|
43
|
+
"ZoneForm",
|
|
44
|
+
"ZoneFilterForm",
|
|
45
|
+
"ZoneImportForm",
|
|
46
|
+
"ZoneBulkEditForm",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class RollbackTransaction(Exception):
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class ZoneTemplateUpdateMixin:
|
|
55
|
+
def clean(self, *args, **kwargs):
|
|
56
|
+
super().clean(*args, **kwargs)
|
|
57
|
+
|
|
58
|
+
if (template := self.cleaned_data.get("template")) is None:
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
if not self.cleaned_data.get("nameservers") and template.nameservers.all():
|
|
62
|
+
self.cleaned_data["nameservers"] = template.nameservers.all()
|
|
63
|
+
|
|
64
|
+
if not self.cleaned_data.get("tags") and template.tags.all():
|
|
65
|
+
self.cleaned_data["tags"] = template.tags.all()
|
|
66
|
+
|
|
67
|
+
for field in template.template_fields:
|
|
68
|
+
if (
|
|
69
|
+
self.cleaned_data.get(field) is None
|
|
70
|
+
and getattr(template, field) is not None
|
|
71
|
+
):
|
|
72
|
+
self.cleaned_data[field] = getattr(template, field)
|
|
73
|
+
|
|
74
|
+
template_error = None
|
|
75
|
+
saved_events_queue = events_queue.get()
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
with transaction.atomic():
|
|
79
|
+
if self.instance.id is not None:
|
|
80
|
+
zone = super().save(*args, **kwargs)
|
|
81
|
+
else:
|
|
82
|
+
zone_data = self.cleaned_data.copy()
|
|
83
|
+
|
|
84
|
+
custom_fields = dict()
|
|
85
|
+
for key, value in zone_data.copy().items():
|
|
86
|
+
if key.startswith("cf_"):
|
|
87
|
+
custom_fields[key[3:]] = value
|
|
88
|
+
zone_data.pop(key)
|
|
89
|
+
if custom_fields:
|
|
90
|
+
zone_data["custom_field_data"] = custom_fields
|
|
91
|
+
|
|
92
|
+
zone_data.pop("template", None)
|
|
93
|
+
zone_data.pop("tenant_group", None)
|
|
94
|
+
zone_data.pop("_init_time", None)
|
|
95
|
+
|
|
96
|
+
nameservers = zone_data.pop("nameservers")
|
|
97
|
+
tags = zone_data.pop("tags")
|
|
98
|
+
|
|
99
|
+
zone = Zone.objects.create(**zone_data)
|
|
100
|
+
|
|
101
|
+
zone.nameservers.set(nameservers)
|
|
102
|
+
zone.tags.set(tags)
|
|
103
|
+
|
|
104
|
+
template.create_records(zone)
|
|
105
|
+
raise RollbackTransaction
|
|
106
|
+
|
|
107
|
+
except ValidationError as exc:
|
|
108
|
+
if isinstance(exc, dict):
|
|
109
|
+
template_error = item.value()
|
|
110
|
+
else:
|
|
111
|
+
template_error = [exc]
|
|
112
|
+
except RollbackTransaction:
|
|
113
|
+
pass
|
|
114
|
+
|
|
115
|
+
events_queue.set(saved_events_queue)
|
|
116
|
+
if template_error is not None:
|
|
117
|
+
raise ValidationError({"template": template_error})
|
|
118
|
+
|
|
119
|
+
return self.cleaned_data
|
|
120
|
+
|
|
121
|
+
def save(self, *args, **kwargs):
|
|
122
|
+
zone = super().save(*args, **kwargs)
|
|
123
|
+
|
|
124
|
+
if (template := self.cleaned_data.get("template")) is not None:
|
|
125
|
+
template.create_records(zone)
|
|
126
|
+
|
|
127
|
+
return zone
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class ZoneForm(ZoneTemplateUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
40
131
|
nameservers = DynamicModelMultipleChoiceField(
|
|
41
132
|
queryset=NameServer.objects.all(),
|
|
42
133
|
required=False,
|
|
@@ -104,11 +195,17 @@ class ZoneForm(TenancyForm, NetBoxModelForm):
|
|
|
104
195
|
help_text="IPv4 reverse zone for deletgating the RFC2317 PTR records is managed in NetBox DNS",
|
|
105
196
|
required=False,
|
|
106
197
|
)
|
|
198
|
+
template = DynamicModelChoiceField(
|
|
199
|
+
queryset=ZoneTemplate.objects.all(),
|
|
200
|
+
required=False,
|
|
201
|
+
label="Template",
|
|
202
|
+
)
|
|
107
203
|
|
|
108
204
|
fieldsets = (
|
|
109
205
|
FieldSet(
|
|
110
206
|
"view",
|
|
111
207
|
"name",
|
|
208
|
+
"template",
|
|
112
209
|
"status",
|
|
113
210
|
"nameservers",
|
|
114
211
|
"default_ttl",
|
|
@@ -172,9 +269,6 @@ class ZoneForm(TenancyForm, NetBoxModelForm):
|
|
|
172
269
|
if self.initial.get("soa_ttl") is None:
|
|
173
270
|
self.initial["soa_ttl"] = self.initial.get("default_ttl")
|
|
174
271
|
|
|
175
|
-
if self.initial.get("soa_serial_auto"):
|
|
176
|
-
self.initial["soa_serial"] = None
|
|
177
|
-
|
|
178
272
|
if self.initial.get("soa_mname") is None:
|
|
179
273
|
default_soa_mname = defaults.get("zone_soa_mname")
|
|
180
274
|
if default_soa_mname is not None:
|
|
@@ -206,6 +300,7 @@ class ZoneForm(TenancyForm, NetBoxModelForm):
|
|
|
206
300
|
"name",
|
|
207
301
|
"view",
|
|
208
302
|
"status",
|
|
303
|
+
"template",
|
|
209
304
|
"nameservers",
|
|
210
305
|
"default_ttl",
|
|
211
306
|
"description",
|
|
@@ -240,7 +335,12 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
240
335
|
fieldsets = (
|
|
241
336
|
FieldSet("q", "filter_id", "tag"),
|
|
242
337
|
FieldSet(
|
|
243
|
-
"view_id",
|
|
338
|
+
"view_id",
|
|
339
|
+
"status",
|
|
340
|
+
"name",
|
|
341
|
+
"nameserver_id",
|
|
342
|
+
"description",
|
|
343
|
+
name="Attributes",
|
|
244
344
|
),
|
|
245
345
|
FieldSet(
|
|
246
346
|
"soa_mname_id",
|
|
@@ -278,9 +378,10 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
278
378
|
name = forms.CharField(
|
|
279
379
|
required=False,
|
|
280
380
|
)
|
|
281
|
-
|
|
381
|
+
nameserver_id = DynamicModelMultipleChoiceField(
|
|
282
382
|
queryset=NameServer.objects.all(),
|
|
283
383
|
required=False,
|
|
384
|
+
label="Nameservers",
|
|
284
385
|
)
|
|
285
386
|
description = forms.CharField(
|
|
286
387
|
required=False,
|
|
@@ -297,6 +398,7 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
297
398
|
soa_serial_auto = forms.NullBooleanField(
|
|
298
399
|
required=False,
|
|
299
400
|
label="Generate Serial",
|
|
401
|
+
widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
|
|
300
402
|
)
|
|
301
403
|
rfc2317_prefix = RFC2317NetworkFormField(
|
|
302
404
|
required=False,
|
|
@@ -305,6 +407,7 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
305
407
|
rfc2317_parent_managed = forms.NullBooleanField(
|
|
306
408
|
required=False,
|
|
307
409
|
label="Parent Managed",
|
|
410
|
+
widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
|
|
308
411
|
)
|
|
309
412
|
rfc2317_parent_zone_id = DynamicModelMultipleChoiceField(
|
|
310
413
|
queryset=Zone.objects.all(),
|
|
@@ -343,7 +446,7 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
343
446
|
tag = TagFilterField(Zone)
|
|
344
447
|
|
|
345
448
|
|
|
346
|
-
class ZoneImportForm(NetBoxModelImportForm):
|
|
449
|
+
class ZoneImportForm(ZoneTemplateUpdateMixin, NetBoxModelImportForm):
|
|
347
450
|
view = CSVModelChoiceField(
|
|
348
451
|
queryset=View.objects.all(),
|
|
349
452
|
required=False,
|
|
@@ -385,7 +488,7 @@ class ZoneImportForm(NetBoxModelImportForm):
|
|
|
385
488
|
required=False,
|
|
386
489
|
help_text="Mailbox of the zone's administrator",
|
|
387
490
|
)
|
|
388
|
-
soa_serial_auto = forms.
|
|
491
|
+
soa_serial_auto = forms.BooleanField(
|
|
389
492
|
required=False,
|
|
390
493
|
help_text="Generate the SOA serial",
|
|
391
494
|
)
|
|
@@ -473,6 +576,12 @@ class ZoneImportForm(NetBoxModelImportForm):
|
|
|
473
576
|
to_field_name="name",
|
|
474
577
|
help_text="Assigned tenant",
|
|
475
578
|
)
|
|
579
|
+
template = CSVModelChoiceField(
|
|
580
|
+
queryset=ZoneTemplate.objects.all(),
|
|
581
|
+
required=False,
|
|
582
|
+
to_field_name="name",
|
|
583
|
+
label="Template",
|
|
584
|
+
)
|
|
476
585
|
|
|
477
586
|
class Meta:
|
|
478
587
|
model = Zone
|
|
@@ -481,6 +590,7 @@ class ZoneImportForm(NetBoxModelImportForm):
|
|
|
481
590
|
"view",
|
|
482
591
|
"name",
|
|
483
592
|
"status",
|
|
593
|
+
"template",
|
|
484
594
|
"nameservers",
|
|
485
595
|
"default_ttl",
|
|
486
596
|
"description",
|
|
@@ -532,9 +642,6 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
532
642
|
queryset=View.objects.all(),
|
|
533
643
|
required=False,
|
|
534
644
|
label="View",
|
|
535
|
-
widget=APISelect(
|
|
536
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:view-list")}
|
|
537
|
-
),
|
|
538
645
|
)
|
|
539
646
|
status = forms.ChoiceField(
|
|
540
647
|
choices=add_blank_choice(ZoneStatusChoices),
|
|
@@ -559,11 +666,6 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
559
666
|
queryset=NameServer.objects.all(),
|
|
560
667
|
required=False,
|
|
561
668
|
label="SOA Primary Nameserver",
|
|
562
|
-
widget=APISelect(
|
|
563
|
-
attrs={
|
|
564
|
-
"data-url": reverse_lazy("plugins-api:netbox_dns-api:nameserver-list")
|
|
565
|
-
}
|
|
566
|
-
),
|
|
567
669
|
)
|
|
568
670
|
soa_rname = forms.CharField(
|
|
569
671
|
required=False,
|
|
@@ -614,11 +716,6 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
614
716
|
registrar = DynamicModelChoiceField(
|
|
615
717
|
queryset=Registrar.objects.all(),
|
|
616
718
|
required=False,
|
|
617
|
-
widget=APISelect(
|
|
618
|
-
attrs={
|
|
619
|
-
"data-url": reverse_lazy("plugins-api:netbox_dns-api:registrar-list")
|
|
620
|
-
}
|
|
621
|
-
),
|
|
622
719
|
)
|
|
623
720
|
registry_domain_id = forms.CharField(
|
|
624
721
|
required=False,
|
|
@@ -627,41 +724,26 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
627
724
|
registrant = DynamicModelChoiceField(
|
|
628
725
|
queryset=Contact.objects.all(),
|
|
629
726
|
required=False,
|
|
630
|
-
widget=APISelect(
|
|
631
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:contact-list")}
|
|
632
|
-
),
|
|
633
727
|
)
|
|
634
728
|
admin_c = DynamicModelChoiceField(
|
|
635
729
|
queryset=Contact.objects.all(),
|
|
636
730
|
required=False,
|
|
637
731
|
label="Administrative Contact",
|
|
638
|
-
widget=APISelect(
|
|
639
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:contact-list")}
|
|
640
|
-
),
|
|
641
732
|
)
|
|
642
733
|
tech_c = DynamicModelChoiceField(
|
|
643
734
|
queryset=Contact.objects.all(),
|
|
644
735
|
required=False,
|
|
645
736
|
label="Technical Contact",
|
|
646
|
-
widget=APISelect(
|
|
647
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:contact-list")}
|
|
648
|
-
),
|
|
649
737
|
)
|
|
650
738
|
billing_c = DynamicModelChoiceField(
|
|
651
739
|
queryset=Contact.objects.all(),
|
|
652
740
|
required=False,
|
|
653
741
|
label="Billing Contact",
|
|
654
|
-
widget=APISelect(
|
|
655
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:contact-list")}
|
|
656
|
-
),
|
|
657
742
|
)
|
|
658
|
-
tenant =
|
|
743
|
+
tenant = DynamicModelChoiceField(
|
|
659
744
|
queryset=Tenant.objects.all(),
|
|
660
745
|
required=False,
|
|
661
|
-
to_field_name="name",
|
|
662
|
-
help_text="Assigned tenant",
|
|
663
746
|
)
|
|
664
|
-
tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False)
|
|
665
747
|
|
|
666
748
|
model = Zone
|
|
667
749
|
|
|
@@ -705,6 +787,7 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
705
787
|
|
|
706
788
|
nullable_fields = (
|
|
707
789
|
"description",
|
|
790
|
+
"nameservers",
|
|
708
791
|
"rfc2317_prefix",
|
|
709
792
|
"registrar",
|
|
710
793
|
"registry_domain_id",
|
|
@@ -712,4 +795,5 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
712
795
|
"admin_c",
|
|
713
796
|
"tech_c",
|
|
714
797
|
"billing_c",
|
|
798
|
+
"tenant",
|
|
715
799
|
)
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
from django import forms
|
|
2
|
+
|
|
3
|
+
from netbox.forms import (
|
|
4
|
+
NetBoxModelBulkEditForm,
|
|
5
|
+
NetBoxModelFilterSetForm,
|
|
6
|
+
NetBoxModelImportForm,
|
|
7
|
+
NetBoxModelForm,
|
|
8
|
+
)
|
|
9
|
+
from utilities.forms.fields import (
|
|
10
|
+
DynamicModelMultipleChoiceField,
|
|
11
|
+
TagFilterField,
|
|
12
|
+
CSVModelChoiceField,
|
|
13
|
+
CSVModelMultipleChoiceField,
|
|
14
|
+
DynamicModelChoiceField,
|
|
15
|
+
)
|
|
16
|
+
from utilities.forms.rendering import FieldSet
|
|
17
|
+
from tenancy.models import Tenant
|
|
18
|
+
from tenancy.forms import TenancyForm, TenancyFilterForm
|
|
19
|
+
|
|
20
|
+
from netbox_dns.models import (
|
|
21
|
+
ZoneTemplate,
|
|
22
|
+
RecordTemplate,
|
|
23
|
+
NameServer,
|
|
24
|
+
Registrar,
|
|
25
|
+
Contact,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
__all__ = (
|
|
30
|
+
"ZoneTemplateForm",
|
|
31
|
+
"ZoneTemplateFilterForm",
|
|
32
|
+
"ZoneTemplateImportForm",
|
|
33
|
+
"ZoneTemplateBulkEditForm",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
38
|
+
nameservers = DynamicModelMultipleChoiceField(
|
|
39
|
+
queryset=NameServer.objects.all(),
|
|
40
|
+
required=False,
|
|
41
|
+
)
|
|
42
|
+
record_templates = DynamicModelMultipleChoiceField(
|
|
43
|
+
queryset=RecordTemplate.objects.all(),
|
|
44
|
+
required=False,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
fieldsets = (
|
|
48
|
+
FieldSet("name", "description", "nameservers", name="Zone Template"),
|
|
49
|
+
FieldSet("record_templates", name="Record Templates"),
|
|
50
|
+
FieldSet(
|
|
51
|
+
"registrar",
|
|
52
|
+
"registrant",
|
|
53
|
+
"admin_c",
|
|
54
|
+
"tech_c",
|
|
55
|
+
"billing_c",
|
|
56
|
+
name="Domain Registration",
|
|
57
|
+
),
|
|
58
|
+
FieldSet("tags", name="Tags"),
|
|
59
|
+
FieldSet("tenant_group", "tenant", name="Tenancy"),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
class Meta:
|
|
63
|
+
model = ZoneTemplate
|
|
64
|
+
|
|
65
|
+
fields = (
|
|
66
|
+
"name",
|
|
67
|
+
"nameservers",
|
|
68
|
+
"record_templates",
|
|
69
|
+
"description",
|
|
70
|
+
"tags",
|
|
71
|
+
"registrar",
|
|
72
|
+
"registrant",
|
|
73
|
+
"admin_c",
|
|
74
|
+
"tech_c",
|
|
75
|
+
"billing_c",
|
|
76
|
+
"tenant",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class ZoneTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
81
|
+
model = ZoneTemplate
|
|
82
|
+
fieldsets = (
|
|
83
|
+
FieldSet("q", "filter_id", "tag"),
|
|
84
|
+
FieldSet("name", "nameserver_id", "description", name="Attributes"),
|
|
85
|
+
FieldSet("record_template_id", name="Record Templates"),
|
|
86
|
+
FieldSet(
|
|
87
|
+
"registrar_id",
|
|
88
|
+
"registrant_id",
|
|
89
|
+
"admin_c_id",
|
|
90
|
+
"tech_c_id",
|
|
91
|
+
"billing_c_id",
|
|
92
|
+
name="Registration",
|
|
93
|
+
),
|
|
94
|
+
FieldSet("tenant_group_id", "tenant_id", name="Tenancy"),
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
name = forms.CharField(
|
|
98
|
+
required=False,
|
|
99
|
+
label="Template name",
|
|
100
|
+
)
|
|
101
|
+
nameserver_id = DynamicModelMultipleChoiceField(
|
|
102
|
+
queryset=NameServer.objects.all(),
|
|
103
|
+
required=False,
|
|
104
|
+
label="Nameservers",
|
|
105
|
+
)
|
|
106
|
+
record_template_id = DynamicModelMultipleChoiceField(
|
|
107
|
+
queryset=RecordTemplate.objects.all(),
|
|
108
|
+
required=False,
|
|
109
|
+
label="Record templates",
|
|
110
|
+
)
|
|
111
|
+
description = forms.CharField(
|
|
112
|
+
required=False,
|
|
113
|
+
)
|
|
114
|
+
registrar_id = DynamicModelMultipleChoiceField(
|
|
115
|
+
queryset=Registrar.objects.all(),
|
|
116
|
+
required=False,
|
|
117
|
+
label="Registrar",
|
|
118
|
+
)
|
|
119
|
+
registrant_id = DynamicModelMultipleChoiceField(
|
|
120
|
+
queryset=Contact.objects.all(),
|
|
121
|
+
required=False,
|
|
122
|
+
label="Registrant",
|
|
123
|
+
)
|
|
124
|
+
admin_c_id = DynamicModelMultipleChoiceField(
|
|
125
|
+
queryset=Contact.objects.all(),
|
|
126
|
+
required=False,
|
|
127
|
+
label="Admin-C",
|
|
128
|
+
)
|
|
129
|
+
tech_c_id = DynamicModelMultipleChoiceField(
|
|
130
|
+
queryset=Contact.objects.all(),
|
|
131
|
+
required=False,
|
|
132
|
+
label="Tech-C",
|
|
133
|
+
)
|
|
134
|
+
billing_c_id = DynamicModelMultipleChoiceField(
|
|
135
|
+
queryset=Contact.objects.all(),
|
|
136
|
+
required=False,
|
|
137
|
+
label="Billing-C",
|
|
138
|
+
)
|
|
139
|
+
tag = TagFilterField(ZoneTemplate)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class ZoneTemplateImportForm(NetBoxModelImportForm):
|
|
143
|
+
nameservers = CSVModelMultipleChoiceField(
|
|
144
|
+
queryset=NameServer.objects.all(),
|
|
145
|
+
to_field_name="name",
|
|
146
|
+
required=False,
|
|
147
|
+
help_text="Name servers for the zone template",
|
|
148
|
+
)
|
|
149
|
+
record_templates = CSVModelMultipleChoiceField(
|
|
150
|
+
queryset=RecordTemplate.objects.all(),
|
|
151
|
+
to_field_name="name",
|
|
152
|
+
required=False,
|
|
153
|
+
help_text="Record templates used by this zone template",
|
|
154
|
+
)
|
|
155
|
+
registrar = CSVModelChoiceField(
|
|
156
|
+
queryset=Registrar.objects.all(),
|
|
157
|
+
required=False,
|
|
158
|
+
to_field_name="name",
|
|
159
|
+
help_text="Registrar the domain is registered with",
|
|
160
|
+
error_messages={
|
|
161
|
+
"invalid_choice": "Registrar not found.",
|
|
162
|
+
},
|
|
163
|
+
)
|
|
164
|
+
registrant = CSVModelChoiceField(
|
|
165
|
+
queryset=Contact.objects.all(),
|
|
166
|
+
required=False,
|
|
167
|
+
to_field_name="contact_id",
|
|
168
|
+
help_text="Owner of the domain",
|
|
169
|
+
error_messages={
|
|
170
|
+
"invalid_choice": "Registrant contact ID not found",
|
|
171
|
+
},
|
|
172
|
+
)
|
|
173
|
+
admin_c = CSVModelChoiceField(
|
|
174
|
+
queryset=Contact.objects.all(),
|
|
175
|
+
required=False,
|
|
176
|
+
to_field_name="contact_id",
|
|
177
|
+
help_text="Administrative contact for the domain",
|
|
178
|
+
error_messages={
|
|
179
|
+
"invalid_choice": "Administrative contact ID not found",
|
|
180
|
+
},
|
|
181
|
+
)
|
|
182
|
+
tech_c = CSVModelChoiceField(
|
|
183
|
+
queryset=Contact.objects.all(),
|
|
184
|
+
required=False,
|
|
185
|
+
to_field_name="contact_id",
|
|
186
|
+
help_text="Technical contact for the domain",
|
|
187
|
+
error_messages={
|
|
188
|
+
"invalid_choice": "Technical contact ID not found",
|
|
189
|
+
},
|
|
190
|
+
)
|
|
191
|
+
billing_c = CSVModelChoiceField(
|
|
192
|
+
queryset=Contact.objects.all(),
|
|
193
|
+
required=False,
|
|
194
|
+
to_field_name="contact_id",
|
|
195
|
+
help_text="Billing contact for the domain",
|
|
196
|
+
error_messages={
|
|
197
|
+
"invalid_choice": "Billing contact ID not found",
|
|
198
|
+
},
|
|
199
|
+
)
|
|
200
|
+
tenant = CSVModelChoiceField(
|
|
201
|
+
queryset=Tenant.objects.all(),
|
|
202
|
+
required=False,
|
|
203
|
+
to_field_name="name",
|
|
204
|
+
help_text="Assigned tenant",
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
class Meta:
|
|
208
|
+
model = ZoneTemplate
|
|
209
|
+
|
|
210
|
+
fields = (
|
|
211
|
+
"name",
|
|
212
|
+
"nameservers",
|
|
213
|
+
"record_templates",
|
|
214
|
+
"description",
|
|
215
|
+
"registrar",
|
|
216
|
+
"registrant",
|
|
217
|
+
"admin_c",
|
|
218
|
+
"tech_c",
|
|
219
|
+
"billing_c",
|
|
220
|
+
"tenant",
|
|
221
|
+
"tags",
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
226
|
+
nameservers = DynamicModelMultipleChoiceField(
|
|
227
|
+
queryset=NameServer.objects.all(),
|
|
228
|
+
required=False,
|
|
229
|
+
)
|
|
230
|
+
record_templates = DynamicModelMultipleChoiceField(
|
|
231
|
+
queryset=RecordTemplate.objects.all(),
|
|
232
|
+
required=False,
|
|
233
|
+
)
|
|
234
|
+
description = forms.CharField(max_length=200, required=False)
|
|
235
|
+
registrar = DynamicModelChoiceField(
|
|
236
|
+
queryset=Registrar.objects.all(),
|
|
237
|
+
required=False,
|
|
238
|
+
)
|
|
239
|
+
registrant = DynamicModelChoiceField(
|
|
240
|
+
queryset=Contact.objects.all(),
|
|
241
|
+
required=False,
|
|
242
|
+
)
|
|
243
|
+
admin_c = DynamicModelChoiceField(
|
|
244
|
+
queryset=Contact.objects.all(),
|
|
245
|
+
required=False,
|
|
246
|
+
label="Administrative Contact",
|
|
247
|
+
)
|
|
248
|
+
tech_c = DynamicModelChoiceField(
|
|
249
|
+
queryset=Contact.objects.all(),
|
|
250
|
+
required=False,
|
|
251
|
+
label="Technical Contact",
|
|
252
|
+
)
|
|
253
|
+
billing_c = DynamicModelChoiceField(
|
|
254
|
+
queryset=Contact.objects.all(),
|
|
255
|
+
required=False,
|
|
256
|
+
label="Billing Contact",
|
|
257
|
+
)
|
|
258
|
+
tenant = CSVModelChoiceField(
|
|
259
|
+
queryset=Tenant.objects.all(),
|
|
260
|
+
required=False,
|
|
261
|
+
to_field_name="name",
|
|
262
|
+
help_text="Assigned tenant",
|
|
263
|
+
)
|
|
264
|
+
tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False)
|
|
265
|
+
|
|
266
|
+
model = ZoneTemplate
|
|
267
|
+
|
|
268
|
+
fieldsets = (
|
|
269
|
+
FieldSet(
|
|
270
|
+
"nameservers",
|
|
271
|
+
"description",
|
|
272
|
+
name="Attributes",
|
|
273
|
+
),
|
|
274
|
+
FieldSet(
|
|
275
|
+
"record_templates",
|
|
276
|
+
name="Record Templates",
|
|
277
|
+
),
|
|
278
|
+
FieldSet(
|
|
279
|
+
"registrar",
|
|
280
|
+
"registrant",
|
|
281
|
+
"admin_c",
|
|
282
|
+
"tech_c",
|
|
283
|
+
"billing_c",
|
|
284
|
+
name="Domain Registration",
|
|
285
|
+
),
|
|
286
|
+
FieldSet("tenant_group", "tenant", name="Tenancy"),
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
nullable_fields = (
|
|
290
|
+
"description",
|
|
291
|
+
"nameservers",
|
|
292
|
+
"record_templates",
|
|
293
|
+
"registrar",
|
|
294
|
+
"registrant",
|
|
295
|
+
"admin_c",
|
|
296
|
+
"tech_c",
|
|
297
|
+
"billing_c",
|
|
298
|
+
)
|
netbox_dns/graphql/__init__.py
CHANGED
|
@@ -5,6 +5,8 @@ from .schema import (
|
|
|
5
5
|
NetBoxDNSRegistrarQuery,
|
|
6
6
|
NetBoxDNSZoneQuery,
|
|
7
7
|
NetBoxDNSRecordQuery,
|
|
8
|
+
NetBoxDNSZoneTemplateQuery,
|
|
9
|
+
NetBoxDNSRecordTemplateQuery,
|
|
8
10
|
)
|
|
9
11
|
|
|
10
12
|
schema = [
|
|
@@ -14,4 +16,6 @@ schema = [
|
|
|
14
16
|
NetBoxDNSRecordQuery,
|
|
15
17
|
NetBoxDNSContactQuery,
|
|
16
18
|
NetBoxDNSRegistrarQuery,
|
|
19
|
+
NetBoxDNSZoneTemplateQuery,
|
|
20
|
+
NetBoxDNSRecordTemplateQuery,
|
|
17
21
|
]
|
netbox_dns/graphql/filters.py
CHANGED
|
@@ -2,7 +2,16 @@ import strawberry_django
|
|
|
2
2
|
|
|
3
3
|
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
|
4
4
|
|
|
5
|
-
from netbox_dns.models import
|
|
5
|
+
from netbox_dns.models import (
|
|
6
|
+
NameServer,
|
|
7
|
+
View,
|
|
8
|
+
Zone,
|
|
9
|
+
Record,
|
|
10
|
+
Contact,
|
|
11
|
+
Registrar,
|
|
12
|
+
ZoneTemplate,
|
|
13
|
+
RecordTemplate,
|
|
14
|
+
)
|
|
6
15
|
from netbox_dns.filtersets import (
|
|
7
16
|
NameServerFilterSet,
|
|
8
17
|
ViewFilterSet,
|
|
@@ -10,6 +19,8 @@ from netbox_dns.filtersets import (
|
|
|
10
19
|
RecordFilterSet,
|
|
11
20
|
ContactFilterSet,
|
|
12
21
|
RegistrarFilterSet,
|
|
22
|
+
ZoneTemplateFilterSet,
|
|
23
|
+
RecordTemplateFilterSet,
|
|
13
24
|
)
|
|
14
25
|
|
|
15
26
|
|
|
@@ -37,6 +48,18 @@ class NetBoxDNSRecordFilter(BaseFilterMixin):
|
|
|
37
48
|
ip_address: str | None
|
|
38
49
|
|
|
39
50
|
|
|
51
|
+
@strawberry_django.filter(ZoneTemplate, lookups=True)
|
|
52
|
+
@autotype_decorator(ZoneTemplateFilterSet)
|
|
53
|
+
class NetBoxDNSZoneTemplateFilter(BaseFilterMixin):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@strawberry_django.filter(RecordTemplate, lookups=True)
|
|
58
|
+
@autotype_decorator(RecordTemplateFilterSet)
|
|
59
|
+
class NetBoxDNSRecordTemplateFilter(BaseFilterMixin):
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
|
|
40
63
|
@strawberry_django.filter(Contact, lookups=True)
|
|
41
64
|
@autotype_decorator(ContactFilterSet)
|
|
42
65
|
class NetBoxDNSContactFilter(BaseFilterMixin):
|