netbox-plugin-dns 0.21.4__py3-none-any.whl → 1.4.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.
- netbox_dns/__init__.py +106 -41
- netbox_dns/api/field_serializers.py +25 -0
- netbox_dns/api/nested_serializers.py +95 -52
- netbox_dns/api/serializers.py +14 -296
- netbox_dns/api/serializers_/__init__.py +0 -0
- netbox_dns/api/serializers_/dnssec_key_template.py +69 -0
- netbox_dns/api/serializers_/dnssec_policy.py +165 -0
- netbox_dns/api/serializers_/nameserver.py +56 -0
- netbox_dns/api/serializers_/prefix.py +18 -0
- netbox_dns/api/serializers_/record.py +105 -0
- netbox_dns/api/serializers_/record_template.py +71 -0
- netbox_dns/api/serializers_/registrar.py +45 -0
- netbox_dns/api/serializers_/registration_contact.py +50 -0
- netbox_dns/api/serializers_/view.py +81 -0
- netbox_dns/api/serializers_/zone.py +247 -0
- netbox_dns/api/serializers_/zone_template.py +157 -0
- netbox_dns/api/urls.py +13 -2
- netbox_dns/api/views.py +96 -58
- netbox_dns/choices/__init__.py +4 -0
- netbox_dns/choices/dnssec_key_template.py +67 -0
- netbox_dns/choices/dnssec_policy.py +40 -0
- netbox_dns/choices/record.py +104 -0
- netbox_dns/choices/utilities.py +4 -0
- netbox_dns/choices/zone.py +119 -0
- netbox_dns/fields/__init__.py +4 -0
- netbox_dns/fields/address.py +22 -16
- netbox_dns/fields/choice_array.py +33 -0
- netbox_dns/fields/ipam.py +15 -0
- netbox_dns/fields/network.py +42 -18
- netbox_dns/fields/rfc2317.py +97 -0
- netbox_dns/fields/timeperiod.py +33 -0
- netbox_dns/filters.py +7 -0
- netbox_dns/filtersets/__init__.py +12 -0
- netbox_dns/filtersets/dnssec_key_template.py +57 -0
- netbox_dns/filtersets/dnssec_policy.py +101 -0
- netbox_dns/filtersets/nameserver.py +46 -0
- netbox_dns/filtersets/record.py +135 -0
- netbox_dns/filtersets/record_template.py +59 -0
- netbox_dns/{filters → filtersets}/registrar.py +8 -1
- netbox_dns/{filters/contact.py → filtersets/registration_contact.py} +9 -3
- netbox_dns/filtersets/view.py +45 -0
- netbox_dns/filtersets/zone.py +254 -0
- netbox_dns/filtersets/zone_template.py +165 -0
- netbox_dns/forms/__init__.py +5 -1
- netbox_dns/forms/dnssec_key_template.py +250 -0
- netbox_dns/forms/dnssec_policy.py +654 -0
- netbox_dns/forms/nameserver.py +121 -27
- netbox_dns/forms/record.py +215 -104
- netbox_dns/forms/record_template.py +285 -0
- netbox_dns/forms/registrar.py +108 -31
- netbox_dns/forms/registration_contact.py +282 -0
- netbox_dns/forms/view.py +331 -20
- netbox_dns/forms/zone.py +769 -373
- netbox_dns/forms/zone_template.py +463 -0
- netbox_dns/graphql/__init__.py +25 -22
- netbox_dns/graphql/enums.py +41 -0
- netbox_dns/graphql/filter_lookups.py +13 -0
- netbox_dns/graphql/filters/__init__.py +12 -0
- netbox_dns/graphql/filters/dnssec_key_template.py +63 -0
- netbox_dns/graphql/filters/dnssec_policy.py +124 -0
- netbox_dns/graphql/filters/nameserver.py +32 -0
- netbox_dns/graphql/filters/record.py +89 -0
- netbox_dns/graphql/filters/record_template.py +55 -0
- netbox_dns/graphql/filters/registrar.py +30 -0
- netbox_dns/graphql/filters/registration_contact.py +27 -0
- netbox_dns/graphql/filters/view.py +28 -0
- netbox_dns/graphql/filters/zone.py +147 -0
- netbox_dns/graphql/filters/zone_template.py +97 -0
- netbox_dns/graphql/schema.py +89 -7
- netbox_dns/graphql/types.py +355 -0
- netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
- netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
- netbox_dns/management/commands/cleanup_database.py +175 -156
- netbox_dns/management/commands/cleanup_rrset_ttl.py +64 -0
- netbox_dns/management/commands/rebuild_dnssync.py +23 -0
- netbox_dns/management/commands/setup_dnssync.py +140 -0
- netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -27
- netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +557 -0
- netbox_dns/migrations/{0013_add_nameserver_zone_record_description.py → 0002_contact_description_registrar_description.py} +4 -9
- netbox_dns/migrations/0003_default_view.py +15 -0
- netbox_dns/migrations/0004_create_and_assign_default_view.py +26 -0
- netbox_dns/migrations/0005_alter_zone_view_not_null.py +18 -0
- netbox_dns/migrations/0006_templating.py +172 -0
- netbox_dns/migrations/0007_alter_ordering_options.py +25 -0
- netbox_dns/migrations/0008_view_prefixes.py +18 -0
- netbox_dns/migrations/0009_rename_contact_registrationcontact.py +36 -0
- netbox_dns/migrations/0010_view_ip_address_filter.py +18 -0
- netbox_dns/migrations/0011_rename_related_fields.py +63 -0
- netbox_dns/migrations/0012_natural_ordering.py +88 -0
- netbox_dns/migrations/0013_zonetemplate_soa_mname_zonetemplate_soa_rname.py +30 -0
- netbox_dns/migrations/0014_alter_unique_constraints_lowercase.py +42 -0
- netbox_dns/migrations/0015_dnssec.py +168 -0
- netbox_dns/migrations/{0015_add_record_status.py → 0016_dnssec_policy_status.py} +5 -4
- netbox_dns/migrations/0017_dnssec_policy_zone_zone_template.py +41 -0
- netbox_dns/migrations/0018_zone_domain_status_zone_expiration_date.py +23 -0
- netbox_dns/migrations/0019_dnssecpolicy_parental_agents.py +25 -0
- netbox_dns/migrations/0020_netbox_3_4.py +1 -1
- netbox_dns/migrations/0020_remove_dnssecpolicy_parental_agents_and_more.py +29 -0
- netbox_dns/migrations/0021_alter_record_ptr_record.py +25 -0
- netbox_dns/migrations/0021_record_ip_address.py +1 -1
- netbox_dns/migrations/0022_alter_record_ipam_ip_address.py +26 -0
- netbox_dns/migrations/0023_disable_ptr_false.py +27 -0
- netbox_dns/migrations/0024_zonetemplate_parental_agents.py +25 -0
- netbox_dns/migrations/0025_remove_zone_inline_signing_and_more.py +22 -0
- netbox_dns/migrations/0026_alter_dnssecpolicy_nsec3_opt_out.py +18 -0
- netbox_dns/migrations/0026_domain_registration.py +1 -1
- netbox_dns/migrations/0027_zone_comments.py +18 -0
- netbox_dns/migrations/0028_alter_zone_default_ttl_alter_zone_soa_minimum_and_more.py +54 -0
- netbox_dns/migrations/0028_rfc2317_fields.py +44 -0
- netbox_dns/migrations/0029_alter_registrationcontact_street.py +18 -0
- netbox_dns/migrations/0029_record_fqdn.py +30 -0
- netbox_dns/mixins/__init__.py +1 -0
- netbox_dns/mixins/object_modification.py +57 -0
- netbox_dns/models/__init__.py +5 -1
- netbox_dns/models/dnssec_key_template.py +114 -0
- netbox_dns/models/dnssec_policy.py +203 -0
- netbox_dns/models/nameserver.py +61 -30
- netbox_dns/models/record.py +781 -234
- netbox_dns/models/record_template.py +198 -0
- netbox_dns/models/registrar.py +34 -15
- netbox_dns/models/{contact.py → registration_contact.py} +72 -43
- netbox_dns/models/view.py +129 -9
- netbox_dns/models/zone.py +806 -242
- netbox_dns/models/zone_template.py +209 -0
- netbox_dns/navigation.py +176 -76
- netbox_dns/signals/__init__.py +0 -0
- netbox_dns/signals/dnssec.py +32 -0
- netbox_dns/signals/ipam_dnssync.py +216 -0
- netbox_dns/tables/__init__.py +5 -1
- netbox_dns/tables/dnssec_key_template.py +49 -0
- netbox_dns/tables/dnssec_policy.py +140 -0
- netbox_dns/tables/ipam_dnssync.py +12 -0
- netbox_dns/tables/nameserver.py +14 -17
- netbox_dns/tables/record.py +117 -59
- netbox_dns/tables/record_template.py +91 -0
- netbox_dns/tables/registrar.py +20 -10
- netbox_dns/tables/{contact.py → registration_contact.py} +22 -11
- netbox_dns/tables/view.py +47 -3
- netbox_dns/tables/zone.py +62 -31
- netbox_dns/tables/zone_template.py +78 -0
- netbox_dns/template_content.py +124 -38
- netbox_dns/templates/netbox_dns/dnsseckeytemplate.html +70 -0
- netbox_dns/templates/netbox_dns/dnssecpolicy.html +163 -0
- netbox_dns/templates/netbox_dns/nameserver.html +31 -28
- netbox_dns/templates/netbox_dns/record/managed.html +2 -1
- netbox_dns/templates/netbox_dns/record/related.html +17 -6
- netbox_dns/templates/netbox_dns/record.html +140 -93
- netbox_dns/templates/netbox_dns/recordtemplate.html +96 -0
- netbox_dns/templates/netbox_dns/registrar.html +41 -34
- netbox_dns/templates/netbox_dns/registrationcontact.html +76 -0
- netbox_dns/templates/netbox_dns/view/button.html +10 -0
- netbox_dns/templates/netbox_dns/view/prefix.html +44 -0
- netbox_dns/templates/netbox_dns/view/related.html +33 -0
- netbox_dns/templates/netbox_dns/view.html +62 -18
- netbox_dns/templates/netbox_dns/zone/base.html +6 -3
- netbox_dns/templates/netbox_dns/zone/child.html +6 -5
- netbox_dns/templates/netbox_dns/zone/child_zone.html +18 -0
- netbox_dns/templates/netbox_dns/zone/delegation_record.html +18 -0
- netbox_dns/templates/netbox_dns/zone/managed_record.html +1 -1
- netbox_dns/templates/netbox_dns/zone/record.html +6 -5
- netbox_dns/templates/netbox_dns/zone/registration.html +43 -24
- netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +18 -0
- netbox_dns/templates/netbox_dns/zone.html +178 -119
- netbox_dns/templates/netbox_dns/zonetemplate/child.html +46 -0
- netbox_dns/templates/netbox_dns/zonetemplate.html +124 -0
- netbox_dns/templatetags/netbox_dns.py +10 -0
- netbox_dns/urls.py +50 -210
- netbox_dns/utilities/__init__.py +3 -0
- netbox_dns/{utilities.py → utilities/conversions.py} +55 -7
- netbox_dns/utilities/dns.py +11 -0
- netbox_dns/utilities/ipam_dnssync.py +370 -0
- netbox_dns/validators/__init__.py +4 -0
- netbox_dns/validators/dns_name.py +116 -0
- netbox_dns/validators/dns_value.py +147 -0
- netbox_dns/validators/dnssec.py +148 -0
- netbox_dns/validators/rfc2317.py +28 -0
- netbox_dns/views/__init__.py +5 -1
- netbox_dns/views/dnssec_key_template.py +78 -0
- netbox_dns/views/dnssec_policy.py +146 -0
- netbox_dns/views/nameserver.py +34 -15
- netbox_dns/views/record.py +156 -15
- netbox_dns/views/record_template.py +93 -0
- netbox_dns/views/registrar.py +32 -13
- netbox_dns/views/registration_contact.py +101 -0
- netbox_dns/views/view.py +58 -14
- netbox_dns/views/zone.py +130 -33
- netbox_dns/views/zone_template.py +82 -0
- netbox_plugin_dns-1.4.7.dist-info/METADATA +132 -0
- netbox_plugin_dns-1.4.7.dist-info/RECORD +201 -0
- {netbox_plugin_dns-0.21.4.dist-info → netbox_plugin_dns-1.4.7.dist-info}/WHEEL +2 -1
- {netbox_plugin_dns-0.21.4.dist-info → netbox_plugin_dns-1.4.7.dist-info/licenses}/LICENSE +2 -1
- netbox_plugin_dns-1.4.7.dist-info/top_level.txt +1 -0
- netbox_dns/filters/__init__.py +0 -6
- netbox_dns/filters/nameserver.py +0 -18
- netbox_dns/filters/record.py +0 -53
- netbox_dns/filters/view.py +0 -18
- netbox_dns/filters/zone.py +0 -112
- netbox_dns/forms/contact.py +0 -211
- netbox_dns/graphql/contact.py +0 -19
- netbox_dns/graphql/nameserver.py +0 -19
- netbox_dns/graphql/record.py +0 -19
- netbox_dns/graphql/registrar.py +0 -19
- netbox_dns/graphql/view.py +0 -19
- netbox_dns/graphql/zone.py +0 -19
- netbox_dns/management/commands/setup_coupling.py +0 -75
- netbox_dns/management/commands/update_soa.py +0 -22
- netbox_dns/middleware.py +0 -226
- netbox_dns/migrations/0001_initial.py +0 -115
- netbox_dns/migrations/0002_zone_default_ttl.py +0 -18
- netbox_dns/migrations/0003_soa_managed_records.py +0 -112
- netbox_dns/migrations/0004_create_ptr_for_a_aaaa_records.py +0 -80
- netbox_dns/migrations/0005_update_ns_records.py +0 -41
- netbox_dns/migrations/0006_zone_soa_serial_auto.py +0 -29
- netbox_dns/migrations/0007_alter_zone_soa_serial_auto.py +0 -17
- netbox_dns/migrations/0008_zone_status_names.py +0 -21
- netbox_dns/migrations/0009_netbox32.py +0 -71
- netbox_dns/migrations/0010_update_soa_records.py +0 -58
- netbox_dns/migrations/0011_add_view_model.py +0 -70
- netbox_dns/migrations/0012_adjust_zone_and_record.py +0 -17
- netbox_dns/migrations/0014_add_view_description.py +0 -16
- netbox_dns/migrations/0016_cleanup_ptr_records.py +0 -38
- netbox_dns/migrations/0017_alter_record_ttl.py +0 -17
- netbox_dns/migrations/0018_zone_arpa_network.py +0 -51
- netbox_dns/migrations/0019_update_ns_ttl.py +0 -19
- netbox_dns/templates/netbox_dns/contact.html +0 -71
- netbox_dns/templates/netbox_dns/related_dns_objects.html +0 -21
- netbox_dns/templatetags/view_helpers.py +0 -15
- netbox_dns/validators.py +0 -57
- netbox_dns/views/contact.py +0 -83
- netbox_plugin_dns-0.21.4.dist-info/METADATA +0 -101
- netbox_plugin_dns-0.21.4.dist-info/RECORD +0 -110
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
from django.utils.translation import gettext as _
|
|
2
|
+
from rest_framework import serializers
|
|
3
|
+
|
|
4
|
+
from netbox.api.serializers import NetBoxModelSerializer
|
|
5
|
+
from tenancy.api.serializers_.tenants import TenantSerializer
|
|
6
|
+
|
|
7
|
+
from netbox_dns.models import ZoneTemplate
|
|
8
|
+
from netbox_dns.api.nested_serializers import NestedRecordTemplateSerializer
|
|
9
|
+
|
|
10
|
+
from .nameserver import NameServerSerializer
|
|
11
|
+
from .registrar import RegistrarSerializer
|
|
12
|
+
from .registration_contact import RegistrationContactSerializer
|
|
13
|
+
from .dnssec_policy import DNSSECPolicySerializer
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = ("ZoneTemplateSerializer",)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ZoneTemplateSerializer(NetBoxModelSerializer):
|
|
20
|
+
class Meta:
|
|
21
|
+
model = ZoneTemplate
|
|
22
|
+
|
|
23
|
+
fields = (
|
|
24
|
+
"id",
|
|
25
|
+
"url",
|
|
26
|
+
"name",
|
|
27
|
+
"description",
|
|
28
|
+
"tags",
|
|
29
|
+
"display",
|
|
30
|
+
"display_url",
|
|
31
|
+
"nameservers",
|
|
32
|
+
"soa_mname",
|
|
33
|
+
"soa_rname",
|
|
34
|
+
"dnssec_policy",
|
|
35
|
+
"parental_agents",
|
|
36
|
+
"registrar",
|
|
37
|
+
"registrant",
|
|
38
|
+
"tech_c",
|
|
39
|
+
"admin_c",
|
|
40
|
+
"billing_c",
|
|
41
|
+
"active",
|
|
42
|
+
"created",
|
|
43
|
+
"last_updated",
|
|
44
|
+
"custom_fields",
|
|
45
|
+
"tenant",
|
|
46
|
+
"record_templates",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
brief_fields = (
|
|
50
|
+
"id",
|
|
51
|
+
"url",
|
|
52
|
+
"name",
|
|
53
|
+
"display",
|
|
54
|
+
"description",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
url = serializers.HyperlinkedIdentityField(
|
|
58
|
+
view_name="plugins-api:netbox_dns-api:zonetemplate-detail"
|
|
59
|
+
)
|
|
60
|
+
nameservers = NameServerSerializer(
|
|
61
|
+
nested=True,
|
|
62
|
+
many=True,
|
|
63
|
+
read_only=False,
|
|
64
|
+
required=False,
|
|
65
|
+
help_text=_("Nameservers for the zone"),
|
|
66
|
+
)
|
|
67
|
+
soa_mname = NameServerSerializer(
|
|
68
|
+
nested=True,
|
|
69
|
+
many=False,
|
|
70
|
+
read_only=False,
|
|
71
|
+
required=False,
|
|
72
|
+
help_text=_("Primary nameserver for the zone"),
|
|
73
|
+
)
|
|
74
|
+
record_templates = NestedRecordTemplateSerializer(
|
|
75
|
+
many=True,
|
|
76
|
+
read_only=False,
|
|
77
|
+
required=False,
|
|
78
|
+
help_text=_("Record templates assigned to the zone template"),
|
|
79
|
+
)
|
|
80
|
+
dnssec_policy = DNSSECPolicySerializer(
|
|
81
|
+
nested=True,
|
|
82
|
+
many=False,
|
|
83
|
+
read_only=False,
|
|
84
|
+
required=False,
|
|
85
|
+
help_text=_("DNSSEC policy assigned to the zone template"),
|
|
86
|
+
)
|
|
87
|
+
registrar = RegistrarSerializer(
|
|
88
|
+
nested=True,
|
|
89
|
+
many=False,
|
|
90
|
+
read_only=False,
|
|
91
|
+
required=False,
|
|
92
|
+
help_text=_("Registrar the domain is registered with"),
|
|
93
|
+
)
|
|
94
|
+
registrant = RegistrationContactSerializer(
|
|
95
|
+
nested=True,
|
|
96
|
+
many=False,
|
|
97
|
+
read_only=False,
|
|
98
|
+
required=False,
|
|
99
|
+
help_text=_("Registrant of the domain"),
|
|
100
|
+
)
|
|
101
|
+
admin_c = RegistrationContactSerializer(
|
|
102
|
+
nested=True,
|
|
103
|
+
many=False,
|
|
104
|
+
read_only=False,
|
|
105
|
+
required=False,
|
|
106
|
+
help_text=_("Administrative contact for the domain"),
|
|
107
|
+
)
|
|
108
|
+
tech_c = RegistrationContactSerializer(
|
|
109
|
+
nested=True,
|
|
110
|
+
many=False,
|
|
111
|
+
read_only=False,
|
|
112
|
+
required=False,
|
|
113
|
+
help_text=_("Technical contact for the domain"),
|
|
114
|
+
)
|
|
115
|
+
billing_c = RegistrationContactSerializer(
|
|
116
|
+
nested=True,
|
|
117
|
+
many=False,
|
|
118
|
+
read_only=False,
|
|
119
|
+
required=False,
|
|
120
|
+
help_text=_("Billing contact for the domain"),
|
|
121
|
+
)
|
|
122
|
+
active = serializers.BooleanField(
|
|
123
|
+
required=False,
|
|
124
|
+
read_only=True,
|
|
125
|
+
allow_null=True,
|
|
126
|
+
)
|
|
127
|
+
tenant = TenantSerializer(
|
|
128
|
+
nested=True,
|
|
129
|
+
required=False,
|
|
130
|
+
allow_null=True,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
def create(self, validated_data):
|
|
134
|
+
nameservers = validated_data.pop("nameservers", None)
|
|
135
|
+
record_templates = validated_data.pop("record_templates", None)
|
|
136
|
+
|
|
137
|
+
zone_template = super().create(validated_data)
|
|
138
|
+
|
|
139
|
+
if nameservers is not None:
|
|
140
|
+
zone_template.nameservers.set(nameservers)
|
|
141
|
+
if record_templates is not None:
|
|
142
|
+
zone_template.record_templates.set(record_templates)
|
|
143
|
+
|
|
144
|
+
return zone_template
|
|
145
|
+
|
|
146
|
+
def update(self, instance, validated_data):
|
|
147
|
+
nameservers = validated_data.pop("nameservers", None)
|
|
148
|
+
record_templates = validated_data.pop("record_templates", None)
|
|
149
|
+
|
|
150
|
+
zone_template = super().update(instance, validated_data)
|
|
151
|
+
|
|
152
|
+
if nameservers is not None:
|
|
153
|
+
zone_template.nameservers.set(nameservers)
|
|
154
|
+
if record_templates is not None:
|
|
155
|
+
zone_template.record_templates.set(record_templates)
|
|
156
|
+
|
|
157
|
+
return zone_template
|
netbox_dns/api/urls.py
CHANGED
|
@@ -7,7 +7,12 @@ from netbox_dns.api.views import (
|
|
|
7
7
|
NameServerViewSet,
|
|
8
8
|
RecordViewSet,
|
|
9
9
|
RegistrarViewSet,
|
|
10
|
-
|
|
10
|
+
RegistrationContactViewSet,
|
|
11
|
+
ZoneTemplateViewSet,
|
|
12
|
+
RecordTemplateViewSet,
|
|
13
|
+
DNSSECKeyTemplateViewSet,
|
|
14
|
+
DNSSECPolicyViewSet,
|
|
15
|
+
PrefixViewSet,
|
|
11
16
|
)
|
|
12
17
|
|
|
13
18
|
router = NetBoxRouter()
|
|
@@ -18,6 +23,12 @@ router.register("zones", ZoneViewSet)
|
|
|
18
23
|
router.register("nameservers", NameServerViewSet)
|
|
19
24
|
router.register("records", RecordViewSet)
|
|
20
25
|
router.register("registrars", RegistrarViewSet)
|
|
21
|
-
router.register("contacts",
|
|
26
|
+
router.register("contacts", RegistrationContactViewSet)
|
|
27
|
+
router.register("zonetemplates", ZoneTemplateViewSet)
|
|
28
|
+
router.register("recordtemplates", RecordTemplateViewSet)
|
|
29
|
+
router.register("dnsseckeytemplates", DNSSECKeyTemplateViewSet)
|
|
30
|
+
router.register("dnssecpolicies", DNSSECPolicyViewSet)
|
|
31
|
+
|
|
32
|
+
router.register("prefixes", PrefixViewSet)
|
|
22
33
|
|
|
23
34
|
urlpatterns = router.urls
|
netbox_dns/api/views.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
from django.utils.translation import gettext as _
|
|
1
2
|
from rest_framework import serializers
|
|
2
|
-
from rest_framework.decorators import action
|
|
3
|
-
from rest_framework.response import Response
|
|
4
3
|
from rest_framework.routers import APIRootView
|
|
5
4
|
|
|
5
|
+
from ipam.models import Prefix
|
|
6
|
+
from ipam.filtersets import PrefixFilterSet
|
|
7
|
+
|
|
6
8
|
from netbox.api.viewsets import NetBoxModelViewSet
|
|
7
9
|
|
|
8
10
|
from netbox_dns.api.serializers import (
|
|
@@ -11,17 +13,37 @@ from netbox_dns.api.serializers import (
|
|
|
11
13
|
NameServerSerializer,
|
|
12
14
|
RecordSerializer,
|
|
13
15
|
RegistrarSerializer,
|
|
14
|
-
|
|
16
|
+
RegistrationContactSerializer,
|
|
17
|
+
ZoneTemplateSerializer,
|
|
18
|
+
RecordTemplateSerializer,
|
|
19
|
+
DNSSECKeyTemplateSerializer,
|
|
20
|
+
DNSSECPolicySerializer,
|
|
21
|
+
PrefixSerializer,
|
|
22
|
+
)
|
|
23
|
+
from netbox_dns.filtersets import (
|
|
24
|
+
ViewFilterSet,
|
|
25
|
+
ZoneFilterSet,
|
|
26
|
+
NameServerFilterSet,
|
|
27
|
+
RecordFilterSet,
|
|
28
|
+
RegistrarFilterSet,
|
|
29
|
+
RegistrationContactFilterSet,
|
|
30
|
+
ZoneTemplateFilterSet,
|
|
31
|
+
RecordTemplateFilterSet,
|
|
32
|
+
DNSSECKeyTemplateFilterSet,
|
|
33
|
+
DNSSECPolicyFilterSet,
|
|
15
34
|
)
|
|
16
|
-
from netbox_dns.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
35
|
+
from netbox_dns.models import (
|
|
36
|
+
View,
|
|
37
|
+
Zone,
|
|
38
|
+
NameServer,
|
|
39
|
+
Record,
|
|
40
|
+
Registrar,
|
|
41
|
+
RegistrationContact,
|
|
42
|
+
ZoneTemplate,
|
|
43
|
+
RecordTemplate,
|
|
44
|
+
DNSSECKeyTemplate,
|
|
45
|
+
DNSSECPolicy,
|
|
23
46
|
)
|
|
24
|
-
from netbox_dns.models import View, Zone, NameServer, Record, Registrar, Contact
|
|
25
47
|
|
|
26
48
|
|
|
27
49
|
class NetBoxDNSRootView(APIRootView):
|
|
@@ -32,64 +54,41 @@ class NetBoxDNSRootView(APIRootView):
|
|
|
32
54
|
class ViewViewSet(NetBoxModelViewSet):
|
|
33
55
|
queryset = View.objects.all()
|
|
34
56
|
serializer_class = ViewSerializer
|
|
35
|
-
filterset_class =
|
|
36
|
-
|
|
37
|
-
@action(detail=True, methods=["get"])
|
|
38
|
-
def views(self, request, pk=None):
|
|
39
|
-
views = View.objects.filter(zone=pk)
|
|
40
|
-
serializer = ViewSerializer(views, many=True, context={"request": request})
|
|
41
|
-
return Response(serializer.data)
|
|
57
|
+
filterset_class = ViewFilterSet
|
|
42
58
|
|
|
43
59
|
|
|
44
60
|
class ZoneViewSet(NetBoxModelViewSet):
|
|
45
|
-
queryset = Zone.objects.prefetch_related(
|
|
46
|
-
"view",
|
|
47
|
-
"nameservers",
|
|
48
|
-
"tags",
|
|
49
|
-
"soa_mname",
|
|
50
|
-
"record_set",
|
|
51
|
-
"tenant",
|
|
52
|
-
)
|
|
61
|
+
queryset = Zone.objects.prefetch_related("view", "nameservers", "soa_mname")
|
|
53
62
|
serializer_class = ZoneSerializer
|
|
54
|
-
filterset_class =
|
|
55
|
-
|
|
56
|
-
@action(detail=True, methods=["get"])
|
|
57
|
-
def records(self, request, pk=None):
|
|
58
|
-
records = Record.objects.filter(zone=pk)
|
|
59
|
-
serializer = RecordSerializer(records, many=True, context={"request": request})
|
|
60
|
-
return Response(serializer.data)
|
|
61
|
-
|
|
62
|
-
@action(detail=True, methods=["get"])
|
|
63
|
-
def nameservers(self, request, pk=None):
|
|
64
|
-
nameservers = NameServer.objects.filter(zones__id=pk)
|
|
65
|
-
serializer = NameServerSerializer(
|
|
66
|
-
nameservers, many=True, context={"request": request}
|
|
67
|
-
)
|
|
68
|
-
return Response(serializer.data)
|
|
63
|
+
filterset_class = ZoneFilterSet
|
|
69
64
|
|
|
70
65
|
|
|
71
66
|
class NameServerViewSet(NetBoxModelViewSet):
|
|
72
|
-
queryset = NameServer.objects.prefetch_related("zones"
|
|
67
|
+
queryset = NameServer.objects.prefetch_related("zones")
|
|
73
68
|
serializer_class = NameServerSerializer
|
|
74
|
-
filterset_class =
|
|
75
|
-
|
|
76
|
-
@action(detail=True, methods=["get"])
|
|
77
|
-
def zones(self, request, pk=None):
|
|
78
|
-
zones = Zone.objects.filter(nameservers__id=pk)
|
|
79
|
-
serializer = ZoneSerializer(zones, many=True, context={"request": request})
|
|
80
|
-
return Response(serializer.data)
|
|
69
|
+
filterset_class = NameServerFilterSet
|
|
81
70
|
|
|
82
71
|
|
|
83
72
|
class RecordViewSet(NetBoxModelViewSet):
|
|
84
|
-
queryset = Record.objects.
|
|
73
|
+
queryset = Record.objects.prefetch_related("zone", "zone__view")
|
|
85
74
|
serializer_class = RecordSerializer
|
|
86
|
-
filterset_class =
|
|
75
|
+
filterset_class = RecordFilterSet
|
|
76
|
+
|
|
77
|
+
def create(self, request, *args, **kwargs):
|
|
78
|
+
data = request.data
|
|
79
|
+
if not isinstance(data, list):
|
|
80
|
+
data = [data]
|
|
81
|
+
|
|
82
|
+
if any(record.get("managed") for record in data):
|
|
83
|
+
raise serializers.ValidationError(_("'managed' is True, refusing create"))
|
|
84
|
+
|
|
85
|
+
return super().create(request, *args, **kwargs)
|
|
87
86
|
|
|
88
87
|
def destroy(self, request, *args, **kwargs):
|
|
89
88
|
v_object = self.get_object()
|
|
90
89
|
if v_object.managed:
|
|
91
90
|
raise serializers.ValidationError(
|
|
92
|
-
|
|
91
|
+
_("{object} is managed, refusing deletion").format(object=v_object)
|
|
93
92
|
)
|
|
94
93
|
|
|
95
94
|
return super().destroy(request, *args, **kwargs)
|
|
@@ -97,7 +96,16 @@ class RecordViewSet(NetBoxModelViewSet):
|
|
|
97
96
|
def update(self, request, *args, **kwargs):
|
|
98
97
|
v_object = self.get_object()
|
|
99
98
|
if v_object.managed:
|
|
100
|
-
raise serializers.ValidationError(
|
|
99
|
+
raise serializers.ValidationError(
|
|
100
|
+
_("{object} is managed, refusing update").format(object=v_object)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
if request.data.get("managed"):
|
|
104
|
+
raise serializers.ValidationError(
|
|
105
|
+
_("{object} is unmanaged, refusing update to managed").format(
|
|
106
|
+
object=v_object
|
|
107
|
+
)
|
|
108
|
+
)
|
|
101
109
|
|
|
102
110
|
return super().update(request, *args, **kwargs)
|
|
103
111
|
|
|
@@ -105,10 +113,40 @@ class RecordViewSet(NetBoxModelViewSet):
|
|
|
105
113
|
class RegistrarViewSet(NetBoxModelViewSet):
|
|
106
114
|
queryset = Registrar.objects.all()
|
|
107
115
|
serializer_class = RegistrarSerializer
|
|
108
|
-
filterset_class =
|
|
116
|
+
filterset_class = RegistrarFilterSet
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class RegistrationContactViewSet(NetBoxModelViewSet):
|
|
120
|
+
queryset = RegistrationContact.objects.all()
|
|
121
|
+
serializer_class = RegistrationContactSerializer
|
|
122
|
+
filterset_class = RegistrationContactFilterSet
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class ZoneTemplateViewSet(NetBoxModelViewSet):
|
|
126
|
+
queryset = ZoneTemplate.objects.all()
|
|
127
|
+
serializer_class = ZoneTemplateSerializer
|
|
128
|
+
filterset_class = ZoneTemplateFilterSet
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class RecordTemplateViewSet(NetBoxModelViewSet):
|
|
132
|
+
queryset = RecordTemplate.objects.all()
|
|
133
|
+
serializer_class = RecordTemplateSerializer
|
|
134
|
+
filterset_class = RecordTemplateFilterSet
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class DNSSECKeyTemplateViewSet(NetBoxModelViewSet):
|
|
138
|
+
queryset = DNSSECKeyTemplate.objects.all()
|
|
139
|
+
serializer_class = DNSSECKeyTemplateSerializer
|
|
140
|
+
filterset_class = DNSSECKeyTemplateFilterSet
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class DNSSECPolicyViewSet(NetBoxModelViewSet):
|
|
144
|
+
queryset = DNSSECPolicy.objects.all()
|
|
145
|
+
serializer_class = DNSSECPolicySerializer
|
|
146
|
+
filterset_class = DNSSECPolicyFilterSet
|
|
109
147
|
|
|
110
148
|
|
|
111
|
-
class
|
|
112
|
-
queryset =
|
|
113
|
-
serializer_class =
|
|
114
|
-
filterset_class =
|
|
149
|
+
class PrefixViewSet(NetBoxModelViewSet):
|
|
150
|
+
queryset = Prefix.objects.all()
|
|
151
|
+
serializer_class = PrefixSerializer
|
|
152
|
+
filterset_class = PrefixFilterSet
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from dns.dnssectypes import Algorithm
|
|
2
|
+
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
4
|
+
|
|
5
|
+
from utilities.choices import ChoiceSet
|
|
6
|
+
|
|
7
|
+
from .utilities import initialize_choice_names
|
|
8
|
+
|
|
9
|
+
DEPRECATED_ALGORITHMS = (
|
|
10
|
+
Algorithm.RSAMD5,
|
|
11
|
+
Algorithm.DH,
|
|
12
|
+
Algorithm.DSA,
|
|
13
|
+
Algorithm.ECC,
|
|
14
|
+
Algorithm.RSASHA1,
|
|
15
|
+
Algorithm.DSANSEC3SHA1,
|
|
16
|
+
Algorithm.RSASHA1NSEC3SHA1,
|
|
17
|
+
Algorithm.RSASHA512,
|
|
18
|
+
Algorithm.ECCGOST,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = (
|
|
23
|
+
"DNSSECKeyTemplateTypeChoices",
|
|
24
|
+
"DNSSECKeyTemplateAlgorithmChoices",
|
|
25
|
+
"DNSSECKeyTemplateKeySizeChoices",
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DNSSECKeyTemplateTypeChoices(ChoiceSet):
|
|
30
|
+
TYPE_CSK = "CSK"
|
|
31
|
+
TYPE_KSK = "KSK"
|
|
32
|
+
TYPE_ZSK = "ZSK"
|
|
33
|
+
|
|
34
|
+
CHOICES = [
|
|
35
|
+
(TYPE_CSK, _("CSK"), "purple"),
|
|
36
|
+
(TYPE_KSK, _("KSK"), "blue"),
|
|
37
|
+
(TYPE_ZSK, _("ZSK"), "green"),
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class DNSSECKeyTemplateKeySizeChoices(ChoiceSet):
|
|
42
|
+
SIZE_512 = 512
|
|
43
|
+
SIZE_1024 = 1024
|
|
44
|
+
SIZE_2048 = 2048
|
|
45
|
+
SIZE_3072 = 3072
|
|
46
|
+
SIZE_4096 = 4096
|
|
47
|
+
|
|
48
|
+
CHOICES = [
|
|
49
|
+
(SIZE_512, 512),
|
|
50
|
+
(SIZE_1024, 1024),
|
|
51
|
+
(SIZE_2048, 2048),
|
|
52
|
+
(SIZE_3072, 3072),
|
|
53
|
+
(SIZE_4096, 4096),
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def as_enum(cls):
|
|
58
|
+
return super().as_enum(prefix="SIZE")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@initialize_choice_names
|
|
62
|
+
class DNSSECKeyTemplateAlgorithmChoices(ChoiceSet):
|
|
63
|
+
CHOICES = [
|
|
64
|
+
(algorithm.name, f"{algorithm.name} ({algorithm.value})")
|
|
65
|
+
for algorithm in sorted(Algorithm, key=lambda a: a.value)
|
|
66
|
+
if algorithm.value < 252 and algorithm not in DEPRECATED_ALGORITHMS
|
|
67
|
+
]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from dns.dnssectypes import DSDigest
|
|
2
|
+
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
4
|
+
|
|
5
|
+
from utilities.choices import ChoiceSet
|
|
6
|
+
|
|
7
|
+
from .utilities import initialize_choice_names
|
|
8
|
+
|
|
9
|
+
DEPRECATED_DIGESTS = (
|
|
10
|
+
DSDigest.NULL,
|
|
11
|
+
DSDigest.SHA1,
|
|
12
|
+
DSDigest.GOST,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = (
|
|
17
|
+
"DNSSECPolicyDigestChoices",
|
|
18
|
+
"DNSSECPolicyStatusChoices",
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@initialize_choice_names
|
|
23
|
+
class DNSSECPolicyDigestChoices(ChoiceSet):
|
|
24
|
+
CHOICES = [
|
|
25
|
+
(digest.name, digest.name)
|
|
26
|
+
for digest in sorted(DSDigest, key=lambda a: a.name)
|
|
27
|
+
if digest not in DEPRECATED_DIGESTS
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class DNSSECPolicyStatusChoices(ChoiceSet):
|
|
32
|
+
key = "DNSSECPolicy.status"
|
|
33
|
+
|
|
34
|
+
STATUS_ACTIVE = "active"
|
|
35
|
+
STATUS_INACTIVE = "inactive"
|
|
36
|
+
|
|
37
|
+
CHOICES = [
|
|
38
|
+
(STATUS_ACTIVE, _("Active"), "blue"),
|
|
39
|
+
(STATUS_INACTIVE, _("Inactive"), "red"),
|
|
40
|
+
]
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from dns import rdatatype, rdataclass
|
|
2
|
+
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
4
|
+
|
|
5
|
+
from utilities.choices import ChoiceSet
|
|
6
|
+
from netbox.plugins.utils import get_plugin_config
|
|
7
|
+
|
|
8
|
+
from .utilities import initialize_choice_names
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
__all__ = (
|
|
12
|
+
"RecordTypeChoices",
|
|
13
|
+
"RecordSelectableTypeChoices",
|
|
14
|
+
"RecordClassChoices",
|
|
15
|
+
"RecordStatusChoices",
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _get_config_option(option_name):
|
|
20
|
+
return list(
|
|
21
|
+
set(get_plugin_config("netbox_dns", option_name, []))
|
|
22
|
+
| set(get_plugin_config("netbox_dns", f"{option_name}+", []))
|
|
23
|
+
- set(get_plugin_config("netbox_dns", f"{option_name}-", []))
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class RecordTypeNames:
|
|
28
|
+
def __init__(self):
|
|
29
|
+
self.record_type_names = sorted(
|
|
30
|
+
[
|
|
31
|
+
rdtype.name
|
|
32
|
+
for rdtype in rdatatype.RdataType
|
|
33
|
+
if not rdatatype.is_metatype(rdtype)
|
|
34
|
+
]
|
|
35
|
+
+ _get_config_option("custom_record_types")
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def __iter__(self):
|
|
39
|
+
for rdtype_name in self.record_type_names:
|
|
40
|
+
yield rdtype_name
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class RecordSelectableTypeNames:
|
|
44
|
+
def __init__(self, exclude_types=[]):
|
|
45
|
+
self.record_type_names = sorted(
|
|
46
|
+
[
|
|
47
|
+
rdtype.name
|
|
48
|
+
for rdtype in rdatatype.RdataType
|
|
49
|
+
if not rdatatype.is_metatype(rdtype)
|
|
50
|
+
and rdtype.name not in _get_config_option("filter_record_types")
|
|
51
|
+
]
|
|
52
|
+
+ _get_config_option("custom_record_types")
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def __iter__(self):
|
|
56
|
+
for rdtype_name in self.record_type_names:
|
|
57
|
+
yield rdtype_name
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class RecordClassNames:
|
|
61
|
+
def __iter__(self):
|
|
62
|
+
for rdclass in rdataclass.RdataClass:
|
|
63
|
+
yield rdclass.name
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@initialize_choice_names
|
|
67
|
+
class RecordTypeChoices(ChoiceSet):
|
|
68
|
+
def choices():
|
|
69
|
+
return RecordTypeNames()
|
|
70
|
+
|
|
71
|
+
CHOICES = [(name, name) for name in choices()]
|
|
72
|
+
|
|
73
|
+
SINGLETONS = [
|
|
74
|
+
rdtype.name for rdtype in rdatatype.RdataType if rdatatype.is_singleton(rdtype)
|
|
75
|
+
]
|
|
76
|
+
CUSTOM_TYPES = _get_config_option("custom_record_types")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@initialize_choice_names
|
|
80
|
+
class RecordSelectableTypeChoices(ChoiceSet):
|
|
81
|
+
def choices():
|
|
82
|
+
return RecordSelectableTypeNames()
|
|
83
|
+
|
|
84
|
+
CHOICES = [(name, name) for name in choices()]
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@initialize_choice_names
|
|
88
|
+
class RecordClassChoices(ChoiceSet):
|
|
89
|
+
def choices():
|
|
90
|
+
return RecordClassNames()
|
|
91
|
+
|
|
92
|
+
CHOICES = [(name, name) for name in choices()]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class RecordStatusChoices(ChoiceSet):
|
|
96
|
+
key = "Record.status"
|
|
97
|
+
|
|
98
|
+
STATUS_ACTIVE = "active"
|
|
99
|
+
STATUS_INACTIVE = "inactive"
|
|
100
|
+
|
|
101
|
+
CHOICES = [
|
|
102
|
+
(STATUS_ACTIVE, _("Active"), "blue"),
|
|
103
|
+
(STATUS_INACTIVE, _("Inactive"), "red"),
|
|
104
|
+
]
|