netbox-plugin-dns 1.0.3__py3-none-any.whl → 1.0.5__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 +57 -0
- netbox_dns/api/serializers_/registrar.py +3 -0
- netbox_dns/api/serializers_/view.py +3 -0
- netbox_dns/api/serializers_/zone.py +30 -6
- netbox_dns/api/serializers_/zone_template.py +129 -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 +3 -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 +8 -0
- netbox_dns/forms/record.py +25 -11
- 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 +109 -36
- 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 +73 -5
- 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 +3 -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 +10 -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 +57 -66
- netbox_dns/models/zone_template.py +149 -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 +11 -0
- netbox_dns/views/nameserver.py +12 -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.3.dist-info → netbox_plugin_dns-1.0.5.dist-info}/METADATA +2 -1
- netbox_plugin_dns-1.0.5.dist-info/RECORD +136 -0
- netbox_plugin_dns-1.0.3.dist-info/RECORD +0 -115
- {netbox_plugin_dns-1.0.3.dist-info → netbox_plugin_dns-1.0.5.dist-info}/LICENSE +0 -0
- {netbox_plugin_dns-1.0.3.dist-info → netbox_plugin_dns-1.0.5.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,107 @@ 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
|
+
zone_data.pop("template", None)
|
|
85
|
+
zone_data.pop("tenant_group", None)
|
|
86
|
+
zone_data.pop("_init_time", None)
|
|
87
|
+
|
|
88
|
+
nameservers = zone_data.pop("nameservers")
|
|
89
|
+
tags = zone_data.pop("tags")
|
|
90
|
+
|
|
91
|
+
zone = Zone.objects.create(**zone_data)
|
|
92
|
+
|
|
93
|
+
zone.nameservers.set(nameservers)
|
|
94
|
+
zone.tags.set(tags)
|
|
95
|
+
|
|
96
|
+
template.create_records(zone)
|
|
97
|
+
raise RollbackTransaction
|
|
98
|
+
|
|
99
|
+
except ValidationError as exc:
|
|
100
|
+
if isinstance(exc, dict):
|
|
101
|
+
template_error = item.value()
|
|
102
|
+
else:
|
|
103
|
+
template_error = [exc]
|
|
104
|
+
except RollbackTransaction:
|
|
105
|
+
pass
|
|
106
|
+
|
|
107
|
+
events_queue.set(saved_events_queue)
|
|
108
|
+
if template_error is not None:
|
|
109
|
+
raise ValidationError({"template": template_error})
|
|
110
|
+
|
|
111
|
+
return self.cleaned_data
|
|
112
|
+
|
|
113
|
+
def save(self, *args, **kwargs):
|
|
114
|
+
zone = super().save(*args, **kwargs)
|
|
115
|
+
|
|
116
|
+
if (template := self.cleaned_data.get("template")) is not None:
|
|
117
|
+
template.create_records(zone)
|
|
118
|
+
|
|
119
|
+
return zone
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class ZoneForm(ZoneTemplateUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
40
123
|
nameservers = DynamicModelMultipleChoiceField(
|
|
41
124
|
queryset=NameServer.objects.all(),
|
|
42
125
|
required=False,
|
|
@@ -104,11 +187,17 @@ class ZoneForm(TenancyForm, NetBoxModelForm):
|
|
|
104
187
|
help_text="IPv4 reverse zone for deletgating the RFC2317 PTR records is managed in NetBox DNS",
|
|
105
188
|
required=False,
|
|
106
189
|
)
|
|
190
|
+
template = DynamicModelChoiceField(
|
|
191
|
+
queryset=ZoneTemplate.objects.all(),
|
|
192
|
+
required=False,
|
|
193
|
+
label="Template",
|
|
194
|
+
)
|
|
107
195
|
|
|
108
196
|
fieldsets = (
|
|
109
197
|
FieldSet(
|
|
110
198
|
"view",
|
|
111
199
|
"name",
|
|
200
|
+
"template",
|
|
112
201
|
"status",
|
|
113
202
|
"nameservers",
|
|
114
203
|
"default_ttl",
|
|
@@ -206,6 +295,7 @@ class ZoneForm(TenancyForm, NetBoxModelForm):
|
|
|
206
295
|
"name",
|
|
207
296
|
"view",
|
|
208
297
|
"status",
|
|
298
|
+
"template",
|
|
209
299
|
"nameservers",
|
|
210
300
|
"default_ttl",
|
|
211
301
|
"description",
|
|
@@ -297,6 +387,7 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
297
387
|
soa_serial_auto = forms.NullBooleanField(
|
|
298
388
|
required=False,
|
|
299
389
|
label="Generate Serial",
|
|
390
|
+
widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
|
|
300
391
|
)
|
|
301
392
|
rfc2317_prefix = RFC2317NetworkFormField(
|
|
302
393
|
required=False,
|
|
@@ -305,6 +396,7 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
305
396
|
rfc2317_parent_managed = forms.NullBooleanField(
|
|
306
397
|
required=False,
|
|
307
398
|
label="Parent Managed",
|
|
399
|
+
widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
|
|
308
400
|
)
|
|
309
401
|
rfc2317_parent_zone_id = DynamicModelMultipleChoiceField(
|
|
310
402
|
queryset=Zone.objects.all(),
|
|
@@ -343,7 +435,7 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
343
435
|
tag = TagFilterField(Zone)
|
|
344
436
|
|
|
345
437
|
|
|
346
|
-
class ZoneImportForm(NetBoxModelImportForm):
|
|
438
|
+
class ZoneImportForm(ZoneTemplateUpdateMixin, NetBoxModelImportForm):
|
|
347
439
|
view = CSVModelChoiceField(
|
|
348
440
|
queryset=View.objects.all(),
|
|
349
441
|
required=False,
|
|
@@ -385,7 +477,7 @@ class ZoneImportForm(NetBoxModelImportForm):
|
|
|
385
477
|
required=False,
|
|
386
478
|
help_text="Mailbox of the zone's administrator",
|
|
387
479
|
)
|
|
388
|
-
soa_serial_auto = forms.
|
|
480
|
+
soa_serial_auto = forms.BooleanField(
|
|
389
481
|
required=False,
|
|
390
482
|
help_text="Generate the SOA serial",
|
|
391
483
|
)
|
|
@@ -473,6 +565,12 @@ class ZoneImportForm(NetBoxModelImportForm):
|
|
|
473
565
|
to_field_name="name",
|
|
474
566
|
help_text="Assigned tenant",
|
|
475
567
|
)
|
|
568
|
+
template = CSVModelChoiceField(
|
|
569
|
+
queryset=ZoneTemplate.objects.all(),
|
|
570
|
+
required=False,
|
|
571
|
+
to_field_name="name",
|
|
572
|
+
label="Template",
|
|
573
|
+
)
|
|
476
574
|
|
|
477
575
|
class Meta:
|
|
478
576
|
model = Zone
|
|
@@ -481,6 +579,7 @@ class ZoneImportForm(NetBoxModelImportForm):
|
|
|
481
579
|
"view",
|
|
482
580
|
"name",
|
|
483
581
|
"status",
|
|
582
|
+
"template",
|
|
484
583
|
"nameservers",
|
|
485
584
|
"default_ttl",
|
|
486
585
|
"description",
|
|
@@ -532,9 +631,6 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
532
631
|
queryset=View.objects.all(),
|
|
533
632
|
required=False,
|
|
534
633
|
label="View",
|
|
535
|
-
widget=APISelect(
|
|
536
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:view-list")}
|
|
537
|
-
),
|
|
538
634
|
)
|
|
539
635
|
status = forms.ChoiceField(
|
|
540
636
|
choices=add_blank_choice(ZoneStatusChoices),
|
|
@@ -559,11 +655,6 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
559
655
|
queryset=NameServer.objects.all(),
|
|
560
656
|
required=False,
|
|
561
657
|
label="SOA Primary Nameserver",
|
|
562
|
-
widget=APISelect(
|
|
563
|
-
attrs={
|
|
564
|
-
"data-url": reverse_lazy("plugins-api:netbox_dns-api:nameserver-list")
|
|
565
|
-
}
|
|
566
|
-
),
|
|
567
658
|
)
|
|
568
659
|
soa_rname = forms.CharField(
|
|
569
660
|
required=False,
|
|
@@ -614,11 +705,6 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
614
705
|
registrar = DynamicModelChoiceField(
|
|
615
706
|
queryset=Registrar.objects.all(),
|
|
616
707
|
required=False,
|
|
617
|
-
widget=APISelect(
|
|
618
|
-
attrs={
|
|
619
|
-
"data-url": reverse_lazy("plugins-api:netbox_dns-api:registrar-list")
|
|
620
|
-
}
|
|
621
|
-
),
|
|
622
708
|
)
|
|
623
709
|
registry_domain_id = forms.CharField(
|
|
624
710
|
required=False,
|
|
@@ -627,41 +713,26 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
627
713
|
registrant = DynamicModelChoiceField(
|
|
628
714
|
queryset=Contact.objects.all(),
|
|
629
715
|
required=False,
|
|
630
|
-
widget=APISelect(
|
|
631
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:contact-list")}
|
|
632
|
-
),
|
|
633
716
|
)
|
|
634
717
|
admin_c = DynamicModelChoiceField(
|
|
635
718
|
queryset=Contact.objects.all(),
|
|
636
719
|
required=False,
|
|
637
720
|
label="Administrative Contact",
|
|
638
|
-
widget=APISelect(
|
|
639
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:contact-list")}
|
|
640
|
-
),
|
|
641
721
|
)
|
|
642
722
|
tech_c = DynamicModelChoiceField(
|
|
643
723
|
queryset=Contact.objects.all(),
|
|
644
724
|
required=False,
|
|
645
725
|
label="Technical Contact",
|
|
646
|
-
widget=APISelect(
|
|
647
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:contact-list")}
|
|
648
|
-
),
|
|
649
726
|
)
|
|
650
727
|
billing_c = DynamicModelChoiceField(
|
|
651
728
|
queryset=Contact.objects.all(),
|
|
652
729
|
required=False,
|
|
653
730
|
label="Billing Contact",
|
|
654
|
-
widget=APISelect(
|
|
655
|
-
attrs={"data-url": reverse_lazy("plugins-api:netbox_dns-api:contact-list")}
|
|
656
|
-
),
|
|
657
731
|
)
|
|
658
|
-
tenant =
|
|
732
|
+
tenant = DynamicModelChoiceField(
|
|
659
733
|
queryset=Tenant.objects.all(),
|
|
660
734
|
required=False,
|
|
661
|
-
to_field_name="name",
|
|
662
|
-
help_text="Assigned tenant",
|
|
663
735
|
)
|
|
664
|
-
tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False)
|
|
665
736
|
|
|
666
737
|
model = Zone
|
|
667
738
|
|
|
@@ -705,6 +776,7 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
705
776
|
|
|
706
777
|
nullable_fields = (
|
|
707
778
|
"description",
|
|
779
|
+
"nameservers",
|
|
708
780
|
"rfc2317_prefix",
|
|
709
781
|
"registrar",
|
|
710
782
|
"registry_domain_id",
|
|
@@ -712,4 +784,5 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
712
784
|
"admin_c",
|
|
713
785
|
"tech_c",
|
|
714
786
|
"billing_c",
|
|
787
|
+
"tenant",
|
|
715
788
|
)
|
|
@@ -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):
|
netbox_dns/graphql/schema.py
CHANGED
|
@@ -3,7 +3,16 @@ from typing import List
|
|
|
3
3
|
import strawberry
|
|
4
4
|
import strawberry_django
|
|
5
5
|
|
|
6
|
-
from netbox_dns.models import
|
|
6
|
+
from netbox_dns.models import (
|
|
7
|
+
NameServer,
|
|
8
|
+
View,
|
|
9
|
+
Zone,
|
|
10
|
+
Record,
|
|
11
|
+
Contact,
|
|
12
|
+
Registrar,
|
|
13
|
+
ZoneTemplate,
|
|
14
|
+
RecordTemplate,
|
|
15
|
+
)
|
|
7
16
|
from .types import (
|
|
8
17
|
NetBoxDNSNameServerType,
|
|
9
18
|
NetBoxDNSViewType,
|
|
@@ -11,6 +20,8 @@ from .types import (
|
|
|
11
20
|
NetBoxDNSRecordType,
|
|
12
21
|
NetBoxDNSContactType,
|
|
13
22
|
NetBoxDNSRegistrarType,
|
|
23
|
+
NetBoxDNSZoneTemplateType,
|
|
24
|
+
NetBoxDNSRecordTemplateType,
|
|
14
25
|
)
|
|
15
26
|
|
|
16
27
|
|
|
@@ -68,3 +79,25 @@ class NetBoxDNSRegistrarQuery:
|
|
|
68
79
|
return Registrar.objects.get(pk=id)
|
|
69
80
|
|
|
70
81
|
netbox_dns_registrar_list: List[NetBoxDNSRegistrarType] = strawberry_django.field()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@strawberry.type
|
|
85
|
+
class NetBoxDNSZoneTemplateQuery:
|
|
86
|
+
@strawberry.field
|
|
87
|
+
def netbox_dns_zone_template(self, id: int) -> NetBoxDNSZoneTemplateType:
|
|
88
|
+
return ZoneTemplate.objects.get(pk=id)
|
|
89
|
+
|
|
90
|
+
netbox_dns_zone_template_list: List[NetBoxDNSZoneTemplateType] = (
|
|
91
|
+
strawberry_django.field()
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@strawberry.type
|
|
96
|
+
class NetBoxDNSRecordTemplateQuery:
|
|
97
|
+
@strawberry.field
|
|
98
|
+
def netbox_dns_record_template(self, id: int) -> NetBoxDNSRecordTemplateType:
|
|
99
|
+
return RecordTemplate.objects.get(pk=id)
|
|
100
|
+
|
|
101
|
+
netbox_dns_record_template_list: List[NetBoxDNSRecordTemplateType] = (
|
|
102
|
+
strawberry_django.field()
|
|
103
|
+
)
|