netbox-plugin-dns 1.3b2__py3-none-any.whl → 1.3.2__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 +2 -2
- netbox_dns/api/serializers_/dnssec_key_template.py +1 -0
- netbox_dns/api/serializers_/dnssec_policy.py +1 -0
- netbox_dns/api/serializers_/nameserver.py +5 -1
- netbox_dns/api/serializers_/record.py +5 -5
- netbox_dns/filtersets/record.py +2 -2
- netbox_dns/forms/zone.py +1 -1
- netbox_dns/graphql/filters/dnssec_key_template.py +1 -1
- netbox_dns/graphql/filters/dnssec_policy.py +1 -1
- netbox_dns/graphql/filters/nameserver.py +1 -1
- netbox_dns/graphql/filters/record.py +1 -1
- netbox_dns/graphql/filters/record_template.py +1 -1
- netbox_dns/graphql/filters/registrar.py +1 -1
- netbox_dns/graphql/filters/registration_contact.py +1 -1
- netbox_dns/graphql/filters/view.py +1 -1
- netbox_dns/graphql/filters/zone.py +1 -1
- netbox_dns/graphql/filters/zone_template.py +1 -1
- netbox_dns/graphql/types.py +2 -3
- netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
- netbox_dns/management/commands/remove_orphaned_ptr_records.py +35 -0
- netbox_dns/migrations/0021_alter_record_ptr_record.py +25 -0
- netbox_dns/migrations/0022_alter_record_ipam_ip_address.py +26 -0
- netbox_dns/models/record.py +115 -46
- netbox_dns/models/zone.py +1 -1
- netbox_dns/tables/record.py +26 -13
- netbox_dns/tables/view.py +1 -0
- netbox_dns/template_content.py +13 -2
- netbox_dns/templates/netbox_dns/record.html +20 -11
- netbox_dns/utilities/ipam_dnssync.py +21 -3
- netbox_dns/validators/dns_name.py +1 -1
- netbox_dns/views/dnssec_key_template.py +3 -3
- netbox_dns/views/record.py +19 -3
- netbox_dns/views/record_template.py +3 -1
- netbox_dns/views/zone_template.py +5 -3
- {netbox_plugin_dns-1.3b2.dist-info → netbox_plugin_dns-1.3.2.dist-info}/METADATA +3 -2
- {netbox_plugin_dns-1.3b2.dist-info → netbox_plugin_dns-1.3.2.dist-info}/RECORD +40 -37
- {netbox_plugin_dns-1.3b2.dist-info → netbox_plugin_dns-1.3.2.dist-info}/WHEEL +1 -1
- {netbox_plugin_dns-1.3b2.dist-info → netbox_plugin_dns-1.3.2.dist-info}/licenses/LICENSE +0 -0
- {netbox_plugin_dns-1.3b2.dist-info → netbox_plugin_dns-1.3.2.dist-info}/top_level.txt +0 -0
netbox_dns/__init__.py
CHANGED
|
@@ -4,7 +4,7 @@ from django.core.exceptions import ImproperlyConfigured
|
|
|
4
4
|
from netbox.plugins import PluginConfig
|
|
5
5
|
from netbox.plugins.utils import get_plugin_config
|
|
6
6
|
|
|
7
|
-
__version__ = "1.3
|
|
7
|
+
__version__ = "1.3.2"
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def _check_list(setting):
|
|
@@ -16,7 +16,7 @@ class DNSConfig(PluginConfig):
|
|
|
16
16
|
name = "netbox_dns"
|
|
17
17
|
verbose_name = _("NetBox DNS")
|
|
18
18
|
description = _("NetBox plugin for DNS data")
|
|
19
|
-
min_version = "4.
|
|
19
|
+
min_version = "4.3.0"
|
|
20
20
|
version = __version__
|
|
21
21
|
author = "Peter Eckel"
|
|
22
22
|
author_email = "pete@netbox-dns.org"
|
|
@@ -48,4 +48,8 @@ class NameServerSerializer(NetBoxModelSerializer):
|
|
|
48
48
|
default=None,
|
|
49
49
|
help_text=_("Zones served by the authoritative nameserver"),
|
|
50
50
|
)
|
|
51
|
-
tenant = TenantSerializer(
|
|
51
|
+
tenant = TenantSerializer(
|
|
52
|
+
nested=True,
|
|
53
|
+
required=False,
|
|
54
|
+
allow_null=True,
|
|
55
|
+
)
|
|
@@ -35,7 +35,7 @@ class RecordSerializer(NetBoxModelSerializer):
|
|
|
35
35
|
"managed",
|
|
36
36
|
"disable_ptr",
|
|
37
37
|
"ptr_record",
|
|
38
|
-
"
|
|
38
|
+
"address_records",
|
|
39
39
|
"active",
|
|
40
40
|
"custom_fields",
|
|
41
41
|
"tenant",
|
|
@@ -71,14 +71,14 @@ class RecordSerializer(NetBoxModelSerializer):
|
|
|
71
71
|
read_only=True,
|
|
72
72
|
required=False,
|
|
73
73
|
allow_null=True,
|
|
74
|
-
help_text=_("PTR record
|
|
74
|
+
help_text=_("PTR record related to an address"),
|
|
75
75
|
)
|
|
76
|
-
|
|
77
|
-
many=
|
|
76
|
+
address_records = NestedRecordSerializer(
|
|
77
|
+
many=True,
|
|
78
78
|
read_only=True,
|
|
79
79
|
required=False,
|
|
80
80
|
allow_null=True,
|
|
81
|
-
help_text=_("Address
|
|
81
|
+
help_text=_("Address records related to the PTR"),
|
|
82
82
|
)
|
|
83
83
|
zone = NestedZoneSerializer(
|
|
84
84
|
many=False,
|
netbox_dns/filtersets/record.py
CHANGED
|
@@ -63,10 +63,10 @@ class RecordFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
|
|
|
63
63
|
label=_("View the Parent Zone belongs to"),
|
|
64
64
|
)
|
|
65
65
|
address_record_id = django_filters.ModelMultipleChoiceFilter(
|
|
66
|
-
field_name="
|
|
66
|
+
field_name="address_records",
|
|
67
67
|
queryset=Record.objects.all(),
|
|
68
68
|
to_field_name="id",
|
|
69
|
-
label=_("Address
|
|
69
|
+
label=_("Address Records"),
|
|
70
70
|
)
|
|
71
71
|
ptr_record_id = django_filters.ModelMultipleChoiceFilter(
|
|
72
72
|
field_name="ptr_record",
|
netbox_dns/forms/zone.py
CHANGED
|
@@ -534,7 +534,7 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
534
534
|
)
|
|
535
535
|
parental_agents = forms.GenericIPAddressField(
|
|
536
536
|
required=False,
|
|
537
|
-
label=_("Parental
|
|
537
|
+
label=_("Parental Agents"),
|
|
538
538
|
)
|
|
539
539
|
registrar_id = DynamicModelMultipleChoiceField(
|
|
540
540
|
queryset=Registrar.objects.all(),
|
|
@@ -23,7 +23,7 @@ from netbox_dns.models import DNSSECKeyTemplate
|
|
|
23
23
|
__all__ = ("NetBoxDNSDNSSECKeyTemplateFilter",)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
@strawberry_django.
|
|
26
|
+
@strawberry_django.filter_type(DNSSECKeyTemplate, lookups=True)
|
|
27
27
|
class NetBoxDNSDNSSECKeyTemplateFilter(
|
|
28
28
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
29
29
|
):
|
|
@@ -21,7 +21,7 @@ from netbox_dns.graphql.filter_lookups import PolicyDigestArrayLookup
|
|
|
21
21
|
__all__ = ("NetBoxDNSDNSSECPolicyFilter", "PolicyDigestArrayLookup")
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
@strawberry_django.
|
|
24
|
+
@strawberry_django.filter_type(DNSSECPolicy, lookups=True)
|
|
25
25
|
class NetBoxDNSDNSSECPolicyFilter(
|
|
26
26
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
27
27
|
):
|
|
@@ -16,7 +16,7 @@ from netbox_dns.models import NameServer
|
|
|
16
16
|
__all__ = ("NetBoxDNSNameServerFilter",)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@strawberry_django.
|
|
19
|
+
@strawberry_django.filter_type(NameServer, lookups=True)
|
|
20
20
|
class NetBoxDNSNameServerFilter(
|
|
21
21
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
22
22
|
):
|
|
@@ -24,7 +24,7 @@ from netbox_dns.models import Record
|
|
|
24
24
|
__all__ = ("NetBoxDNSRecordFilter",)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
@strawberry_django.
|
|
27
|
+
@strawberry_django.filter_type(Record, lookups=True)
|
|
28
28
|
class NetBoxDNSRecordFilter(
|
|
29
29
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
30
30
|
):
|
|
@@ -20,7 +20,7 @@ from netbox_dns.models import RecordTemplate
|
|
|
20
20
|
__all__ = ("NetBoxDNSRecordTemplateFilter",)
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
@strawberry_django.
|
|
23
|
+
@strawberry_django.filter_type(RecordTemplate, lookups=True)
|
|
24
24
|
class NetBoxDNSRecordTemplateFilter(
|
|
25
25
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
26
26
|
):
|
|
@@ -15,7 +15,7 @@ from netbox_dns.models import Registrar
|
|
|
15
15
|
__all__ = ("NetBoxDNSRegistrarFilter",)
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
@strawberry_django.
|
|
18
|
+
@strawberry_django.filter_type(Registrar, lookups=True)
|
|
19
19
|
class NetBoxDNSRegistrarFilter(NetBoxModelFilterMixin):
|
|
20
20
|
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
|
21
21
|
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
|
@@ -9,7 +9,7 @@ from netbox_dns.models import RegistrationContact
|
|
|
9
9
|
__all__ = ("NetBoxDNSRegistrationContactFilter",)
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
@strawberry_django.
|
|
12
|
+
@strawberry_django.filter_type(RegistrationContact, lookups=True)
|
|
13
13
|
class NetBoxDNSRegistrationContactFilter(NetBoxModelFilterMixin):
|
|
14
14
|
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
|
15
15
|
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
|
@@ -16,7 +16,7 @@ from netbox_dns.models import View
|
|
|
16
16
|
__all__ = ("NetBoxDNSViewFilter",)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@strawberry_django.
|
|
19
|
+
@strawberry_django.filter_type(View, lookups=True)
|
|
20
20
|
class NetBoxDNSViewFilter(
|
|
21
21
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
22
22
|
):
|
|
@@ -23,7 +23,7 @@ from netbox_dns.models import Zone
|
|
|
23
23
|
__all__ = ("NetBoxDNSZoneFilter",)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
@strawberry_django.
|
|
26
|
+
@strawberry_django.filter_type(Zone, lookups=True)
|
|
27
27
|
class NetBoxDNSZoneFilter(
|
|
28
28
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
29
29
|
):
|
|
@@ -21,7 +21,7 @@ from netbox_dns.models import ZoneTemplate
|
|
|
21
21
|
__all__ = ("NetBoxDNSZoneTemplateFilter",)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
@strawberry_django.
|
|
24
|
+
@strawberry_django.filter_type(ZoneTemplate, lookups=True)
|
|
25
25
|
class NetBoxDNSZoneTemplateFilter(
|
|
26
26
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
27
27
|
):
|
netbox_dns/graphql/types.py
CHANGED
|
@@ -165,10 +165,9 @@ class NetBoxDNSRecordType(NetBoxObjectType):
|
|
|
165
165
|
Annotated["NetBoxDNSRecordType", strawberry.lazy("netbox_dns.graphql.types")]
|
|
166
166
|
| None
|
|
167
167
|
)
|
|
168
|
-
|
|
168
|
+
address_records: List[
|
|
169
169
|
Annotated["NetBoxDNSRecordType", strawberry.lazy("netbox_dns.graphql.types")]
|
|
170
|
-
|
|
171
|
-
)
|
|
170
|
+
]
|
|
172
171
|
rfc2317_ptr_records: List[
|
|
173
172
|
Annotated["NetBoxDNSRecordType", strawberry.lazy("netbox_dns.graphql.types")]
|
|
174
173
|
]
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from django.core.management.base import BaseCommand
|
|
2
|
+
|
|
3
|
+
from netbox_dns.models import Record
|
|
4
|
+
from netbox_dns.choices import RecordTypeChoices
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Command(BaseCommand):
|
|
8
|
+
help = "Remove managed PTR records without an address record"
|
|
9
|
+
|
|
10
|
+
def handle(self, *model_names, **options):
|
|
11
|
+
orphaned_ptr_records = Record.objects.filter(
|
|
12
|
+
type=RecordTypeChoices.PTR,
|
|
13
|
+
address_records__isnull=True,
|
|
14
|
+
managed=True,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if not orphaned_ptr_records.exists():
|
|
18
|
+
if options.get("verbosity") >= 1:
|
|
19
|
+
self.stdout.write("No orphaned PTR records found")
|
|
20
|
+
return
|
|
21
|
+
|
|
22
|
+
if options.get("verbosity") >= 1:
|
|
23
|
+
self.stdout.write(
|
|
24
|
+
f"Removing {orphaned_ptr_records.count()} orphaned PTR record(s) ..."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
for record in orphaned_ptr_records:
|
|
28
|
+
if options.get("verbosity") >= 2:
|
|
29
|
+
self.stdout.write(
|
|
30
|
+
f"removing PTR record {record} from zone {record.zone}"
|
|
31
|
+
)
|
|
32
|
+
record.delete()
|
|
33
|
+
|
|
34
|
+
if options.get("verbosity") >= 1:
|
|
35
|
+
self.stdout.write("... done.")
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated by Django 5.2 on 2025-05-13 09:16
|
|
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", "0020_remove_dnssecpolicy_parental_agents_and_more"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterField(
|
|
15
|
+
model_name="record",
|
|
16
|
+
name="ptr_record",
|
|
17
|
+
field=models.ForeignKey(
|
|
18
|
+
blank=True,
|
|
19
|
+
null=True,
|
|
20
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
21
|
+
related_name="address_records",
|
|
22
|
+
to="netbox_dns.record",
|
|
23
|
+
),
|
|
24
|
+
),
|
|
25
|
+
]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Generated by Django 5.2.1 on 2025-05-19 19:34
|
|
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
|
+
("ipam", "0081_remove_service_device_virtual_machine_add_parent_gfk_index"),
|
|
11
|
+
("netbox_dns", "0021_alter_record_ptr_record"),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.AlterField(
|
|
16
|
+
model_name="record",
|
|
17
|
+
name="ipam_ip_address",
|
|
18
|
+
field=models.ForeignKey(
|
|
19
|
+
blank=True,
|
|
20
|
+
null=True,
|
|
21
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
22
|
+
related_name="netbox_dns_records",
|
|
23
|
+
to="ipam.ipaddress",
|
|
24
|
+
),
|
|
25
|
+
),
|
|
26
|
+
]
|
netbox_dns/models/record.py
CHANGED
|
@@ -6,7 +6,7 @@ from dns import name as dns_name
|
|
|
6
6
|
from dns import rdata
|
|
7
7
|
|
|
8
8
|
from django.core.exceptions import ValidationError
|
|
9
|
-
from django.db import
|
|
9
|
+
from django.db import models
|
|
10
10
|
from django.db.models import Q, ExpressionWrapper, BooleanField, Min
|
|
11
11
|
from django.conf import settings
|
|
12
12
|
from django.utils.translation import gettext_lazy as _
|
|
@@ -28,7 +28,6 @@ from netbox_dns.choices import (
|
|
|
28
28
|
RecordClassChoices,
|
|
29
29
|
)
|
|
30
30
|
|
|
31
|
-
|
|
32
31
|
__all__ = (
|
|
33
32
|
"Record",
|
|
34
33
|
"RecordIndex",
|
|
@@ -143,6 +142,11 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
143
142
|
"tenant",
|
|
144
143
|
)
|
|
145
144
|
|
|
145
|
+
def __init__(self, *args, **kwargs):
|
|
146
|
+
super().__init__(*args, **kwargs)
|
|
147
|
+
|
|
148
|
+
self._cleanup_ptr_record = None
|
|
149
|
+
|
|
146
150
|
def __str__(self):
|
|
147
151
|
try:
|
|
148
152
|
fqdn = dns_name.from_text(
|
|
@@ -206,11 +210,11 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
206
210
|
null=False,
|
|
207
211
|
default=False,
|
|
208
212
|
)
|
|
209
|
-
ptr_record = models.
|
|
213
|
+
ptr_record = models.ForeignKey(
|
|
210
214
|
verbose_name=_("PTR Record"),
|
|
211
215
|
to="self",
|
|
212
216
|
on_delete=models.SET_NULL,
|
|
213
|
-
related_name="
|
|
217
|
+
related_name="address_records",
|
|
214
218
|
null=True,
|
|
215
219
|
blank=True,
|
|
216
220
|
)
|
|
@@ -241,7 +245,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
241
245
|
ipam_ip_address = models.ForeignKey(
|
|
242
246
|
verbose_name=_("IPAM IP Address"),
|
|
243
247
|
to="ipam.IPAddress",
|
|
244
|
-
on_delete=models.
|
|
248
|
+
on_delete=models.SET_NULL,
|
|
245
249
|
related_name="netbox_dns_records",
|
|
246
250
|
blank=True,
|
|
247
251
|
null=True,
|
|
@@ -255,6 +259,14 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
255
259
|
blank=True,
|
|
256
260
|
)
|
|
257
261
|
|
|
262
|
+
@property
|
|
263
|
+
def cleanup_ptr_record(self):
|
|
264
|
+
return self._cleanup_ptr_record
|
|
265
|
+
|
|
266
|
+
@cleanup_ptr_record.setter
|
|
267
|
+
def cleanup_ptr_record(self, ptr_record):
|
|
268
|
+
self._cleanup_ptr_record = ptr_record
|
|
269
|
+
|
|
258
270
|
@property
|
|
259
271
|
def display_name(self):
|
|
260
272
|
return name_to_unicode(self.name)
|
|
@@ -348,21 +360,42 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
348
360
|
def is_delegation_record(self):
|
|
349
361
|
return self in self.zone.delegation_records
|
|
350
362
|
|
|
363
|
+
def refresh_ptr_record(
|
|
364
|
+
self, ptr_record=None, update_rfc2317_cname=True, save_zone_serial=True
|
|
365
|
+
):
|
|
366
|
+
if ptr_record is None:
|
|
367
|
+
return
|
|
368
|
+
|
|
369
|
+
if not ptr_record.address_records.exists():
|
|
370
|
+
if ptr_record.rfc2317_cname_record is not None:
|
|
371
|
+
ptr_record.remove_from_rfc2317_cname_record()
|
|
372
|
+
|
|
373
|
+
ptr_record.delete(save_zone_serial=save_zone_serial)
|
|
374
|
+
|
|
375
|
+
elif update_rfc2317_cname:
|
|
376
|
+
ptr_record.update_rfc2317_cname_record(save_zone_serial=save_zone_serial)
|
|
377
|
+
|
|
351
378
|
def update_ptr_record(self, update_rfc2317_cname=True, save_zone_serial=True):
|
|
352
379
|
ptr_zone = self.ptr_zone
|
|
353
380
|
|
|
381
|
+
# +
|
|
382
|
+
# Check whether a PTR record is optioned for and return if that is not the
|
|
383
|
+
# case.
|
|
384
|
+
# -
|
|
354
385
|
if (
|
|
355
386
|
ptr_zone is None
|
|
356
387
|
or self.disable_ptr
|
|
357
388
|
or not self.is_active
|
|
358
389
|
or self.name.startswith("*")
|
|
359
390
|
):
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
self.ptr_record.delete()
|
|
363
|
-
self.ptr_record = None
|
|
391
|
+
self.cleanup_ptr_record = self.ptr_record
|
|
392
|
+
self.ptr_record = None
|
|
364
393
|
return
|
|
365
394
|
|
|
395
|
+
# +
|
|
396
|
+
# Determine the ptr_name and ptr_value related to the ptr_zone. RFC2317
|
|
397
|
+
# PTR names and zones need to be handled differently.
|
|
398
|
+
# -
|
|
366
399
|
if ptr_zone.is_rfc2317_zone:
|
|
367
400
|
ptr_name = self.rfc2317_ptr_name
|
|
368
401
|
else:
|
|
@@ -371,51 +404,76 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
371
404
|
.relativize(dns_name.from_text(ptr_zone.name))
|
|
372
405
|
.to_text()
|
|
373
406
|
)
|
|
374
|
-
|
|
375
407
|
ptr_value = self.fqdn
|
|
376
|
-
ptr_record = self.ptr_record
|
|
377
408
|
|
|
378
|
-
|
|
409
|
+
# +
|
|
410
|
+
# If there is an existing and matching PTR record there is nothing to be done.
|
|
411
|
+
# -
|
|
412
|
+
if (ptr_record := self.ptr_record) is not None:
|
|
379
413
|
if (
|
|
380
|
-
|
|
381
|
-
and ptr_record.
|
|
414
|
+
ptr_record.zone == ptr_zone
|
|
415
|
+
and ptr_record.name == ptr_name
|
|
416
|
+
and ptr_record.value == ptr_value
|
|
417
|
+
and ptr_record.ttl == self.ttl
|
|
382
418
|
):
|
|
419
|
+
return
|
|
420
|
+
|
|
421
|
+
# +
|
|
422
|
+
# If there is an RFC2317 CNAME for the PTR record and it is either
|
|
423
|
+
# not required or needs to be changed, remove it.
|
|
424
|
+
# -
|
|
425
|
+
if (
|
|
426
|
+
ptr_record.zone.pk != ptr_zone.pk or not ptr_record.zone.is_rfc2317_zone
|
|
427
|
+
) and ptr_record.rfc2317_cname_record is not None:
|
|
383
428
|
ptr_record.rfc2317_cname_record.delete(
|
|
384
429
|
save_zone_serial=save_zone_serial
|
|
385
430
|
)
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
ptr_record.name != ptr_name
|
|
398
|
-
or ptr_record.value != ptr_value
|
|
399
|
-
or ptr_record.ttl != self.ttl
|
|
400
|
-
):
|
|
401
|
-
ptr_record.name = ptr_name
|
|
402
|
-
ptr_record.value = ptr_value
|
|
403
|
-
ptr_record.ttl = self.ttl
|
|
404
|
-
ptr_record.save(save_zone_serial=save_zone_serial)
|
|
405
|
-
|
|
406
|
-
if ptr_record is None:
|
|
407
|
-
ptr_record = Record(
|
|
408
|
-
zone_id=ptr_zone.pk,
|
|
409
|
-
type=RecordTypeChoices.PTR,
|
|
410
|
-
name=ptr_name,
|
|
411
|
-
ttl=self.ttl,
|
|
412
|
-
value=ptr_value,
|
|
413
|
-
managed=True,
|
|
414
|
-
)
|
|
431
|
+
ptr_record.rfc2317_cname_record = None
|
|
432
|
+
|
|
433
|
+
# +
|
|
434
|
+
# If the PTR record is used exclusively by the address record it can be
|
|
435
|
+
# modified to match the new name, zone, value and TTL.
|
|
436
|
+
# -
|
|
437
|
+
if ptr_record.address_records.count() == 1:
|
|
438
|
+
ptr_record.zone = ptr_zone
|
|
439
|
+
ptr_record.name = ptr_name
|
|
440
|
+
ptr_record.value = ptr_value
|
|
441
|
+
ptr_record.ttl = self.ttl
|
|
415
442
|
ptr_record.save(
|
|
416
443
|
update_rfc2317_cname=update_rfc2317_cname,
|
|
417
444
|
save_zone_serial=save_zone_serial,
|
|
418
445
|
)
|
|
446
|
+
return
|
|
447
|
+
|
|
448
|
+
# +
|
|
449
|
+
# Either there was no PTR record or the existing PTR record could not be re-used,
|
|
450
|
+
# so we need to either get find a matching PTR record or create a new one.
|
|
451
|
+
# -
|
|
452
|
+
try:
|
|
453
|
+
ptr_record = Record.objects.get(
|
|
454
|
+
name=ptr_name,
|
|
455
|
+
zone=ptr_zone,
|
|
456
|
+
type=RecordTypeChoices.PTR,
|
|
457
|
+
value=ptr_value,
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
# +
|
|
461
|
+
# If no existing PTR record could be found in the database, create a new
|
|
462
|
+
# one from scratch.
|
|
463
|
+
# -
|
|
464
|
+
except Record.DoesNotExist:
|
|
465
|
+
ptr_record = Record(
|
|
466
|
+
zone_id=ptr_zone.pk,
|
|
467
|
+
type=RecordTypeChoices.PTR,
|
|
468
|
+
name=ptr_name,
|
|
469
|
+
ttl=self.ttl,
|
|
470
|
+
value=ptr_value,
|
|
471
|
+
managed=True,
|
|
472
|
+
)
|
|
473
|
+
ptr_record.save(
|
|
474
|
+
update_rfc2317_cname=update_rfc2317_cname,
|
|
475
|
+
save_zone_serial=save_zone_serial,
|
|
476
|
+
)
|
|
419
477
|
|
|
420
478
|
self.ptr_record = ptr_record
|
|
421
479
|
|
|
@@ -905,13 +963,19 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
905
963
|
save_zone_serial=save_zone_serial,
|
|
906
964
|
)
|
|
907
965
|
elif self.ptr_record is not None:
|
|
908
|
-
self.ptr_record
|
|
966
|
+
self.cleanup_ptr_record = self.ptr_record
|
|
909
967
|
self.ptr_record = None
|
|
910
968
|
|
|
911
969
|
changed_fields = self.changed_fields
|
|
912
970
|
if changed_fields is None or changed_fields:
|
|
913
971
|
super().save(*args, **kwargs)
|
|
914
972
|
|
|
973
|
+
self.refresh_ptr_record(
|
|
974
|
+
self.cleanup_ptr_record,
|
|
975
|
+
update_rfc2317_cname=update_rfc2317_cname,
|
|
976
|
+
save_zone_serial=save_zone_serial,
|
|
977
|
+
)
|
|
978
|
+
|
|
915
979
|
if self.type != RecordTypeChoices.SOA and self.zone.soa_serial_auto:
|
|
916
980
|
self.zone.update_serial(save_zone_serial=save_zone_serial)
|
|
917
981
|
|
|
@@ -919,11 +983,16 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
919
983
|
if self.rfc2317_cname_record:
|
|
920
984
|
self.remove_from_rfc2317_cname_record(save_zone_serial=save_zone_serial)
|
|
921
985
|
|
|
922
|
-
|
|
923
|
-
self.ptr_record.delete()
|
|
986
|
+
ptr_record = self.ptr_record
|
|
924
987
|
|
|
925
988
|
super().delete(*args, **kwargs)
|
|
926
989
|
|
|
990
|
+
self.refresh_ptr_record(
|
|
991
|
+
ptr_record,
|
|
992
|
+
update_rfc2317_cname=True,
|
|
993
|
+
save_zone_serial=save_zone_serial,
|
|
994
|
+
)
|
|
995
|
+
|
|
927
996
|
_zone = self.zone
|
|
928
997
|
if _zone.soa_serial_auto:
|
|
929
998
|
_zone.update_serial(save_zone_serial=save_zone_serial)
|
netbox_dns/models/zone.py
CHANGED
|
@@ -1036,7 +1036,7 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
1036
1036
|
for address_record in address_records:
|
|
1037
1037
|
address_record.ptr_record.delete()
|
|
1038
1038
|
|
|
1039
|
-
ptr_records = self.records.filter(
|
|
1039
|
+
ptr_records = self.records.filter(address_records__isnull=False)
|
|
1040
1040
|
update_records = list(
|
|
1041
1041
|
Record.objects.filter(ptr_record__in=ptr_records).values_list(
|
|
1042
1042
|
"pk", flat=True
|
netbox_dns/tables/record.py
CHANGED
|
@@ -116,9 +116,15 @@ class ManagedRecordTable(RecordBaseTable):
|
|
|
116
116
|
"active",
|
|
117
117
|
)
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
verbose_name=_("Address
|
|
119
|
+
address_records = tables.ManyToManyColumn(
|
|
120
|
+
verbose_name=_("Address Records"),
|
|
121
121
|
linkify=True,
|
|
122
|
+
linkify_item=True,
|
|
123
|
+
transform=lambda obj: (
|
|
124
|
+
obj.fqdn.rstrip(".")
|
|
125
|
+
if obj.zone.view.default_view
|
|
126
|
+
else f"[{obj.zone.view.name}] {obj.fqdn.rstrip('.')}"
|
|
127
|
+
),
|
|
122
128
|
)
|
|
123
129
|
ipam_ip_address = tables.Column(
|
|
124
130
|
verbose_name=_("IPAM IP Address"),
|
|
@@ -134,12 +140,16 @@ class ManagedRecordTable(RecordBaseTable):
|
|
|
134
140
|
def render_related_ip_address(self, record):
|
|
135
141
|
if record.ipam_ip_address is not None:
|
|
136
142
|
address = record.ipam_ip_address
|
|
137
|
-
elif (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
elif hasattr(record, "address_records"):
|
|
144
|
+
address_record = record.address_records.filter(
|
|
145
|
+
ipam_ip_address__isnull=False
|
|
146
|
+
).first()
|
|
147
|
+
if address_record is not None:
|
|
148
|
+
address = address_record.ipam_ip_address
|
|
149
|
+
else:
|
|
150
|
+
address = None
|
|
151
|
+
|
|
152
|
+
if address is None:
|
|
143
153
|
return format_html("—")
|
|
144
154
|
|
|
145
155
|
return format_html(f"<a href='{address.get_absolute_url()}'>{address}</a>")
|
|
@@ -147,11 +157,14 @@ class ManagedRecordTable(RecordBaseTable):
|
|
|
147
157
|
def value_related_ip_address(self, record):
|
|
148
158
|
if record.ipam_ip_address is not None:
|
|
149
159
|
return record.ipam_ip_address
|
|
150
|
-
elif (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
160
|
+
elif hasattr(record, "address_records"):
|
|
161
|
+
address_record = record.address_records.filter(
|
|
162
|
+
ipam_ip_address__isnull=False
|
|
163
|
+
).first()
|
|
164
|
+
if address_record is not None:
|
|
165
|
+
return address_record.ipam_ip_address
|
|
166
|
+
|
|
167
|
+
return None
|
|
155
168
|
|
|
156
169
|
|
|
157
170
|
class RelatedRecordTable(RecordBaseTable):
|
netbox_dns/tables/view.py
CHANGED
netbox_dns/template_content.py
CHANGED
|
@@ -20,6 +20,7 @@ class RelatedDNSRecords(PluginTemplateExtension):
|
|
|
20
20
|
|
|
21
21
|
def right_page(self):
|
|
22
22
|
ip_address = self.context.get("object")
|
|
23
|
+
request = self.context.get("request")
|
|
23
24
|
|
|
24
25
|
address_records = ip_address.netbox_dns_records.all()
|
|
25
26
|
pointer_records = [
|
|
@@ -32,6 +33,7 @@ class RelatedDNSRecords(PluginTemplateExtension):
|
|
|
32
33
|
address_record_table = RelatedRecordTable(
|
|
33
34
|
data=address_records,
|
|
34
35
|
)
|
|
36
|
+
address_record_table.configure(request)
|
|
35
37
|
else:
|
|
36
38
|
address_record_table = None
|
|
37
39
|
|
|
@@ -39,6 +41,7 @@ class RelatedDNSRecords(PluginTemplateExtension):
|
|
|
39
41
|
pointer_record_table = RelatedRecordTable(
|
|
40
42
|
data=pointer_records,
|
|
41
43
|
)
|
|
44
|
+
pointer_record_table.configure(request)
|
|
42
45
|
else:
|
|
43
46
|
pointer_record_table = None
|
|
44
47
|
|
|
@@ -56,11 +59,16 @@ class RelatedDNSViews(PluginTemplateExtension):
|
|
|
56
59
|
|
|
57
60
|
def right_page(self):
|
|
58
61
|
prefix = self.context.get("object")
|
|
62
|
+
request = self.context.get("request")
|
|
59
63
|
|
|
60
64
|
if assigned_views := prefix.netbox_dns_views.all():
|
|
61
|
-
|
|
65
|
+
assigned_views_table = RelatedViewTable(data=assigned_views)
|
|
66
|
+
assigned_views_table.configure(request)
|
|
67
|
+
context = {"assigned_views": assigned_views_table}
|
|
62
68
|
elif inherited_views := get_views_by_prefix(prefix):
|
|
63
|
-
|
|
69
|
+
inherited_views_table = RelatedViewTable(data=inherited_views)
|
|
70
|
+
inherited_views_table.configure(request)
|
|
71
|
+
context = {"inherited_views": inherited_views_table}
|
|
64
72
|
else:
|
|
65
73
|
context = {}
|
|
66
74
|
|
|
@@ -86,6 +94,7 @@ class IPRelatedDNSRecords(PluginTemplateExtension):
|
|
|
86
94
|
|
|
87
95
|
def right_page(self):
|
|
88
96
|
ip_address = self.context.get("object")
|
|
97
|
+
request = self.context.get("request")
|
|
89
98
|
|
|
90
99
|
address_records = Record.objects.filter(
|
|
91
100
|
type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA),
|
|
@@ -100,6 +109,7 @@ class IPRelatedDNSRecords(PluginTemplateExtension):
|
|
|
100
109
|
address_record_table = RelatedRecordTable(
|
|
101
110
|
data=address_records,
|
|
102
111
|
)
|
|
112
|
+
address_record_table.configure(request)
|
|
103
113
|
else:
|
|
104
114
|
address_record_table = None
|
|
105
115
|
|
|
@@ -107,6 +117,7 @@ class IPRelatedDNSRecords(PluginTemplateExtension):
|
|
|
107
117
|
pointer_record_table = RelatedRecordTable(
|
|
108
118
|
data=pointer_records,
|
|
109
119
|
)
|
|
120
|
+
pointer_record_table.configure(request)
|
|
110
121
|
else:
|
|
111
122
|
pointer_record_table = None
|
|
112
123
|
|
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
{% load i18n %}
|
|
7
7
|
|
|
8
8
|
{% block control-buttons %}
|
|
9
|
+
{% if perms.netbox_dns.add_record and object.type != "CNAME" %}
|
|
10
|
+
<a href="{% url 'plugins:netbox_dns:record_add' %}?view={{ object.zone.view.pk }}&zone={{ object.zone.pk }}&value={{ object.fqdn }}&type=CNAME&return_url={{ object.get_absolute_url }}">
|
|
11
|
+
<button type="submit" class="btn btn-primary" name="add-record">
|
|
12
|
+
<i class="mdi mdi-plus-thick" aria-hidden="true"></i>{% trans "Add CNAME" %}
|
|
13
|
+
</button>
|
|
14
|
+
</a>
|
|
15
|
+
{% endif %}
|
|
9
16
|
{% if object.managed %}
|
|
10
17
|
{% else %}
|
|
11
18
|
{{ block.super }}
|
|
@@ -116,22 +123,24 @@
|
|
|
116
123
|
<td>{{ object.ptr_record|linkify }}</td>
|
|
117
124
|
</tr>
|
|
118
125
|
{% endif %}
|
|
119
|
-
{% if object.
|
|
120
|
-
<tr>
|
|
121
|
-
<th scope="row">{% trans "Address Record" %}</th>
|
|
122
|
-
<td>{{ object.address_record|linkify }}</td>
|
|
123
|
-
</tr>
|
|
124
|
-
{% if object.address_record.ipam_ip_address %}
|
|
126
|
+
{% if object.address_records.exists %}
|
|
125
127
|
<tr>
|
|
126
|
-
<th scope="row">{% trans "
|
|
127
|
-
<td>
|
|
128
|
+
<th scope="row">{% trans "Address Records" %}</th>
|
|
129
|
+
<td>
|
|
130
|
+
<table>
|
|
131
|
+
{% for address_record in object.address_records.all %}
|
|
132
|
+
<tr>
|
|
133
|
+
<td>{{ address_record|linkify:"name" }}.{{ address_record.zone|linkify:"name" }}</td>
|
|
134
|
+
</tr>
|
|
135
|
+
{% endfor %}
|
|
136
|
+
</table>
|
|
137
|
+
</td>
|
|
128
138
|
</tr>
|
|
129
139
|
{% endif %}
|
|
130
|
-
{%
|
|
131
|
-
{% if object.ipam_ip_address %}
|
|
140
|
+
{% if ipam_ip_address %}
|
|
132
141
|
<tr>
|
|
133
142
|
<th scope="row">{% trans "IPAM IP Address" %}</th>
|
|
134
|
-
<td>{{
|
|
143
|
+
<td>{{ ipam_ip_address|linkify }}</td>
|
|
135
144
|
</tr>
|
|
136
145
|
{% endif %}
|
|
137
146
|
<tr>
|
|
@@ -10,7 +10,7 @@ from django.db.models import Q
|
|
|
10
10
|
from netbox.context import current_request
|
|
11
11
|
from ipam.models import IPAddress, Prefix
|
|
12
12
|
|
|
13
|
-
from netbox_dns.choices import RecordStatusChoices
|
|
13
|
+
from netbox_dns.choices import RecordStatusChoices, RecordTypeChoices
|
|
14
14
|
|
|
15
15
|
from .dns import get_parent_zone_names
|
|
16
16
|
from .conversions import regex_from_list
|
|
@@ -213,10 +213,28 @@ def update_dns_records(ip_address, view=None, force=False):
|
|
|
213
213
|
|
|
214
214
|
|
|
215
215
|
def delete_dns_records(ip_address, view=None):
|
|
216
|
-
|
|
216
|
+
from netbox_dns.models import Record
|
|
217
|
+
|
|
218
|
+
if current_request.get() is None:
|
|
217
219
|
address_records = ip_address.netbox_dns_records.all()
|
|
218
220
|
else:
|
|
219
|
-
|
|
221
|
+
# +
|
|
222
|
+
# This is a dirty hack made necessary by NetBox grand idea of manipulating
|
|
223
|
+
# objects in its event handling code, removing references to related objects
|
|
224
|
+
# in pre_delete() before our pre_delete() handler has the chance to handle
|
|
225
|
+
# them.
|
|
226
|
+
#
|
|
227
|
+
# TODO: Find something better. This is really awful.
|
|
228
|
+
# -
|
|
229
|
+
address_records = Record.objects.filter(
|
|
230
|
+
type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA),
|
|
231
|
+
managed=True,
|
|
232
|
+
ip_address=ip_address.address.ip,
|
|
233
|
+
ipam_ip_address__isnull=True,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
if view is not None:
|
|
237
|
+
address_records &= Record.objects.filter(zone__view=view)
|
|
220
238
|
|
|
221
239
|
if not address_records.exists():
|
|
222
240
|
return False
|
|
@@ -49,7 +49,7 @@ def _get_label(tolerate_leading_underscores=False, always_tolerant=False):
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
def _has_invalid_double_dash(name):
|
|
52
|
-
return bool(re.findall(r"
|
|
52
|
+
return bool(re.findall(r"(^|\.)(?!xn)..--", name, re.IGNORECASE))
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
def validate_fqdn(name, always_tolerant=False):
|
|
@@ -37,9 +37,9 @@ class DNSSECKeyTemplateView(generic.ObjectView):
|
|
|
37
37
|
|
|
38
38
|
def get_extra_context(self, request, instance):
|
|
39
39
|
if instance.policies.exists():
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
40
|
+
policy_table = DNSSECPolicyDisplayTable(data=instance.policies.all())
|
|
41
|
+
policy_table.configure(request)
|
|
42
|
+
return {"policy_table": policy_table}
|
|
43
43
|
|
|
44
44
|
return {}
|
|
45
45
|
|
netbox_dns/views/record.py
CHANGED
|
@@ -51,7 +51,7 @@ class RecordListView(generic.ObjectListView):
|
|
|
51
51
|
@register_model_view(Record, "list_managed", path="managed", detail=False)
|
|
52
52
|
class ManagedRecordListView(generic.ObjectListView):
|
|
53
53
|
queryset = Record.objects.filter(managed=True).prefetch_related(
|
|
54
|
-
"ipam_ip_address", "
|
|
54
|
+
"ipam_ip_address", "address_records"
|
|
55
55
|
)
|
|
56
56
|
filterset = RecordFilterSet
|
|
57
57
|
filterset_form = RecordFilterForm
|
|
@@ -141,11 +141,26 @@ class RecordView(generic.ObjectView):
|
|
|
141
141
|
|
|
142
142
|
if instance.type == RecordTypeChoices.CNAME:
|
|
143
143
|
try:
|
|
144
|
-
|
|
144
|
+
cname_target_table = self.get_value_records(instance)
|
|
145
|
+
if cname_target_table is not None:
|
|
146
|
+
cname_target_table.configure(request)
|
|
147
|
+
context["cname_target_table"] = cname_target_table
|
|
145
148
|
except CNAMEWarning as exc:
|
|
146
149
|
context["cname_warning"] = str(exc)
|
|
147
150
|
else:
|
|
148
|
-
|
|
151
|
+
cname_table = self.get_cname_records(instance)
|
|
152
|
+
if cname_table is not None:
|
|
153
|
+
cname_table.configure(request)
|
|
154
|
+
context["cname_table"] = cname_table
|
|
155
|
+
|
|
156
|
+
if instance.ipam_ip_address is not None:
|
|
157
|
+
context["ipam_ip_address"] = instance.ipam_ip_address
|
|
158
|
+
elif instance.address_records is not None:
|
|
159
|
+
address_record = instance.address_records.filter(
|
|
160
|
+
ipam_ip_address__isnull=False
|
|
161
|
+
).first()
|
|
162
|
+
if address_record is not None:
|
|
163
|
+
context["ipam_ip_address"] = address_record.ipam_ip_address
|
|
149
164
|
|
|
150
165
|
if not instance.managed:
|
|
151
166
|
name = dns_name.from_text(instance.name, origin=None)
|
|
@@ -155,6 +170,7 @@ class RecordView(generic.ObjectView):
|
|
|
155
170
|
|
|
156
171
|
if Zone.objects.filter(
|
|
157
172
|
active=True,
|
|
173
|
+
view=instance.zone.view,
|
|
158
174
|
name__iregex=regex_from_list(
|
|
159
175
|
get_parent_zone_names(
|
|
160
176
|
instance.fqdn,
|
|
@@ -50,9 +50,11 @@ class RecordTemplateView(generic.ObjectView):
|
|
|
50
50
|
context["unicode_value"] = unicode_value
|
|
51
51
|
|
|
52
52
|
if instance.zone_templates.exists():
|
|
53
|
-
|
|
53
|
+
zone_template_table = ZoneTemplateDisplayTable(
|
|
54
54
|
data=instance.zone_templates.all()
|
|
55
55
|
)
|
|
56
|
+
zone_template_table.configure(request)
|
|
57
|
+
context["zone_template_table"] = zone_template_table
|
|
56
58
|
|
|
57
59
|
return context
|
|
58
60
|
|
|
@@ -37,10 +37,12 @@ class ZoneTemplateView(generic.ObjectView):
|
|
|
37
37
|
|
|
38
38
|
def get_extra_context(self, request, instance):
|
|
39
39
|
if instance.record_templates.exists():
|
|
40
|
+
record_template_table = RecordTemplateDisplayTable(
|
|
41
|
+
data=instance.record_templates.all()
|
|
42
|
+
)
|
|
43
|
+
record_template_table.configure(request)
|
|
40
44
|
return {
|
|
41
|
-
"record_template_table":
|
|
42
|
-
data=instance.record_templates.all()
|
|
43
|
-
)
|
|
45
|
+
"record_template_table": record_template_table,
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
return {}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: netbox-plugin-dns
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: NetBox DNS is a NetBox plugin for managing DNS data.
|
|
5
5
|
Author-email: Peter Eckel <pete@netbox-dns.org>
|
|
6
6
|
Project-URL: Homepage, https://github.com/peteeckel/netbox-plugin-dns
|
|
@@ -8,7 +8,7 @@ Project-URL: Documentation, https://github.com/peteeckel/netbox-plugin-dns/blob/
|
|
|
8
8
|
Project-URL: Repository, https://github.com/peteeckel/netbox-plugin-dns
|
|
9
9
|
Project-URL: Issues, https://github.com/peteeckel/netbox-plugin-dns/issues
|
|
10
10
|
Keywords: netbox,netbox-plugin,dns
|
|
11
|
-
Classifier: Development Status ::
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
@@ -52,6 +52,7 @@ The main focus of the plugin is to ensure the quality of the data stored in it.
|
|
|
52
52
|
* Support for [RFC 2317](https://datatracker.ietf.org/doc/html/rfc2317) delegation of PTR zones for IPv4 subnets longer than 24 bits
|
|
53
53
|
* Templating for zones and records enables faster creations of zones with given boilerplate object relations, such as name servers, tags, tenants or registration information, or records like standard SPF or MX records that are the same for a subset of zones
|
|
54
54
|
* IPAM DNSsync can be used to automatically create address and pointer records for IP addresses by assigning prefixes to DNS views. When an IP address has a DNS name assigned and there are zones with matching names in the DNS views linked to the IP address' prefix, a matching DNS record will be created in these zones
|
|
55
|
+
* DNSSEC support for storing configuration data relevant to DNSSEC operation in NetBox DNS
|
|
55
56
|
|
|
56
57
|
Other main features include:
|
|
57
58
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
netbox_dns/__init__.py,sha256=
|
|
1
|
+
netbox_dns/__init__.py,sha256=EjxvbIOO4SlZ6nP_tL6bjBWj5tImlXFh_mPUGQjpHkE,4890
|
|
2
2
|
netbox_dns/apps.py,sha256=JCW5eS-AQBUubDJve1DjP-IRFKTFGQh1NLGWzJpC5MI,151
|
|
3
3
|
netbox_dns/navigation.py,sha256=u90MwWBySg1Z9yfZEdvUctYWEkab5z1Y3019J7U_-3g,7741
|
|
4
|
-
netbox_dns/template_content.py,sha256=
|
|
4
|
+
netbox_dns/template_content.py,sha256=nwjbWkMc02vpTmcFQdiAA1TdopJiZ0MkRy6qa18_wLI,4848
|
|
5
5
|
netbox_dns/urls.py,sha256=wrse8l5scD-jz_O7WY0YXRlYPzpkL-0-kyAd-wCPtbQ,2596
|
|
6
6
|
netbox_dns/api/field_serializers.py,sha256=nVZ6d69DWagONDwbYCP2j3cmL-x9lryitF1wThEJxyI,725
|
|
7
7
|
netbox_dns/api/nested_serializers.py,sha256=7ViTZBNMEZ7-NAGn5LXnd7AWxt7TbpFdAq1pcCPtTK8,3695
|
|
@@ -9,11 +9,11 @@ netbox_dns/api/serializers.py,sha256=OHrpfJkBn6D1y6b3nIxBEFyE50U5p-Aqv4lBojMEFgk
|
|
|
9
9
|
netbox_dns/api/urls.py,sha256=-kQaei47yZeGbDpQ9RaFaFlFb682ThuPA5h321_2cgM,1000
|
|
10
10
|
netbox_dns/api/views.py,sha256=w71SRyZue5zPD1C64TIr496nYFA_ARjHTlpSVFTZ76o,4522
|
|
11
11
|
netbox_dns/api/serializers_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
netbox_dns/api/serializers_/dnssec_key_template.py,sha256=
|
|
13
|
-
netbox_dns/api/serializers_/dnssec_policy.py,sha256=
|
|
14
|
-
netbox_dns/api/serializers_/nameserver.py,sha256=
|
|
12
|
+
netbox_dns/api/serializers_/dnssec_key_template.py,sha256=gZNv8hdpTc_X0rhfuKfUcsLzV_l6CV_tTzElw6tyEGw,1654
|
|
13
|
+
netbox_dns/api/serializers_/dnssec_policy.py,sha256=DOGtQDiLLMmH2TvmVp9w-enZtrXygiSwfiREWk2IjH0,4322
|
|
14
|
+
netbox_dns/api/serializers_/nameserver.py,sha256=0ItKFCmDVqMbw9i5LandYMZTpJAGClu6lejaWvpLbBY,1288
|
|
15
15
|
netbox_dns/api/serializers_/prefix.py,sha256=kZ1DjDly6VFZamXSxGa57YC6MfZZcI5S7jmGBkVB2_I,551
|
|
16
|
-
netbox_dns/api/serializers_/record.py,sha256=
|
|
16
|
+
netbox_dns/api/serializers_/record.py,sha256=wHs86KwLCgeC_7ORw2b0gvlpAustwfBSfbPva1yPb-k,2570
|
|
17
17
|
netbox_dns/api/serializers_/record_template.py,sha256=imRRPkCXQMCpXUUk58kB2KwXC6SyAo4HN18pSZyLpHI,1682
|
|
18
18
|
netbox_dns/api/serializers_/registrar.py,sha256=ul_6SJVqxvTE2ysXBy52U59oTzwmaD781URH1l1OW9o,927
|
|
19
19
|
netbox_dns/api/serializers_/registration_contact.py,sha256=P_aoG_1rriHn4KkwTx5Dhw37Rn3VY2whg0vAIm55cjk,1108
|
|
@@ -37,7 +37,7 @@ netbox_dns/filtersets/__init__.py,sha256=bKppz_w3X2xNNHOcxZZiIO7zSkDaNTrZJ__k1U7
|
|
|
37
37
|
netbox_dns/filtersets/dnssec_key_template.py,sha256=dFaNGYdGXghe_uDMedOPxrMGxhDu4gHXwSQ6VLSY7gk,1625
|
|
38
38
|
netbox_dns/filtersets/dnssec_policy.py,sha256=FRmHulpWmglf89J6bzQYUVFFxvt0mvp29kp7LHA5080,3071
|
|
39
39
|
netbox_dns/filtersets/nameserver.py,sha256=4hkFsohhvBptFwY9_LJJN8_8KkMhCPsFujzIlDhlnqw,1251
|
|
40
|
-
netbox_dns/filtersets/record.py,sha256=
|
|
40
|
+
netbox_dns/filtersets/record.py,sha256=7asGcd2zePhnIDAvuVE-aKAo_NNM0Pm06epXzEql4y4,3916
|
|
41
41
|
netbox_dns/filtersets/record_template.py,sha256=Pc4P479MqfgdUMvBK39ic2nsV_gg4GT_tbdVcCL9wSI,1605
|
|
42
42
|
netbox_dns/filtersets/registrar.py,sha256=6QrsrWXu19bMa99DzwwXqfNqxpvTG0JwGEpybhOSYps,978
|
|
43
43
|
netbox_dns/filtersets/registration_contact.py,sha256=42j7NkwkbSEfomCDekkIE9ZWNug_qfvmTO_D1e-fFIw,1140
|
|
@@ -53,30 +53,31 @@ netbox_dns/forms/record_template.py,sha256=5yuY2ppV2diEOdm_IN3QSLLEdWkOkWZOYRtOh
|
|
|
53
53
|
netbox_dns/forms/registrar.py,sha256=oLMcXJOpt0F02a2Aga6A45rja7TvI18nTCZb_Dx_8t0,4038
|
|
54
54
|
netbox_dns/forms/registration_contact.py,sha256=GtUmHzPmAFNRt81rTgJbmb5TMoEJ-mpmjltkuyppJwc,6157
|
|
55
55
|
netbox_dns/forms/view.py,sha256=KZ2enzbqAEElt3b5C02kMJwnIDEjdQf_BsgMuMqKP50,10836
|
|
56
|
-
netbox_dns/forms/zone.py,sha256
|
|
56
|
+
netbox_dns/forms/zone.py,sha256=Z6YypsV9tKdnNPWekLZFZVGoHz8UBO2Hylnium5M26c,29921
|
|
57
57
|
netbox_dns/forms/zone_template.py,sha256=ACx8YJirsrGMMQExVL-aEOaitsUYMyNBL793CoQZrWQ,11716
|
|
58
58
|
netbox_dns/graphql/__init__.py,sha256=0xg_5d1PPFTadBOZo752t5sfZeLFrqs2jM51Rbf8ti4,652
|
|
59
59
|
netbox_dns/graphql/enums.py,sha256=vC-v24AuNbaGoekLTDu1PBVbnR1aYeX6LmvrZkfd2F4,1453
|
|
60
60
|
netbox_dns/graphql/filter_lookups.py,sha256=P6wW2JrtkzUiIx6mJz_DvwYg5Sov68IKAx0zVQfuvYY,355
|
|
61
61
|
netbox_dns/graphql/schema.py,sha256=KlbJmlfQEqZhvb6-cYmq94mrMFcQoCh3MldaUD5eVV4,2904
|
|
62
|
-
netbox_dns/graphql/types.py,sha256=
|
|
62
|
+
netbox_dns/graphql/types.py,sha256=H03lx5YTkxLevGtTHGV5VkdKbTJbgvUYPGqBWl3X8Q4,10182
|
|
63
63
|
netbox_dns/graphql/filters/__init__.py,sha256=bKppz_w3X2xNNHOcxZZiIO7zSkDaNTrZJ__k1U7rKik,275
|
|
64
|
-
netbox_dns/graphql/filters/dnssec_key_template.py,sha256=
|
|
65
|
-
netbox_dns/graphql/filters/dnssec_policy.py,sha256=
|
|
66
|
-
netbox_dns/graphql/filters/nameserver.py,sha256=
|
|
67
|
-
netbox_dns/graphql/filters/record.py,sha256=
|
|
68
|
-
netbox_dns/graphql/filters/record_template.py,sha256=
|
|
69
|
-
netbox_dns/graphql/filters/registrar.py,sha256=
|
|
70
|
-
netbox_dns/graphql/filters/registration_contact.py,sha256=
|
|
71
|
-
netbox_dns/graphql/filters/view.py,sha256=
|
|
72
|
-
netbox_dns/graphql/filters/zone.py,sha256=
|
|
73
|
-
netbox_dns/graphql/filters/zone_template.py,sha256=
|
|
74
|
-
netbox_dns/locale/de/LC_MESSAGES/django.mo,sha256=
|
|
64
|
+
netbox_dns/graphql/filters/dnssec_key_template.py,sha256=hK7KgikQOC-BMp88PR1moHQboWd-DS59GwQ0TJADdLM,2076
|
|
65
|
+
netbox_dns/graphql/filters/dnssec_policy.py,sha256=hu2_W74PDxN4QLRQTFd-qh_qf55ztoWtShTiVhOuvD8,4656
|
|
66
|
+
netbox_dns/graphql/filters/nameserver.py,sha256=sDVIrRXBeyscGfQSost4SqrBnBQ_ZIK13GjaXkKAcCw,1050
|
|
67
|
+
netbox_dns/graphql/filters/record.py,sha256=v3-8zyVrA0Hl4AC9d4SkYAQLHpQ1StIP-ws8xM_5Qb4,3313
|
|
68
|
+
netbox_dns/graphql/filters/record_template.py,sha256=sCAm-ct3aXjz9XNtAfUhPXaXRRHIaiXq_oQ4oFzxFY8,1819
|
|
69
|
+
netbox_dns/graphql/filters/registrar.py,sha256=4tv1nlZU41-sOsNXf3-JyZESpAdktsDj7JTr1hv0aG4,1158
|
|
70
|
+
netbox_dns/graphql/filters/registration_contact.py,sha256=feCw4zZd2UQ9895Gg0PJ4R-oGm90ss5XB6ve3B9JlVg,1402
|
|
71
|
+
netbox_dns/graphql/filters/view.py,sha256=ozXGNJ0ELri2FAnQXPHDs3--Hznzx4ZF5mH264nr-DI,934
|
|
72
|
+
netbox_dns/graphql/filters/zone.py,sha256=2mqPq4jikCWhbGRbIIcKbCXRtA9QiH6rXb5ufk1DAFE,5253
|
|
73
|
+
netbox_dns/graphql/filters/zone_template.py,sha256=6ZxBN_VPXvBDGXXwcYlkX6wJXx_IlMAZIEDX5-ARO_4,3100
|
|
74
|
+
netbox_dns/locale/de/LC_MESSAGES/django.mo,sha256=lwJghKXnXryPoDpC8TpvN2QyzY8vCBfF-Bmf_MWhZYs,29944
|
|
75
75
|
netbox_dns/locale/en/LC_MESSAGES/django.mo,sha256=GDnSZkfHs3yjtTsll7dksEEej4B50F8pc9RGytZNubM,393
|
|
76
|
-
netbox_dns/locale/fr/LC_MESSAGES/django.mo,sha256=
|
|
76
|
+
netbox_dns/locale/fr/LC_MESSAGES/django.mo,sha256=vL8TcVYyBiDFZ3GVdZe4Kkc42mmtbMF3fot8maY-Q_s,30088
|
|
77
77
|
netbox_dns/management/commands/cleanup_database.py,sha256=1-tAl0Sht80qaNZyfFyUW19Eh9gBUuc7GdbHN4aemGU,5935
|
|
78
78
|
netbox_dns/management/commands/cleanup_rrset_ttl.py,sha256=UFRURLBcFeGHUS2lrYFv7UWIebjI72aG1EUQJt0XsXw,2046
|
|
79
79
|
netbox_dns/management/commands/rebuild_dnssync.py,sha256=Tcl385u6kJTX47SvSyRzKm1RIx4nYRYCMcKr3uVnV60,1246
|
|
80
|
+
netbox_dns/management/commands/remove_orphaned_ptr_records.py,sha256=vYYvI2yr4U1EiAoWm26PkULzaz3rr_Yfaw2eg9i4oIw,1142
|
|
80
81
|
netbox_dns/management/commands/setup_dnssync.py,sha256=qtVj6egSjclaQbuI60hLfl-zg89VJVbX-TB17f1k77Y,5730
|
|
81
82
|
netbox_dns/management/commands/update_soa.py,sha256=Rj_Xk-qpwkAVRubVnM5OqSTwgzi93E0PqjwGb3rYjf0,660
|
|
82
83
|
netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py,sha256=3U0810NWSHPu2dTSHpfzlleDgwMS04FhJ_CkO76SDaw,10283
|
|
@@ -101,7 +102,9 @@ netbox_dns/migrations/0018_zone_domain_status_zone_expiration_date.py,sha256=P_J
|
|
|
101
102
|
netbox_dns/migrations/0019_dnssecpolicy_parental_agents.py,sha256=ENbj3lhsCYHBflUnb2LrfUyTxwvPwcACmL8sUsm7P7A,655
|
|
102
103
|
netbox_dns/migrations/0020_netbox_3_4.py,sha256=UMcHdn8ZAuQjUaM_3rEGpktYrM0TuvhccD7Jt7WQnPs,1271
|
|
103
104
|
netbox_dns/migrations/0020_remove_dnssecpolicy_parental_agents_and_more.py,sha256=Fq2Tv-yz4TAY0yzyVs6j79ztIJa1wOm5oSdbPosYdh0,756
|
|
105
|
+
netbox_dns/migrations/0021_alter_record_ptr_record.py,sha256=arSb_EVRX0RjuldPpFTjfyLHPmzQbyzHq9qw1It50c0,656
|
|
104
106
|
netbox_dns/migrations/0021_record_ip_address.py,sha256=EqdhWXmq7aiK4X79xTRUZng3zFncCl-8JoO65HqlJKw,3244
|
|
107
|
+
netbox_dns/migrations/0022_alter_record_ipam_ip_address.py,sha256=KKmB3moxPJBKytOBymy0tS6ABIKjpNd5YY6cG--Lluk,727
|
|
105
108
|
netbox_dns/migrations/0022_search.py,sha256=KW1ffEZ4-0dppGQ_KD1EN7iw8eQJOnDco-xfJFRZqKQ,172
|
|
106
109
|
netbox_dns/migrations/0023_alter_record_value.py,sha256=4_4v8YZzU8_jadJqIUUjH6SIhNTeALWhclozTqYDmv0,378
|
|
107
110
|
netbox_dns/migrations/0024_tenancy.py,sha256=3kc5l5_AyfhOI6g6mbCfReUAbSgb2DAv0MDMZqJ-3YQ,1745
|
|
@@ -117,12 +120,12 @@ netbox_dns/models/__init__.py,sha256=CuwFENIVUv0FNMDlY18Am-mvN5kBGkPOGavCP0cle7c
|
|
|
117
120
|
netbox_dns/models/dnssec_key_template.py,sha256=Nv0vjdkOFWMptRYR1sT60bM6D8n_SnCpPZhI7WE5_UQ,2588
|
|
118
121
|
netbox_dns/models/dnssec_policy.py,sha256=REsE8p04bgJVF8yJuWuUITXpsZmvVlXWyQuJ9I6dEMs,5268
|
|
119
122
|
netbox_dns/models/nameserver.py,sha256=oVfyc_iWRzxVE2tIhfRb1Vuj2gZmlfFFzEtXj9ZEr6s,3848
|
|
120
|
-
netbox_dns/models/record.py,sha256=
|
|
123
|
+
netbox_dns/models/record.py,sha256=2HSxvroCGhvb7eg4qSXl1ACN7yzGGywbyBjhPR6siEk,31867
|
|
121
124
|
netbox_dns/models/record_template.py,sha256=Qr43_YZm1z3Od1cBdDY9wpNlV-UCzvpn2c6_dDzFzN8,5145
|
|
122
125
|
netbox_dns/models/registrar.py,sha256=-ozazecvd-oryEoDlOUvTWhEQKKQp3my6YVTEzWlUuI,1747
|
|
123
126
|
netbox_dns/models/registration_contact.py,sha256=9ehnTjg8KUrUYJKRRu2SaJX-NE5dO4wy90FRPlT2ys4,3620
|
|
124
127
|
netbox_dns/models/view.py,sha256=pwo7i8gtukIRgAC1A4rm58jcEpIbsSW_IUq6vSv-mRo,4618
|
|
125
|
-
netbox_dns/models/zone.py,sha256=
|
|
128
|
+
netbox_dns/models/zone.py,sha256=olGZyUsSF0orwefxNUtilsxByr3UceDdF8g8QIYCcsE,35642
|
|
126
129
|
netbox_dns/models/zone_template.py,sha256=aUkMtWL7SAcmmBd-w33Z5HN6N9LlSlKmYNwf9MlwNq4,5051
|
|
127
130
|
netbox_dns/signals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
128
131
|
netbox_dns/signals/dnssec.py,sha256=o4MOEg6ftxoDWFAhDtajkXzb7Nb6KuUHjtx1zNu7C1w,1040
|
|
@@ -132,17 +135,17 @@ netbox_dns/tables/dnssec_key_template.py,sha256=5Y4S3Q_RtDdUHI4KxY37Trm7uKQCFUcq
|
|
|
132
135
|
netbox_dns/tables/dnssec_policy.py,sha256=6GIhoecku3BjYwx7wsOzzkZ0uEVZk5bA63foJ3_g9sw,3332
|
|
133
136
|
netbox_dns/tables/ipam_dnssync.py,sha256=7IK95XlA2ter6gsHqXjXPd6WubpOxrV-O5-UT6R1CKU,330
|
|
134
137
|
netbox_dns/tables/nameserver.py,sha256=NFFHwwW174x_XskHF9oBllnI22PGV0J78mklrJF_psw,741
|
|
135
|
-
netbox_dns/tables/record.py,sha256=
|
|
138
|
+
netbox_dns/tables/record.py,sha256=DRe0voUIlqi3Q4CHDp-xgzCqgnSG9ynBhNPO8vnzHQw,4777
|
|
136
139
|
netbox_dns/tables/record_template.py,sha256=ueNSya2Zyrm_zU1Z-ZxwhsJIfxBtYXXoi2pSX-l4Bt8,1977
|
|
137
140
|
netbox_dns/tables/registrar.py,sha256=yI4n0jq7igYwa-zs6YT6YVV2FxkgpfkSAsA_iPzel7A,776
|
|
138
141
|
netbox_dns/tables/registration_contact.py,sha256=PeXp5l2WC5qIwctNdk_WP9LRDq_7bnoUlSS3OS6-SDs,980
|
|
139
|
-
netbox_dns/tables/view.py,sha256=
|
|
142
|
+
netbox_dns/tables/view.py,sha256=BFM50EgudRvcB32hqi0I5qA5nLBfXLzHbt_2q4_KeJA,1318
|
|
140
143
|
netbox_dns/tables/zone.py,sha256=0lsfI3N9rY11Cxgr-t0PReyNRSnB10JOh-jMVZ4qEBA,2434
|
|
141
144
|
netbox_dns/tables/zone_template.py,sha256=90geASGP6jSqKnvx2t-DaSxNZpp7j67lH1t0UzsKZ1Q,1755
|
|
142
145
|
netbox_dns/templates/netbox_dns/dnsseckeytemplate.html,sha256=dSEyHgUp0k_5JSdR4s4m_7Rom67TqvRIQN0zbQKYfjE,2839
|
|
143
146
|
netbox_dns/templates/netbox_dns/dnssecpolicy.html,sha256=dXHAt8ISsSWv-vK_kaJMcAzUBh4TZ2hAmeaYa47u0PU,7694
|
|
144
147
|
netbox_dns/templates/netbox_dns/nameserver.html,sha256=MawPiuAmjFrbv0zRi-7xkm8vr-dT1tlEno8EcoQ9peU,1714
|
|
145
|
-
netbox_dns/templates/netbox_dns/record.html,sha256=
|
|
148
|
+
netbox_dns/templates/netbox_dns/record.html,sha256=aFvbIEhhfp0AH5tRDNSgc2nQIymGgnVilk5Q8lCpKKw,7055
|
|
146
149
|
netbox_dns/templates/netbox_dns/recordtemplate.html,sha256=a29PAUl-KI_I1lxWpVdPp2loJtzgis9DG9erOWrOZM0,3708
|
|
147
150
|
netbox_dns/templates/netbox_dns/registrar.html,sha256=4kJuj3biiDxQrIMQEQUEmF4iGRE4psr6Fh0CBP1evz8,2308
|
|
148
151
|
netbox_dns/templates/netbox_dns/registrationcontact.html,sha256=sljVp_MrPSJRc2vJCPFXq9MiWOw4wjbr1kI_YStBntw,3094
|
|
@@ -168,25 +171,25 @@ netbox_dns/templatetags/netbox_dns.py,sha256=DND1DMPzv636Rak3M6Hor_Vw6pjqUfSTquo
|
|
|
168
171
|
netbox_dns/utilities/__init__.py,sha256=cSGf-nGaRWx9b-Xrh3dLMJYoWNsZ6FF-qdmV4F1uOgg,74
|
|
169
172
|
netbox_dns/utilities/conversions.py,sha256=qYnzecmR28l8Je_H0vFvzJ2sikTiEiyxr6drl_aRocg,3016
|
|
170
173
|
netbox_dns/utilities/dns.py,sha256=UBiyQe8thiOTnKOmU9e2iRHHnGF9toVLe4efU623kX4,322
|
|
171
|
-
netbox_dns/utilities/ipam_dnssync.py,sha256=
|
|
174
|
+
netbox_dns/utilities/ipam_dnssync.py,sha256=cJ1P1RuLE_MmlF7yHuLXiv5TNBtinzj2dL7U4S7eAWw,10318
|
|
172
175
|
netbox_dns/validators/__init__.py,sha256=X0hPZlC3VZcXMcvXKZ2_5LSoEJdXPNSBr4QtEIFSBJ0,94
|
|
173
|
-
netbox_dns/validators/dns_name.py,sha256=
|
|
176
|
+
netbox_dns/validators/dns_name.py,sha256=1MKnYAmkSTIQGf6zInqkpbIj5SCeCM0YGKmYOqFzUK4,3770
|
|
174
177
|
netbox_dns/validators/dns_value.py,sha256=cADhgTohXAtOLPzaoMKO9DahEUiDanpdiuKonrwFw0E,5278
|
|
175
178
|
netbox_dns/validators/dnssec.py,sha256=FzWLXX3qwS9ZMaLWHaBJStwJ_D96wp7GI4LYoKjoegc,4909
|
|
176
179
|
netbox_dns/validators/rfc2317.py,sha256=uKkwxpakiFFKdYA0qy8WSlEnbFwJD4MDw6gGV4F6skg,706
|
|
177
180
|
netbox_dns/views/__init__.py,sha256=tObkTOHw_6kVtEcwdyshN0Ql-8VGhwsgQw7owL_s2lI,273
|
|
178
|
-
netbox_dns/views/dnssec_key_template.py,sha256=
|
|
181
|
+
netbox_dns/views/dnssec_key_template.py,sha256=06omBc2RCTltGH078mNLLwz3A_y9gqrtQ08ex1XEwlg,2694
|
|
179
182
|
netbox_dns/views/dnssec_policy.py,sha256=ZvkCVfvI78w8e9c0m8lSWgRwg-jg07PM8Od0HwAVjGI,4427
|
|
180
183
|
netbox_dns/views/nameserver.py,sha256=cLB0W1UnnvEmYdoCYH5HmjrFhbEZ1gWxJTKdMS-wuh0,3564
|
|
181
|
-
netbox_dns/views/record.py,sha256=
|
|
182
|
-
netbox_dns/views/record_template.py,sha256=
|
|
184
|
+
netbox_dns/views/record.py,sha256=cPvsc20EUFcVidQ9YGIdsSTLHZKYzZD3JcV9bFv7iak,7123
|
|
185
|
+
netbox_dns/views/record_template.py,sha256=Cye1rjlpAewRgIv7QGD7o5n-knjzqjEUJzZHVxtGX4s,3041
|
|
183
186
|
netbox_dns/views/registrar.py,sha256=gYpMyz3rRJDmBfEeRfVENvR6fdWXN1y0XbN4JBlXoHc,2625
|
|
184
187
|
netbox_dns/views/registration_contact.py,sha256=5bJWjNBisqCkBo6d2TJyyBJlc95WM7VcSA6wsEB184k,3383
|
|
185
188
|
netbox_dns/views/view.py,sha256=xLXt7sKrda3FpNXsBSJk8L8P2XhZ1sVb5OOXovCsKEU,3089
|
|
186
189
|
netbox_dns/views/zone.py,sha256=tJiQWMmcuWX6OBtsflQwoTNVjp_GzeZ3-jmywRp74ZU,7065
|
|
187
|
-
netbox_dns/views/zone_template.py,sha256=
|
|
188
|
-
netbox_plugin_dns-1.
|
|
189
|
-
netbox_plugin_dns-1.
|
|
190
|
-
netbox_plugin_dns-1.
|
|
191
|
-
netbox_plugin_dns-1.
|
|
192
|
-
netbox_plugin_dns-1.
|
|
190
|
+
netbox_dns/views/zone_template.py,sha256=5P9DT3XBRL-TiM5zFhBTMlMusL4bP2jTu3GHxKz5ojc,2553
|
|
191
|
+
netbox_plugin_dns-1.3.2.dist-info/licenses/LICENSE,sha256=I3tDu11bZfhFm3EkV4zOD5TmWgLjnUNLEFwrdjniZYs,1112
|
|
192
|
+
netbox_plugin_dns-1.3.2.dist-info/METADATA,sha256=q6Zuz8KKMmZYwfUL2eaTCF_viJG4S5qm98MBm76nUQ8,7787
|
|
193
|
+
netbox_plugin_dns-1.3.2.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
|
194
|
+
netbox_plugin_dns-1.3.2.dist-info/top_level.txt,sha256=sA1Rwl1mRKvMC6XHe2ylZ1GF-Q1NGd08XedK9Y4xZc4,11
|
|
195
|
+
netbox_plugin_dns-1.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|