netbox-plugin-dns 1.2.6__py3-none-any.whl → 1.2.7b2__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 +15 -1
- netbox_dns/api/serializers.py +3 -0
- netbox_dns/api/serializers_/dnssec_key_template.py +46 -0
- netbox_dns/api/serializers_/dnssec_policy.py +83 -0
- netbox_dns/api/serializers_/zone.py +10 -0
- netbox_dns/api/serializers_/zone_template.py +13 -4
- netbox_dns/api/urls.py +4 -0
- netbox_dns/api/views.py +18 -0
- netbox_dns/choices/__init__.py +2 -0
- netbox_dns/choices/dnssec_key_template.py +63 -0
- netbox_dns/choices/dnssec_policy.py +40 -0
- netbox_dns/choices/record.py +2 -25
- netbox_dns/choices/utilities.py +26 -0
- netbox_dns/fields/__init__.py +1 -0
- netbox_dns/fields/choice_array.py +20 -0
- netbox_dns/filtersets/__init__.py +3 -0
- netbox_dns/filtersets/dnssec_key_template.py +51 -0
- netbox_dns/filtersets/dnssec_policy.py +73 -0
- netbox_dns/filtersets/zone.py +23 -4
- netbox_dns/filtersets/zone_template.py +11 -0
- netbox_dns/forms/__init__.py +2 -0
- netbox_dns/forms/dnssec_key_template.py +188 -0
- netbox_dns/forms/dnssec_policy.py +563 -0
- netbox_dns/forms/zone.py +48 -0
- netbox_dns/forms/zone_template.py +29 -0
- netbox_dns/graphql/__init__.py +7 -3
- netbox_dns/graphql/filters.py +16 -0
- netbox_dns/graphql/schema.py +20 -0
- netbox_dns/graphql/types.py +67 -3
- netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
- netbox_dns/migrations/0015_dnssec.py +168 -0
- netbox_dns/migrations/0016_dnssec_policy_status.py +18 -0
- netbox_dns/migrations/0017_dnssec_policy_zone_zone_template.py +41 -0
- netbox_dns/models/__init__.py +2 -0
- netbox_dns/models/dnssec_key_template.py +114 -0
- netbox_dns/models/dnssec_policy.py +201 -0
- netbox_dns/models/zone.py +29 -16
- netbox_dns/models/zone_template.py +16 -6
- netbox_dns/navigation.py +49 -0
- netbox_dns/signals/dnssec.py +32 -0
- netbox_dns/tables/__init__.py +2 -0
- netbox_dns/tables/dnssec_key_template.py +48 -0
- netbox_dns/tables/dnssec_policy.py +131 -0
- netbox_dns/tables/zone.py +17 -1
- netbox_dns/tables/zone_template.py +4 -0
- netbox_dns/templates/netbox_dns/dnsseckeytemplate.html +70 -0
- netbox_dns/templates/netbox_dns/dnssecpolicy.html +155 -0
- netbox_dns/templates/netbox_dns/zone.html +16 -0
- netbox_dns/templates/netbox_dns/zonetemplate/child.html +46 -0
- netbox_dns/templates/netbox_dns/zonetemplate.html +12 -0
- netbox_dns/urls.py +16 -0
- netbox_dns/validators/__init__.py +1 -0
- netbox_dns/validators/dnssec.py +146 -0
- netbox_dns/views/__init__.py +2 -0
- netbox_dns/views/dnssec_key_template.py +87 -0
- netbox_dns/views/dnssec_policy.py +153 -0
- {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7b2.dist-info}/METADATA +2 -2
- {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7b2.dist-info}/RECORD +62 -38
- {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7b2.dist-info}/LICENSE +0 -0
- {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7b2.dist-info}/WHEEL +0 -0
- {netbox_plugin_dns-1.2.6.dist-info → netbox_plugin_dns-1.2.7b2.dist-info}/top_level.txt +0 -0
|
@@ -27,6 +27,7 @@ from netbox_dns.models import (
|
|
|
27
27
|
NameServer,
|
|
28
28
|
Registrar,
|
|
29
29
|
RegistrationContact,
|
|
30
|
+
DNSSECPolicy,
|
|
30
31
|
)
|
|
31
32
|
|
|
32
33
|
|
|
@@ -62,6 +63,7 @@ class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
|
62
63
|
FieldSet("name", "description", "nameservers", name=_("Zone Template")),
|
|
63
64
|
FieldSet("soa_mname", "soa_rname", name=_("SOA")),
|
|
64
65
|
FieldSet("record_templates", name=_("Record Templates")),
|
|
66
|
+
FieldSet("dnssec_policy", name=_("DNSSEC")),
|
|
65
67
|
FieldSet(
|
|
66
68
|
"registrar",
|
|
67
69
|
"registrant",
|
|
@@ -82,6 +84,7 @@ class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
|
82
84
|
"nameservers",
|
|
83
85
|
"soa_mname",
|
|
84
86
|
"soa_rname",
|
|
87
|
+
"dnssec_policy",
|
|
85
88
|
"record_templates",
|
|
86
89
|
"description",
|
|
87
90
|
"registrar",
|
|
@@ -105,6 +108,7 @@ class ZoneTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
105
108
|
FieldSet("name", "nameserver_id", "description", name=_("Attributes")),
|
|
106
109
|
FieldSet("soa_mname_id", "soa_rname", name=_("SOA")),
|
|
107
110
|
FieldSet("record_template_id", name=_("Record Templates")),
|
|
111
|
+
FieldSet("dnssec_policy", name=_("DNSSEC")),
|
|
108
112
|
FieldSet(
|
|
109
113
|
"registrar_id",
|
|
110
114
|
"registrant_id",
|
|
@@ -142,6 +146,11 @@ class ZoneTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
142
146
|
description = forms.CharField(
|
|
143
147
|
required=False,
|
|
144
148
|
)
|
|
149
|
+
dnssec_policy_id = DynamicModelMultipleChoiceField(
|
|
150
|
+
queryset=DNSSECPolicy.objects.all(),
|
|
151
|
+
required=False,
|
|
152
|
+
label=_("DNSSEC Policy ID"),
|
|
153
|
+
)
|
|
145
154
|
registrar_id = DynamicModelMultipleChoiceField(
|
|
146
155
|
queryset=Registrar.objects.all(),
|
|
147
156
|
required=False,
|
|
@@ -189,6 +198,15 @@ class ZoneTemplateImportForm(NetBoxModelImportForm):
|
|
|
189
198
|
required=False,
|
|
190
199
|
label=_("Record Templates"),
|
|
191
200
|
)
|
|
201
|
+
dnssec_policy = CSVModelChoiceField(
|
|
202
|
+
queryset=DNSSECPolicy.objects.all(),
|
|
203
|
+
required=False,
|
|
204
|
+
to_field_name="name",
|
|
205
|
+
error_messages={
|
|
206
|
+
"invalid_choice": _("DNSSEC policy %(value)s not found"),
|
|
207
|
+
},
|
|
208
|
+
label=_("DNSSEC Policy"),
|
|
209
|
+
)
|
|
192
210
|
registrar = CSVModelChoiceField(
|
|
193
211
|
queryset=Registrar.objects.all(),
|
|
194
212
|
required=False,
|
|
@@ -250,6 +268,7 @@ class ZoneTemplateImportForm(NetBoxModelImportForm):
|
|
|
250
268
|
"soa_mname",
|
|
251
269
|
"soa_rname",
|
|
252
270
|
"record_templates",
|
|
271
|
+
"dnssec_policy",
|
|
253
272
|
"description",
|
|
254
273
|
"registrar",
|
|
255
274
|
"registrant",
|
|
@@ -281,6 +300,11 @@ class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
281
300
|
description = forms.CharField(
|
|
282
301
|
max_length=200, required=False, label=_("Description")
|
|
283
302
|
)
|
|
303
|
+
dnssec_policy = DynamicModelChoiceField(
|
|
304
|
+
queryset=DNSSECPolicy.objects.all(),
|
|
305
|
+
required=False,
|
|
306
|
+
label=_("DNSSEC Policy"),
|
|
307
|
+
)
|
|
284
308
|
registrar = DynamicModelChoiceField(
|
|
285
309
|
queryset=Registrar.objects.all(),
|
|
286
310
|
required=False,
|
|
@@ -334,6 +358,10 @@ class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
334
358
|
"record_templates",
|
|
335
359
|
name=_("Record Templates"),
|
|
336
360
|
),
|
|
361
|
+
FieldSet(
|
|
362
|
+
"dnssec_policy",
|
|
363
|
+
name=_("DNSSEC"),
|
|
364
|
+
),
|
|
337
365
|
FieldSet(
|
|
338
366
|
"registrar",
|
|
339
367
|
"registrant",
|
|
@@ -351,6 +379,7 @@ class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
351
379
|
"soa_mname",
|
|
352
380
|
"soa_rname",
|
|
353
381
|
"record_templates",
|
|
382
|
+
"dnssec_policy",
|
|
354
383
|
"registrar",
|
|
355
384
|
"registrant",
|
|
356
385
|
"admin_c",
|
netbox_dns/graphql/__init__.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
from .schema import (
|
|
2
|
-
NetBoxDNSViewQuery,
|
|
3
2
|
NetBoxDNSNameServerQuery,
|
|
4
|
-
|
|
5
|
-
NetBoxDNSRegistrarQuery,
|
|
3
|
+
NetBoxDNSViewQuery,
|
|
6
4
|
NetBoxDNSZoneQuery,
|
|
7
5
|
NetBoxDNSRecordQuery,
|
|
6
|
+
NetBoxDNSDNSSECKeyTemplateQuery,
|
|
7
|
+
NetBoxDNSDNSSECPolicyQuery,
|
|
8
|
+
NetBoxDNSRegistrationContactQuery,
|
|
9
|
+
NetBoxDNSRegistrarQuery,
|
|
8
10
|
NetBoxDNSZoneTemplateQuery,
|
|
9
11
|
NetBoxDNSRecordTemplateQuery,
|
|
10
12
|
)
|
|
@@ -14,6 +16,8 @@ schema = [
|
|
|
14
16
|
NetBoxDNSViewQuery,
|
|
15
17
|
NetBoxDNSZoneQuery,
|
|
16
18
|
NetBoxDNSRecordQuery,
|
|
19
|
+
NetBoxDNSDNSSECKeyTemplateQuery,
|
|
20
|
+
NetBoxDNSDNSSECPolicyQuery,
|
|
17
21
|
NetBoxDNSRegistrationContactQuery,
|
|
18
22
|
NetBoxDNSRegistrarQuery,
|
|
19
23
|
NetBoxDNSZoneTemplateQuery,
|
netbox_dns/graphql/filters.py
CHANGED
|
@@ -7,6 +7,8 @@ from netbox_dns.models import (
|
|
|
7
7
|
View,
|
|
8
8
|
Zone,
|
|
9
9
|
Record,
|
|
10
|
+
DNSSECKeyTemplate,
|
|
11
|
+
DNSSECPolicy,
|
|
10
12
|
RegistrationContact,
|
|
11
13
|
Registrar,
|
|
12
14
|
ZoneTemplate,
|
|
@@ -17,6 +19,8 @@ from netbox_dns.filtersets import (
|
|
|
17
19
|
ViewFilterSet,
|
|
18
20
|
ZoneFilterSet,
|
|
19
21
|
RecordFilterSet,
|
|
22
|
+
DNSSECKeyTemplateFilterSet,
|
|
23
|
+
DNSSECPolicyFilterSet,
|
|
20
24
|
RegistrationContactFilterSet,
|
|
21
25
|
RegistrarFilterSet,
|
|
22
26
|
ZoneTemplateFilterSet,
|
|
@@ -48,6 +52,18 @@ class NetBoxDNSRecordFilter(BaseFilterMixin):
|
|
|
48
52
|
ip_address: str | None
|
|
49
53
|
|
|
50
54
|
|
|
55
|
+
@strawberry_django.filter(DNSSECKeyTemplate, lookups=True)
|
|
56
|
+
@autotype_decorator(DNSSECKeyTemplateFilterSet)
|
|
57
|
+
class NetBoxDNSDNSSECKeyTemplateFilter(BaseFilterMixin):
|
|
58
|
+
ip_address: str | None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@strawberry_django.filter(DNSSECPolicy, lookups=True)
|
|
62
|
+
@autotype_decorator(DNSSECPolicyFilterSet)
|
|
63
|
+
class NetBoxDNSDNSSECPolicyFilter(BaseFilterMixin):
|
|
64
|
+
ip_address: str | None
|
|
65
|
+
|
|
66
|
+
|
|
51
67
|
@strawberry_django.filter(ZoneTemplate, lookups=True)
|
|
52
68
|
@autotype_decorator(ZoneTemplateFilterSet)
|
|
53
69
|
class NetBoxDNSZoneTemplateFilter(BaseFilterMixin):
|
netbox_dns/graphql/schema.py
CHANGED
|
@@ -8,6 +8,8 @@ from .types import (
|
|
|
8
8
|
NetBoxDNSViewType,
|
|
9
9
|
NetBoxDNSZoneType,
|
|
10
10
|
NetBoxDNSRecordType,
|
|
11
|
+
NetBoxDNSDNSSECKeyTemplateType,
|
|
12
|
+
NetBoxDNSDNSSECPolicyType,
|
|
11
13
|
NetBoxDNSRegistrationContactType,
|
|
12
14
|
NetBoxDNSRegistrarType,
|
|
13
15
|
NetBoxDNSZoneTemplateType,
|
|
@@ -41,6 +43,24 @@ class NetBoxDNSRecordQuery:
|
|
|
41
43
|
netbox_dns_record_list: List[NetBoxDNSRecordType] = strawberry_django.field()
|
|
42
44
|
|
|
43
45
|
|
|
46
|
+
@strawberry.type(name="Query")
|
|
47
|
+
class NetBoxDNSDNSSECKeyTemplateQuery:
|
|
48
|
+
netbox_dns_dnssec_key_template: NetBoxDNSDNSSECKeyTemplateType = (
|
|
49
|
+
strawberry_django.field()
|
|
50
|
+
)
|
|
51
|
+
netbox_dns_dnssec_key_template_list: List[NetBoxDNSDNSSECKeyTemplateType] = (
|
|
52
|
+
strawberry_django.field()
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@strawberry.type(name="Query")
|
|
57
|
+
class NetBoxDNSDNSSECPolicyQuery:
|
|
58
|
+
netbox_dns_dnssec_policy: NetBoxDNSDNSSECPolicyType = strawberry_django.field()
|
|
59
|
+
netbox_dns_dnssec_policy_list: List[NetBoxDNSDNSSECPolicyType] = (
|
|
60
|
+
strawberry_django.field()
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
44
64
|
@strawberry.type(name="Query")
|
|
45
65
|
class NetBoxDNSRegistrationContactQuery:
|
|
46
66
|
netbox_dns_registration_contact: NetBoxDNSRegistrationContactType = (
|
netbox_dns/graphql/types.py
CHANGED
|
@@ -13,6 +13,8 @@ from netbox_dns.models import (
|
|
|
13
13
|
View,
|
|
14
14
|
Zone,
|
|
15
15
|
Record,
|
|
16
|
+
DNSSECKeyTemplate,
|
|
17
|
+
DNSSECPolicy,
|
|
16
18
|
RegistrationContact,
|
|
17
19
|
Registrar,
|
|
18
20
|
ZoneTemplate,
|
|
@@ -23,6 +25,8 @@ from .filters import (
|
|
|
23
25
|
NetBoxDNSViewFilter,
|
|
24
26
|
NetBoxDNSZoneFilter,
|
|
25
27
|
NetBoxDNSRecordFilter,
|
|
28
|
+
NetBoxDNSDNSSECKeyTemplateFilter,
|
|
29
|
+
NetBoxDNSDNSSECPolicyFilter,
|
|
26
30
|
NetBoxDNSRegistrationContactFilter,
|
|
27
31
|
NetBoxDNSRegistrarFilter,
|
|
28
32
|
NetBoxDNSZoneTemplateFilter,
|
|
@@ -58,6 +62,7 @@ class NetBoxDNSViewType(NetBoxObjectType):
|
|
|
58
62
|
@strawberry_django.type(Zone, fields="__all__", filters=NetBoxDNSZoneFilter)
|
|
59
63
|
class NetBoxDNSZoneType(NetBoxObjectType):
|
|
60
64
|
name: str
|
|
65
|
+
description: str | None
|
|
61
66
|
status: str
|
|
62
67
|
active: bool
|
|
63
68
|
view: Annotated["NetBoxDNSViewType", strawberry.lazy("netbox_dns.graphql.types")]
|
|
@@ -78,9 +83,13 @@ class NetBoxDNSZoneType(NetBoxObjectType):
|
|
|
78
83
|
soa_expire: BigInt
|
|
79
84
|
soa_minimum: BigInt
|
|
80
85
|
soa_serial_auto: bool
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
86
|
+
dnssec_policy: (
|
|
87
|
+
Annotated[
|
|
88
|
+
"NetBoxDNSDNSSECPolicyType", strawberry.lazy("netbox_dns.graphql.types")
|
|
89
|
+
]
|
|
90
|
+
| None
|
|
91
|
+
)
|
|
92
|
+
inline_signing: bool
|
|
84
93
|
registrar: (
|
|
85
94
|
Annotated["NetBoxDNSRegistrarType", strawberry.lazy("netbox_dns.graphql.types")]
|
|
86
95
|
| None
|
|
@@ -126,6 +135,8 @@ class NetBoxDNSZoneType(NetBoxObjectType):
|
|
|
126
135
|
rfc2317_child_zones: List[
|
|
127
136
|
Annotated["NetBoxDNSRecordType", strawberry.lazy("netbox_dns.graphql.types")]
|
|
128
137
|
]
|
|
138
|
+
arpa_network: str | None
|
|
139
|
+
tenant: Annotated["TenantType", strawberry.lazy("tenancy.graphql.types")] | None
|
|
129
140
|
|
|
130
141
|
|
|
131
142
|
@strawberry_django.type(Record, fields="__all__", filters=NetBoxDNSRecordFilter)
|
|
@@ -162,6 +173,53 @@ class NetBoxDNSRecordType(NetBoxObjectType):
|
|
|
162
173
|
]
|
|
163
174
|
|
|
164
175
|
|
|
176
|
+
@strawberry_django.type(
|
|
177
|
+
DNSSECKeyTemplate, fields="__all__", filters=NetBoxDNSDNSSECKeyTemplateFilter
|
|
178
|
+
)
|
|
179
|
+
class NetBoxDNSDNSSECKeyTemplateType(NetBoxObjectType):
|
|
180
|
+
name: str
|
|
181
|
+
description: str
|
|
182
|
+
tenant: Annotated["TenantType", strawberry.lazy("tenancy.graphql.types")] | None
|
|
183
|
+
type: str
|
|
184
|
+
lifetime: BigInt | None
|
|
185
|
+
algorithm: str
|
|
186
|
+
key_size: BigInt | None
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@strawberry_django.type(
|
|
190
|
+
DNSSECPolicy, fields="__all__", filters=NetBoxDNSDNSSECPolicyFilter
|
|
191
|
+
)
|
|
192
|
+
class NetBoxDNSDNSSECPolicyType(NetBoxObjectType):
|
|
193
|
+
name: str
|
|
194
|
+
description: str | None
|
|
195
|
+
status: str
|
|
196
|
+
tenant: Annotated["TenantType", strawberry.lazy("tenancy.graphql.types")] | None
|
|
197
|
+
key_templates: List[
|
|
198
|
+
Annotated[
|
|
199
|
+
"NetBoxDNSDNSSECKeyTemplateType",
|
|
200
|
+
strawberry.lazy("netbox_dns.graphql.types"),
|
|
201
|
+
]
|
|
202
|
+
]
|
|
203
|
+
dnskey_ttl: BigInt | None
|
|
204
|
+
purge_keys: BigInt | None
|
|
205
|
+
publish_safety: BigInt | None
|
|
206
|
+
retire_safety: BigInt | None
|
|
207
|
+
signatures_jitter: BigInt | None
|
|
208
|
+
signatures_refresh: BigInt | None
|
|
209
|
+
signatures_validity: BigInt | None
|
|
210
|
+
signatures_validity_dnskey: BigInt | None
|
|
211
|
+
max_zone_ttl: BigInt | None
|
|
212
|
+
zone_propagation_delay: BigInt | None
|
|
213
|
+
create_cdnskey: bool
|
|
214
|
+
cds_digest_types: List[str]
|
|
215
|
+
parent_ds_ttl: BigInt | None
|
|
216
|
+
parent_propagation_delay: BigInt | None
|
|
217
|
+
use_nsec3: bool
|
|
218
|
+
nsec3_iterations: BigInt | None
|
|
219
|
+
nsec3_opt_out: bool
|
|
220
|
+
nsec3_salt_size: BigInt | None
|
|
221
|
+
|
|
222
|
+
|
|
165
223
|
@strawberry_django.type(
|
|
166
224
|
RegistrationContact, fields="__all__", filters=NetBoxDNSRegistrationContactFilter
|
|
167
225
|
)
|
|
@@ -226,6 +284,12 @@ class NetBoxDNSZoneTemplateType(NetBoxObjectType):
|
|
|
226
284
|
| None
|
|
227
285
|
)
|
|
228
286
|
soa_rname: str | None
|
|
287
|
+
dnssec_policy: (
|
|
288
|
+
Annotated[
|
|
289
|
+
"NetBoxDNSDNSSECPolicyType", strawberry.lazy("netbox_dns.graphql.types")
|
|
290
|
+
]
|
|
291
|
+
| None
|
|
292
|
+
)
|
|
229
293
|
record_templates: List[
|
|
230
294
|
Annotated[
|
|
231
295
|
"NetBoxDNSRecordTemplateType", strawberry.lazy("netbox_dns.graphql.types")
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Generated by Django 5.1.6 on 2025-03-04 12:09
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
import netbox_dns.fields.choice_array
|
|
5
|
+
import taggit.managers
|
|
6
|
+
import utilities.json
|
|
7
|
+
from django.db import migrations, models
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Migration(migrations.Migration):
|
|
11
|
+
|
|
12
|
+
dependencies = [
|
|
13
|
+
("extras", "0122_charfield_null_choices"),
|
|
14
|
+
("netbox_dns", "0014_alter_unique_constraints_lowercase"),
|
|
15
|
+
("tenancy", "0017_natural_ordering"),
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
operations = [
|
|
19
|
+
migrations.CreateModel(
|
|
20
|
+
name="DNSSECKeyTemplate",
|
|
21
|
+
fields=[
|
|
22
|
+
(
|
|
23
|
+
"id",
|
|
24
|
+
models.BigAutoField(
|
|
25
|
+
auto_created=True, primary_key=True, serialize=False
|
|
26
|
+
),
|
|
27
|
+
),
|
|
28
|
+
("created", models.DateTimeField(auto_now_add=True, null=True)),
|
|
29
|
+
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
|
30
|
+
(
|
|
31
|
+
"custom_field_data",
|
|
32
|
+
models.JSONField(
|
|
33
|
+
blank=True,
|
|
34
|
+
default=dict,
|
|
35
|
+
encoder=utilities.json.CustomFieldJSONEncoder,
|
|
36
|
+
),
|
|
37
|
+
),
|
|
38
|
+
("name", models.CharField(max_length=255)),
|
|
39
|
+
("description", models.CharField(blank=True, max_length=200)),
|
|
40
|
+
("type", models.CharField(max_length=3)),
|
|
41
|
+
("lifetime", models.PositiveIntegerField(blank=True, null=True)),
|
|
42
|
+
("algorithm", models.CharField()),
|
|
43
|
+
("key_size", models.PositiveIntegerField(blank=True, null=True)),
|
|
44
|
+
(
|
|
45
|
+
"tags",
|
|
46
|
+
taggit.managers.TaggableManager(
|
|
47
|
+
through="extras.TaggedItem", to="extras.Tag"
|
|
48
|
+
),
|
|
49
|
+
),
|
|
50
|
+
(
|
|
51
|
+
"tenant",
|
|
52
|
+
models.ForeignKey(
|
|
53
|
+
blank=True,
|
|
54
|
+
null=True,
|
|
55
|
+
on_delete=django.db.models.deletion.PROTECT,
|
|
56
|
+
related_name="netbox_dns_dnssec_key_templates",
|
|
57
|
+
to="tenancy.tenant",
|
|
58
|
+
),
|
|
59
|
+
),
|
|
60
|
+
],
|
|
61
|
+
options={
|
|
62
|
+
"verbose_name": "DNSSEC Key Template",
|
|
63
|
+
"verbose_name_plural": "DNSSEC Key Templates",
|
|
64
|
+
"ordering": ("name",),
|
|
65
|
+
"unique_together": {("name", "type")},
|
|
66
|
+
},
|
|
67
|
+
),
|
|
68
|
+
migrations.CreateModel(
|
|
69
|
+
name="DNSSECPolicy",
|
|
70
|
+
fields=[
|
|
71
|
+
(
|
|
72
|
+
"id",
|
|
73
|
+
models.BigAutoField(
|
|
74
|
+
auto_created=True, primary_key=True, serialize=False
|
|
75
|
+
),
|
|
76
|
+
),
|
|
77
|
+
("created", models.DateTimeField(auto_now_add=True, null=True)),
|
|
78
|
+
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
|
79
|
+
(
|
|
80
|
+
"custom_field_data",
|
|
81
|
+
models.JSONField(
|
|
82
|
+
blank=True,
|
|
83
|
+
default=dict,
|
|
84
|
+
encoder=utilities.json.CustomFieldJSONEncoder,
|
|
85
|
+
),
|
|
86
|
+
),
|
|
87
|
+
("name", models.CharField(max_length=255, unique=True)),
|
|
88
|
+
("description", models.CharField(blank=True, max_length=200)),
|
|
89
|
+
("dnskey_ttl", models.PositiveIntegerField(blank=True, null=True)),
|
|
90
|
+
("purge_keys", models.PositiveIntegerField(blank=True, null=True)),
|
|
91
|
+
("publish_safety", models.PositiveIntegerField(blank=True, null=True)),
|
|
92
|
+
("retire_safety", models.PositiveIntegerField(blank=True, null=True)),
|
|
93
|
+
(
|
|
94
|
+
"signatures_jitter",
|
|
95
|
+
models.PositiveIntegerField(blank=True, null=True),
|
|
96
|
+
),
|
|
97
|
+
(
|
|
98
|
+
"signatures_refresh",
|
|
99
|
+
models.PositiveIntegerField(blank=True, null=True),
|
|
100
|
+
),
|
|
101
|
+
(
|
|
102
|
+
"signatures_validity",
|
|
103
|
+
models.PositiveIntegerField(blank=True, null=True),
|
|
104
|
+
),
|
|
105
|
+
(
|
|
106
|
+
"signatures_validity_dnskey",
|
|
107
|
+
models.PositiveIntegerField(blank=True, null=True),
|
|
108
|
+
),
|
|
109
|
+
("max_zone_ttl", models.PositiveIntegerField(blank=True, null=True)),
|
|
110
|
+
(
|
|
111
|
+
"zone_propagation_delay",
|
|
112
|
+
models.PositiveIntegerField(blank=True, null=True),
|
|
113
|
+
),
|
|
114
|
+
("create_cdnskey", models.BooleanField(default=True)),
|
|
115
|
+
(
|
|
116
|
+
"cds_digest_types",
|
|
117
|
+
netbox_dns.fields.choice_array.ChoiceArrayField(
|
|
118
|
+
base_field=models.CharField(),
|
|
119
|
+
blank=True,
|
|
120
|
+
default=list,
|
|
121
|
+
null=True,
|
|
122
|
+
size=None,
|
|
123
|
+
),
|
|
124
|
+
),
|
|
125
|
+
("parent_ds_ttl", models.PositiveIntegerField(blank=True, null=True)),
|
|
126
|
+
(
|
|
127
|
+
"parent_propagation_delay",
|
|
128
|
+
models.PositiveIntegerField(blank=True, null=True),
|
|
129
|
+
),
|
|
130
|
+
("use_nsec3", models.BooleanField(default=True)),
|
|
131
|
+
(
|
|
132
|
+
"nsec3_iterations",
|
|
133
|
+
models.PositiveIntegerField(blank=True, null=True),
|
|
134
|
+
),
|
|
135
|
+
("nsec3_opt_out", models.BooleanField(default=False)),
|
|
136
|
+
("nsec3_salt_size", models.PositiveIntegerField(blank=True, null=True)),
|
|
137
|
+
(
|
|
138
|
+
"key_templates",
|
|
139
|
+
models.ManyToManyField(
|
|
140
|
+
blank=True,
|
|
141
|
+
related_name="policies",
|
|
142
|
+
to="netbox_dns.dnsseckeytemplate",
|
|
143
|
+
),
|
|
144
|
+
),
|
|
145
|
+
(
|
|
146
|
+
"tags",
|
|
147
|
+
taggit.managers.TaggableManager(
|
|
148
|
+
through="extras.TaggedItem", to="extras.Tag"
|
|
149
|
+
),
|
|
150
|
+
),
|
|
151
|
+
(
|
|
152
|
+
"tenant",
|
|
153
|
+
models.ForeignKey(
|
|
154
|
+
blank=True,
|
|
155
|
+
null=True,
|
|
156
|
+
on_delete=django.db.models.deletion.PROTECT,
|
|
157
|
+
related_name="netbox_dns_dnssec_policy",
|
|
158
|
+
to="tenancy.tenant",
|
|
159
|
+
),
|
|
160
|
+
),
|
|
161
|
+
],
|
|
162
|
+
options={
|
|
163
|
+
"verbose_name": "DNSSEC Policy",
|
|
164
|
+
"verbose_name_plural": "DNSSEC Policies",
|
|
165
|
+
"ordering": ("name",),
|
|
166
|
+
},
|
|
167
|
+
),
|
|
168
|
+
]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 5.1.7 on 2025-03-09 18:23
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("netbox_dns", "0015_dnssec"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="dnssecpolicy",
|
|
15
|
+
name="status",
|
|
16
|
+
field=models.CharField(default="active"),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Generated by Django 5.1.6 on 2025-03-10 15:40
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("netbox_dns", "0016_dnssec_policy_status"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AddField(
|
|
15
|
+
model_name="zone",
|
|
16
|
+
name="dnssec_policy",
|
|
17
|
+
field=models.ForeignKey(
|
|
18
|
+
blank=True,
|
|
19
|
+
null=True,
|
|
20
|
+
on_delete=django.db.models.deletion.PROTECT,
|
|
21
|
+
related_name="zones",
|
|
22
|
+
to="netbox_dns.dnssecpolicy",
|
|
23
|
+
),
|
|
24
|
+
),
|
|
25
|
+
migrations.AddField(
|
|
26
|
+
model_name="zone",
|
|
27
|
+
name="inline_signing",
|
|
28
|
+
field=models.BooleanField(default=True),
|
|
29
|
+
),
|
|
30
|
+
migrations.AddField(
|
|
31
|
+
model_name="zonetemplate",
|
|
32
|
+
name="dnssec_policy",
|
|
33
|
+
field=models.ForeignKey(
|
|
34
|
+
blank=True,
|
|
35
|
+
null=True,
|
|
36
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
37
|
+
related_name="zone_templates",
|
|
38
|
+
to="netbox_dns.dnssecpolicy",
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
]
|
netbox_dns/models/__init__.py
CHANGED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from django.urls import reverse
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
4
|
+
|
|
5
|
+
from netbox.models import NetBoxModel
|
|
6
|
+
from netbox.search import SearchIndex, register_search
|
|
7
|
+
from netbox.models.features import ContactsMixin
|
|
8
|
+
|
|
9
|
+
from netbox_dns.choices import (
|
|
10
|
+
DNSSECKeyTemplateTypeChoices,
|
|
11
|
+
DNSSECKeyTemplateAlgorithmChoices,
|
|
12
|
+
DNSSECKeyTemplateKeySizeChoices,
|
|
13
|
+
)
|
|
14
|
+
from netbox_dns.validators import validate_key_template
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
__all__ = (
|
|
18
|
+
"DNSSECKeyTemplate",
|
|
19
|
+
"DNSSECKeyTemplateIndex",
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class DNSSECKeyTemplate(ContactsMixin, NetBoxModel):
|
|
24
|
+
name = models.CharField(
|
|
25
|
+
verbose_name=_("Name"),
|
|
26
|
+
max_length=255,
|
|
27
|
+
)
|
|
28
|
+
description = models.CharField(
|
|
29
|
+
verbose_name=_("Description"),
|
|
30
|
+
max_length=200,
|
|
31
|
+
blank=True,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
type = models.CharField(
|
|
35
|
+
verbose_name=_("Type"),
|
|
36
|
+
choices=DNSSECKeyTemplateTypeChoices,
|
|
37
|
+
max_length=3,
|
|
38
|
+
blank=False,
|
|
39
|
+
null=False,
|
|
40
|
+
)
|
|
41
|
+
lifetime = models.PositiveIntegerField(
|
|
42
|
+
verbose_name=_("Lifetime"),
|
|
43
|
+
blank=True,
|
|
44
|
+
null=True,
|
|
45
|
+
)
|
|
46
|
+
algorithm = models.CharField(
|
|
47
|
+
verbose_name=_("Algorithm"),
|
|
48
|
+
choices=DNSSECKeyTemplateAlgorithmChoices,
|
|
49
|
+
blank=False,
|
|
50
|
+
null=False,
|
|
51
|
+
)
|
|
52
|
+
key_size = models.PositiveIntegerField(
|
|
53
|
+
verbose_name=_("Key Size"),
|
|
54
|
+
choices=DNSSECKeyTemplateKeySizeChoices,
|
|
55
|
+
blank=True,
|
|
56
|
+
null=True,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
tenant = models.ForeignKey(
|
|
60
|
+
verbose_name=_("Tenant"),
|
|
61
|
+
to="tenancy.Tenant",
|
|
62
|
+
on_delete=models.PROTECT,
|
|
63
|
+
related_name="netbox_dns_dnssec_key_templates",
|
|
64
|
+
blank=True,
|
|
65
|
+
null=True,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
clone_fields = (
|
|
69
|
+
"description",
|
|
70
|
+
"type",
|
|
71
|
+
"lifetime",
|
|
72
|
+
"algorithm",
|
|
73
|
+
"key_size",
|
|
74
|
+
"tenant",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
class Meta:
|
|
78
|
+
verbose_name = _("DNSSEC Key Template")
|
|
79
|
+
verbose_name_plural = _("DNSSEC Key Templates")
|
|
80
|
+
unique_together = (
|
|
81
|
+
"name",
|
|
82
|
+
"type",
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
ordering = ("name",)
|
|
86
|
+
|
|
87
|
+
def __str__(self):
|
|
88
|
+
return f"{str(self.name)} [{self.type}]"
|
|
89
|
+
|
|
90
|
+
# TODO: Remove in version 1.3.0 (NetBox #18555)
|
|
91
|
+
def get_absolute_url(self):
|
|
92
|
+
return reverse("plugins:netbox_dns:dnsseckeytemplate", kwargs={"pk": self.pk})
|
|
93
|
+
|
|
94
|
+
def get_type_color(self):
|
|
95
|
+
return DNSSECKeyTemplateTypeChoices.colors.get(self.type)
|
|
96
|
+
|
|
97
|
+
def clean(self, *args, **kwargs):
|
|
98
|
+
super().clean(*args, **kwargs)
|
|
99
|
+
|
|
100
|
+
validate_key_template(self)
|
|
101
|
+
|
|
102
|
+
def save(self, *args, **kwargs):
|
|
103
|
+
validate_key_template(self)
|
|
104
|
+
|
|
105
|
+
super().save(*args, **kwargs)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@register_search
|
|
109
|
+
class DNSSECKeyTemplateIndex(SearchIndex):
|
|
110
|
+
model = DNSSECKeyTemplate
|
|
111
|
+
fields = (
|
|
112
|
+
("name", 100),
|
|
113
|
+
("description", 500),
|
|
114
|
+
)
|