netbox-plugin-dns 1.3.1__py3-none-any.whl → 1.3.3__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.

Files changed (30) hide show
  1. netbox_dns/__init__.py +1 -1
  2. netbox_dns/forms/zone.py +9 -2
  3. netbox_dns/graphql/filters/dnssec_key_template.py +1 -1
  4. netbox_dns/graphql/filters/dnssec_policy.py +1 -1
  5. netbox_dns/graphql/filters/nameserver.py +1 -1
  6. netbox_dns/graphql/filters/record.py +1 -1
  7. netbox_dns/graphql/filters/record_template.py +1 -1
  8. netbox_dns/graphql/filters/registrar.py +1 -1
  9. netbox_dns/graphql/filters/registration_contact.py +1 -1
  10. netbox_dns/graphql/filters/view.py +1 -1
  11. netbox_dns/graphql/filters/zone.py +1 -1
  12. netbox_dns/graphql/filters/zone_template.py +1 -1
  13. netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
  14. netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
  15. netbox_dns/management/commands/remove_orphaned_ptr_records.py +35 -0
  16. netbox_dns/migrations/0022_alter_record_ipam_ip_address.py +26 -0
  17. netbox_dns/models/record.py +58 -44
  18. netbox_dns/models/zone.py +30 -24
  19. netbox_dns/models/zone_template.py +2 -0
  20. netbox_dns/navigation.py +55 -55
  21. netbox_dns/templates/netbox_dns/record.html +7 -0
  22. netbox_dns/templates/netbox_dns/zone/base.html +1 -1
  23. netbox_dns/templates/netbox_dns/zone.html +7 -0
  24. netbox_dns/utilities/ipam_dnssync.py +21 -3
  25. netbox_dns/views/zone.py +2 -0
  26. {netbox_plugin_dns-1.3.1.dist-info → netbox_plugin_dns-1.3.3.dist-info}/METADATA +1 -1
  27. {netbox_plugin_dns-1.3.1.dist-info → netbox_plugin_dns-1.3.3.dist-info}/RECORD +30 -28
  28. {netbox_plugin_dns-1.3.1.dist-info → netbox_plugin_dns-1.3.3.dist-info}/WHEEL +1 -1
  29. {netbox_plugin_dns-1.3.1.dist-info → netbox_plugin_dns-1.3.3.dist-info}/licenses/LICENSE +0 -0
  30. {netbox_plugin_dns-1.3.1.dist-info → netbox_plugin_dns-1.3.3.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.1"
7
+ __version__ = "1.3.3"
8
8
 
9
9
 
10
10
  def _check_list(setting):
netbox_dns/forms/zone.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from django import forms
2
- from django.db import transaction
2
+ from django.db import models, transaction
3
3
  from django.conf import settings
4
4
  from django.core.validators import MinValueValidator, MaxValueValidator
5
5
  from django.core.exceptions import ValidationError
@@ -101,7 +101,14 @@ class ZoneTemplateUpdateMixin:
101
101
  custom_fields = {}
102
102
  for key, value in zone_data.copy().items():
103
103
  if key.startswith("cf_"):
104
- custom_fields[key[3:]] = value
104
+ if isinstance(value, models.Model):
105
+ custom_fields[key[3:]] = value.pk
106
+ elif isinstance(value, models.QuerySet):
107
+ custom_fields[key[3:]] = list(
108
+ value.values_list("pk", flat=True)
109
+ )
110
+ else:
111
+ custom_fields[key[3:]] = value
105
112
  zone_data.pop(key)
106
113
  if custom_fields:
107
114
  zone_data["custom_field_data"] = custom_fields
@@ -23,7 +23,7 @@ from netbox_dns.models import DNSSECKeyTemplate
23
23
  __all__ = ("NetBoxDNSDNSSECKeyTemplateFilter",)
24
24
 
25
25
 
26
- @strawberry_django.filter(DNSSECKeyTemplate, lookups=True)
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.filter(DNSSECPolicy, lookups=True)
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.filter(NameServer, lookups=True)
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.filter(Record, lookups=True)
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.filter(RecordTemplate, lookups=True)
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.filter(Registrar, lookups=True)
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.filter(RegistrationContact, lookups=True)
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.filter(View, lookups=True)
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.filter(Zone, lookups=True)
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.filter(ZoneTemplate, lookups=True)
24
+ @strawberry_django.filter_type(ZoneTemplate, lookups=True)
25
25
  class NetBoxDNSZoneTemplateFilter(
26
26
  ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
27
27
  ):
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,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
+ ]
@@ -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 transaction, models
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 _
@@ -245,7 +245,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
245
245
  ipam_ip_address = models.ForeignKey(
246
246
  verbose_name=_("IPAM IP Address"),
247
247
  to="ipam.IPAddress",
248
- on_delete=models.CASCADE,
248
+ on_delete=models.SET_NULL,
249
249
  related_name="netbox_dns_records",
250
250
  blank=True,
251
251
  null=True,
@@ -378,6 +378,10 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
378
378
  def update_ptr_record(self, update_rfc2317_cname=True, save_zone_serial=True):
379
379
  ptr_zone = self.ptr_zone
380
380
 
381
+ # +
382
+ # Check whether a PTR record is optioned for and return if that is not the
383
+ # case.
384
+ # -
381
385
  if (
382
386
  ptr_zone is None
383
387
  or self.disable_ptr
@@ -388,6 +392,10 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
388
392
  self.ptr_record = None
389
393
  return
390
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
+ # -
391
399
  if ptr_zone.is_rfc2317_zone:
392
400
  ptr_name = self.rfc2317_ptr_name
393
401
  else:
@@ -396,9 +404,12 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
396
404
  .relativize(dns_name.from_text(ptr_zone.name))
397
405
  .to_text()
398
406
  )
399
-
400
407
  ptr_value = self.fqdn
401
- if ptr_record := self.ptr_record:
408
+
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:
402
413
  if (
403
414
  ptr_record.zone == ptr_zone
404
415
  and ptr_record.name == ptr_name
@@ -407,15 +418,37 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
407
418
  ):
408
419
  return
409
420
 
410
- if ptr_record is not None:
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
+ # -
411
425
  if (
412
- not ptr_record.zone.is_rfc2317_zone
413
- and ptr_record.rfc2317_cname_record is not None
414
- ):
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:
415
428
  ptr_record.rfc2317_cname_record.delete(
416
429
  save_zone_serial=save_zone_serial
417
430
  )
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
442
+ ptr_record.save(
443
+ update_rfc2317_cname=update_rfc2317_cname,
444
+ save_zone_serial=save_zone_serial,
445
+ )
446
+ return
418
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
+ # -
419
452
  try:
420
453
  ptr_record = Record.objects.get(
421
454
  name=ptr_name,
@@ -423,43 +456,24 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
423
456
  type=RecordTypeChoices.PTR,
424
457
  value=ptr_value,
425
458
  )
426
- except Record.DoesNotExist:
427
- pass
428
-
429
- with transaction.atomic():
430
- if ptr_record is not None:
431
- if ptr_record.zone.pk != ptr_zone.pk:
432
- if ptr_record.rfc2317_cname_record is not None:
433
- ptr_record.rfc2317_cname_record.delete()
434
- ptr_record.rfc2317_cname_record = None
435
-
436
- if ptr_record.address_records.count() == 1:
437
- ptr_record.zone = ptr_zone
438
- ptr_record.name = ptr_name
439
- ptr_record.value = ptr_value
440
- ptr_record.ttl = self.ttl
441
- ptr_record.save(
442
- update_rfc2317_cname=update_rfc2317_cname,
443
- save_zone_serial=save_zone_serial,
444
- )
445
459
 
446
- else:
447
- self.ptr_record = ptr_record
448
- return
449
-
450
- if ptr_record is None:
451
- ptr_record = Record(
452
- zone_id=ptr_zone.pk,
453
- type=RecordTypeChoices.PTR,
454
- name=ptr_name,
455
- ttl=self.ttl,
456
- value=ptr_value,
457
- managed=True,
458
- )
459
- ptr_record.save(
460
- update_rfc2317_cname=update_rfc2317_cname,
461
- save_zone_serial=save_zone_serial,
462
- )
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
+ )
463
477
 
464
478
  self.ptr_record = ptr_record
465
479
 
netbox_dns/models/zone.py CHANGED
@@ -585,6 +585,30 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
585
585
  managed=True,
586
586
  )
587
587
 
588
+ def _check_nameserver_address_records(self, nameserver):
589
+ name = dns_name.from_text(nameserver.name, origin=None)
590
+ parent = name.parent()
591
+
592
+ if len(parent) < 2:
593
+ return None
594
+
595
+ try:
596
+ ns_zone = Zone.objects.get(view_id=self.view.pk, name=parent.to_text())
597
+ except ObjectDoesNotExist:
598
+ return None
599
+
600
+ relative_name = name.relativize(parent).to_text()
601
+ address_records = ns_zone.records.filter(
602
+ Q(status__in=RECORD_ACTIVE_STATUS_LIST),
603
+ Q(Q(name=f"{nameserver.name}.") | Q(name=relative_name)),
604
+ Q(Q(type=RecordTypeChoices.A) | Q(type=RecordTypeChoices.AAAA)),
605
+ )
606
+
607
+ if not address_records.exists():
608
+ return _(
609
+ "Nameserver {ns} does not have an active address record in zone {zone}"
610
+ ).format(ns=nameserver.name, zone=ns_zone)
611
+
588
612
  def check_nameservers(self):
589
613
  nameservers = self.nameservers.all()
590
614
 
@@ -597,33 +621,15 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
597
621
  )
598
622
 
599
623
  for _nameserver in nameservers:
600
- name = dns_name.from_text(_nameserver.name, origin=None)
601
- parent = name.parent()
602
-
603
- if len(parent) < 2:
604
- continue
605
-
606
- try:
607
- ns_zone = Zone.objects.get(view_id=self.view.pk, name=parent.to_text())
608
- except ObjectDoesNotExist:
609
- continue
610
-
611
- relative_name = name.relativize(parent).to_text()
612
- address_records = ns_zone.records.filter(
613
- Q(status__in=RECORD_ACTIVE_STATUS_LIST),
614
- Q(Q(name=f"{_nameserver.name}.") | Q(name=relative_name)),
615
- Q(Q(type=RecordTypeChoices.A) | Q(type=RecordTypeChoices.AAAA)),
616
- )
617
-
618
- if not address_records:
619
- ns_warnings.append(
620
- _(
621
- "Nameserver {nameserver} does not have an active address record in zone {zone}"
622
- ).format(nameserver=_nameserver.name, zone=ns_zone)
623
- )
624
+ warning = self._check_nameserver_address_records(_nameserver)
625
+ if warning is not None:
626
+ ns_warnings.append(warning)
624
627
 
625
628
  return ns_warnings, ns_errors
626
629
 
630
+ def check_soa_mname(self):
631
+ return self._check_nameserver_address_records(self.soa_mname)
632
+
627
633
  def check_expiration(self):
628
634
  if self.expiration_date is None:
629
635
  return None, None
@@ -28,6 +28,8 @@ class ZoneTemplate(NetBoxModel):
28
28
  "description",
29
29
  "nameservers",
30
30
  "record_templates",
31
+ "soa_mname",
32
+ "soa_rname",
31
33
  "dnssec_policy",
32
34
  "registrar",
33
35
  "registrant",
netbox_dns/navigation.py CHANGED
@@ -26,42 +26,42 @@ view_menu_item = PluginMenuItem(
26
26
  ),
27
27
  )
28
28
 
29
- zone_menu_item = PluginMenuItem(
30
- link="plugins:netbox_dns:zone_list",
31
- link_text=_("Zones"),
32
- permissions=["netbox_dns.view_zone"],
29
+ nameserver_menu_item = PluginMenuItem(
30
+ link="plugins:netbox_dns:nameserver_list",
31
+ link_text=_("Nameservers"),
32
+ permissions=["netbox_dns.view_nameserver"],
33
33
  buttons=(
34
34
  PluginMenuButton(
35
- "plugins:netbox_dns:zone_add",
35
+ "plugins:netbox_dns:nameserver_add",
36
36
  _("Add"),
37
37
  "mdi mdi-plus-thick",
38
- permissions=["netbox_dns.add_zone"],
38
+ permissions=["netbox_dns.add_nameserver"],
39
39
  ),
40
40
  PluginMenuButton(
41
- "plugins:netbox_dns:zone_bulk_import",
41
+ "plugins:netbox_dns:nameserver_bulk_import",
42
42
  _("Import"),
43
43
  "mdi mdi-upload",
44
- permissions=["netbox_dns.add_zone"],
44
+ permissions=["netbox_dns.add_nameserver"],
45
45
  ),
46
46
  ),
47
47
  )
48
48
 
49
- nameserver_menu_item = PluginMenuItem(
50
- link="plugins:netbox_dns:nameserver_list",
51
- link_text=_("Nameservers"),
52
- permissions=["netbox_dns.view_nameserver"],
49
+ zone_menu_item = PluginMenuItem(
50
+ link="plugins:netbox_dns:zone_list",
51
+ link_text=_("Zones"),
52
+ permissions=["netbox_dns.view_zone"],
53
53
  buttons=(
54
54
  PluginMenuButton(
55
- "plugins:netbox_dns:nameserver_add",
55
+ "plugins:netbox_dns:zone_add",
56
56
  _("Add"),
57
57
  "mdi mdi-plus-thick",
58
- permissions=["netbox_dns.add_nameserver"],
58
+ permissions=["netbox_dns.add_zone"],
59
59
  ),
60
60
  PluginMenuButton(
61
- "plugins:netbox_dns:nameserver_bulk_import",
61
+ "plugins:netbox_dns:zone_bulk_import",
62
62
  _("Import"),
63
63
  "mdi mdi-upload",
64
- permissions=["netbox_dns.add_nameserver"],
64
+ permissions=["netbox_dns.add_zone"],
65
65
  ),
66
66
  ),
67
67
  )
@@ -92,82 +92,82 @@ managed_record_menu_item = PluginMenuItem(
92
92
  permissions=["netbox_dns.view_record"],
93
93
  )
94
94
 
95
- dnsseckeytemplate_menu_item = PluginMenuItem(
96
- link="plugins:netbox_dns:dnsseckeytemplate_list",
97
- link_text=_("DNSSEC Key Templates"),
98
- permissions=["netbox_dns.view_dnsseckeytemplate"],
95
+ zonetemplate_menu_item = PluginMenuItem(
96
+ link="plugins:netbox_dns:zonetemplate_list",
97
+ link_text=_("Zone Templates"),
98
+ permissions=["netbox_dns.view_zonetemplate"],
99
99
  buttons=(
100
100
  PluginMenuButton(
101
- "plugins:netbox_dns:dnsseckeytemplate_add",
101
+ "plugins:netbox_dns:zonetemplate_add",
102
102
  _("Add"),
103
103
  "mdi mdi-plus-thick",
104
- permissions=["netbox_dns.add_dnsseckeytemplate"],
104
+ permissions=["netbox_dns.add_zonetemplate"],
105
105
  ),
106
106
  PluginMenuButton(
107
- "plugins:netbox_dns:dnsseckeytemplate_bulk_import",
107
+ "plugins:netbox_dns:zonetemplate_bulk_import",
108
108
  _("Import"),
109
109
  "mdi mdi-upload",
110
- permissions=["netbox_dns.add_dnsseckeytemplate"],
110
+ permissions=["netbox_dns.add_zonetemplate"],
111
111
  ),
112
112
  ),
113
113
  )
114
114
 
115
- dnssecpolicy_menu_item = PluginMenuItem(
116
- link="plugins:netbox_dns:dnssecpolicy_list",
117
- link_text=_("DNSSEC Policies"),
118
- permissions=["netbox_dns.view_dnssecpolicy"],
115
+ recordtemplate_menu_item = PluginMenuItem(
116
+ link="plugins:netbox_dns:recordtemplate_list",
117
+ link_text=_("Record Templates"),
118
+ permissions=["netbox_dns.view_recordtemplate"],
119
119
  buttons=(
120
120
  PluginMenuButton(
121
- "plugins:netbox_dns:dnssecpolicy_add",
121
+ "plugins:netbox_dns:recordtemplate_add",
122
122
  _("Add"),
123
123
  "mdi mdi-plus-thick",
124
- permissions=["netbox_dns.add_dnssecpolicy"],
124
+ permissions=["netbox_dns.add_recordtemplate"],
125
125
  ),
126
126
  PluginMenuButton(
127
- "plugins:netbox_dns:dnssecpolicy_bulk_import",
127
+ "plugins:netbox_dns:recordtemplate_bulk_import",
128
128
  _("Import"),
129
129
  "mdi mdi-upload",
130
- permissions=["netbox_dns.add_dnssecpolicy"],
130
+ permissions=["netbox_dns.add_recordtemplate"],
131
131
  ),
132
132
  ),
133
133
  )
134
134
 
135
- zonetemplate_menu_item = PluginMenuItem(
136
- link="plugins:netbox_dns:zonetemplate_list",
137
- link_text=_("Zone Templates"),
138
- permissions=["netbox_dns.view_zonetemplate"],
135
+ dnsseckeytemplate_menu_item = PluginMenuItem(
136
+ link="plugins:netbox_dns:dnsseckeytemplate_list",
137
+ link_text=_("DNSSEC Key Templates"),
138
+ permissions=["netbox_dns.view_dnsseckeytemplate"],
139
139
  buttons=(
140
140
  PluginMenuButton(
141
- "plugins:netbox_dns:zonetemplate_add",
141
+ "plugins:netbox_dns:dnsseckeytemplate_add",
142
142
  _("Add"),
143
143
  "mdi mdi-plus-thick",
144
- permissions=["netbox_dns.add_zonetemplate"],
144
+ permissions=["netbox_dns.add_dnsseckeytemplate"],
145
145
  ),
146
146
  PluginMenuButton(
147
- "plugins:netbox_dns:zonetemplate_bulk_import",
147
+ "plugins:netbox_dns:dnsseckeytemplate_bulk_import",
148
148
  _("Import"),
149
149
  "mdi mdi-upload",
150
- permissions=["netbox_dns.add_zonetemplate"],
150
+ permissions=["netbox_dns.add_dnsseckeytemplate"],
151
151
  ),
152
152
  ),
153
153
  )
154
154
 
155
- recordtemplate_menu_item = PluginMenuItem(
156
- link="plugins:netbox_dns:recordtemplate_list",
157
- link_text=_("Record Templates"),
158
- permissions=["netbox_dns.view_recordtemplate"],
155
+ dnssecpolicy_menu_item = PluginMenuItem(
156
+ link="plugins:netbox_dns:dnssecpolicy_list",
157
+ link_text=_("DNSSEC Policies"),
158
+ permissions=["netbox_dns.view_dnssecpolicy"],
159
159
  buttons=(
160
160
  PluginMenuButton(
161
- "plugins:netbox_dns:recordtemplate_add",
161
+ "plugins:netbox_dns:dnssecpolicy_add",
162
162
  _("Add"),
163
163
  "mdi mdi-plus-thick",
164
- permissions=["netbox_dns.add_recordtemplate"],
164
+ permissions=["netbox_dns.add_dnssecpolicy"],
165
165
  ),
166
166
  PluginMenuButton(
167
- "plugins:netbox_dns:recordtemplate_bulk_import",
167
+ "plugins:netbox_dns:dnssecpolicy_bulk_import",
168
168
  _("Import"),
169
169
  "mdi mdi-upload",
170
- permissions=["netbox_dns.add_recordtemplate"],
170
+ permissions=["netbox_dns.add_dnssecpolicy"],
171
171
  ),
172
172
  ),
173
173
  )
@@ -221,24 +221,24 @@ if top_level_menu:
221
221
  _("DNS Configuration"),
222
222
  (
223
223
  view_menu_item,
224
- zone_menu_item,
225
224
  nameserver_menu_item,
225
+ zone_menu_item,
226
226
  record_menu_item,
227
227
  managed_record_menu_item,
228
228
  ),
229
229
  ),
230
230
  (
231
- _("DNSSEC"),
231
+ _("Templates"),
232
232
  (
233
- dnsseckeytemplate_menu_item,
234
- dnssecpolicy_menu_item,
233
+ zonetemplate_menu_item,
234
+ recordtemplate_menu_item,
235
235
  ),
236
236
  ),
237
237
  (
238
- _("Templates"),
238
+ _("DNSSEC"),
239
239
  (
240
- zonetemplate_menu_item,
241
- recordtemplate_menu_item,
240
+ dnsseckeytemplate_menu_item,
241
+ dnssecpolicy_menu_item,
242
242
  ),
243
243
  ),
244
244
  (
@@ -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 }}
@@ -7,7 +7,7 @@
7
7
 
8
8
  {% block extra_controls %}
9
9
  {% if perms.netbox_dns.add_record %}
10
- <a href="{% url 'plugins:netbox_dns:record_add' %}?zone={{ object.pk }}&return_url={{ object.get_absolute_url }}">
10
+ <a href="{% url 'plugins:netbox_dns:record_add' %}?zone={{ object.pk }}&return_url={% url 'plugins:netbox_dns:zone_records' pk=object.pk %}">
11
11
  <button type="submit" class="btn btn-primary" name="add-record">
12
12
  <i class="mdi mdi-plus-thick" aria-hidden="true"></i>{% trans "Add Record" %}
13
13
  </button>
@@ -137,6 +137,13 @@
137
137
  <th scope="row">{% trans "MName" %}</th>
138
138
  <td>{{ object.soa_mname|linkify }}</td>
139
139
  </tr>
140
+ {% if mname_warning %}
141
+ <tr>
142
+ <th class="text-warning" scope="row">{% trans "Warning" %}</th>
143
+ <td class="text-warning">{{ mname_warning }}</td>
144
+ </tr>
145
+ {% endif %}
146
+
140
147
  <tr>
141
148
  <th scope="row">{% trans "RName" %}</th>
142
149
  <td>{{ object.soa_rname }}</td>
@@ -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
- if view is None:
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
- address_records = ip_address.netbox_dns_records.filter(zone__view=view)
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
netbox_dns/views/zone.py CHANGED
@@ -52,10 +52,12 @@ class ZoneView(generic.ObjectView):
52
52
 
53
53
  def get_extra_context(self, request, instance):
54
54
  ns_warnings, ns_errors = instance.check_nameservers()
55
+ mname_warning = instance.check_soa_mname()
55
56
 
56
57
  context = {
57
58
  "nameserver_warnings": ns_warnings,
58
59
  "nameserver_errors": ns_errors,
60
+ "mname_warning": mname_warning,
59
61
  "parent_zone": instance.parent_zone,
60
62
  }
61
63
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-plugin-dns
3
- Version: 1.3.1
3
+ Version: 1.3.3
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
@@ -1,6 +1,6 @@
1
- netbox_dns/__init__.py,sha256=GEWbFp50kHBgrhLUzp8A7ExgJAOKlyH0Oz8BdkjQjAk,4890
1
+ netbox_dns/__init__.py,sha256=MVztNOPEPnEVgDW3bm96rasp3q0E34dt-SgScdi7_Lg,4890
2
2
  netbox_dns/apps.py,sha256=JCW5eS-AQBUubDJve1DjP-IRFKTFGQh1NLGWzJpC5MI,151
3
- netbox_dns/navigation.py,sha256=u90MwWBySg1Z9yfZEdvUctYWEkab5z1Y3019J7U_-3g,7741
3
+ netbox_dns/navigation.py,sha256=ZF2-bKRfuxXnLArSCvozyRXRd7GME14sVJZdmDEMhBk,7741
4
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
@@ -53,7 +53,7 @@ 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=Z6YypsV9tKdnNPWekLZFZVGoHz8UBO2Hylnium5M26c,29921
56
+ netbox_dns/forms/zone.py,sha256=aVeSvUwohcqqetPupj4FQRgouE5fS53vvIoe82zmoaA,30334
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
@@ -61,22 +61,23 @@ netbox_dns/graphql/filter_lookups.py,sha256=P6wW2JrtkzUiIx6mJz_DvwYg5Sov68IKAx0z
61
61
  netbox_dns/graphql/schema.py,sha256=KlbJmlfQEqZhvb6-cYmq94mrMFcQoCh3MldaUD5eVV4,2904
62
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=EPZqXaQyZ6UAnUgKy6_NjxbhXDbOI8oM7I62BuwGzR0,2071
65
- netbox_dns/graphql/filters/dnssec_policy.py,sha256=MImrsCGjNKxqCRB8HGOoNKyqxRuZyhq3su_nT5hdxW4,4651
66
- netbox_dns/graphql/filters/nameserver.py,sha256=iiBQ_1_id-eVgDjtcCYCnVlMG4QeP-lz3p3ZuoGaW3k,1045
67
- netbox_dns/graphql/filters/record.py,sha256=RqJNgLcFJ-Q4ZxV8fqAKXAPpjl6yDxSJz-pWGHIsoS8,3308
68
- netbox_dns/graphql/filters/record_template.py,sha256=3kIeIoPzl3RV7yE-h8Bdc7Lt7VXbtK86uOARFM8UmDo,1814
69
- netbox_dns/graphql/filters/registrar.py,sha256=hiGBl4Fkv_yy8f-I7P25ZAFLrK4Z4hRt9C9hBNSGT14,1153
70
- netbox_dns/graphql/filters/registration_contact.py,sha256=Gwwj55846y90xJiVIdBfPDqrKX_9tjxy6UwfXPbIFJo,1397
71
- netbox_dns/graphql/filters/view.py,sha256=dNjGoSj5aKuQmofRDEIhxTs07ZWc8T0uheI6FOPTafQ,929
72
- netbox_dns/graphql/filters/zone.py,sha256=y5262E4Xqghny8-oUgkt0pod5KtPvZjxAsEowJ5HCdU,5248
73
- netbox_dns/graphql/filters/zone_template.py,sha256=I7_NFFkI8dsVMgIS5PV-VBkoxGZg2w74G3XXq2Fmdco,3095
74
- netbox_dns/locale/de/LC_MESSAGES/django.mo,sha256=lwJghKXnXryPoDpC8TpvN2QyzY8vCBfF-Bmf_MWhZYs,29944
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=fSlYDunygrkHE4TAIlHI0ol67Lz3qiu2hUkeirewlOQ,29995
75
75
  netbox_dns/locale/en/LC_MESSAGES/django.mo,sha256=GDnSZkfHs3yjtTsll7dksEEej4B50F8pc9RGytZNubM,393
76
- netbox_dns/locale/fr/LC_MESSAGES/django.mo,sha256=vL8TcVYyBiDFZ3GVdZe4Kkc42mmtbMF3fot8maY-Q_s,30088
76
+ netbox_dns/locale/fr/LC_MESSAGES/django.mo,sha256=hZjbClaXZndP8VtqAiXWBdYEFVD9CQrKJXelL6kMOPE,30021
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
@@ -103,6 +104,7 @@ netbox_dns/migrations/0020_netbox_3_4.py,sha256=UMcHdn8ZAuQjUaM_3rEGpktYrM0Tuvhc
103
104
  netbox_dns/migrations/0020_remove_dnssecpolicy_parental_agents_and_more.py,sha256=Fq2Tv-yz4TAY0yzyVs6j79ztIJa1wOm5oSdbPosYdh0,756
104
105
  netbox_dns/migrations/0021_alter_record_ptr_record.py,sha256=arSb_EVRX0RjuldPpFTjfyLHPmzQbyzHq9qw1It50c0,656
105
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
106
108
  netbox_dns/migrations/0022_search.py,sha256=KW1ffEZ4-0dppGQ_KD1EN7iw8eQJOnDco-xfJFRZqKQ,172
107
109
  netbox_dns/migrations/0023_alter_record_value.py,sha256=4_4v8YZzU8_jadJqIUUjH6SIhNTeALWhclozTqYDmv0,378
108
110
  netbox_dns/migrations/0024_tenancy.py,sha256=3kc5l5_AyfhOI6g6mbCfReUAbSgb2DAv0MDMZqJ-3YQ,1745
@@ -118,13 +120,13 @@ netbox_dns/models/__init__.py,sha256=CuwFENIVUv0FNMDlY18Am-mvN5kBGkPOGavCP0cle7c
118
120
  netbox_dns/models/dnssec_key_template.py,sha256=Nv0vjdkOFWMptRYR1sT60bM6D8n_SnCpPZhI7WE5_UQ,2588
119
121
  netbox_dns/models/dnssec_policy.py,sha256=REsE8p04bgJVF8yJuWuUITXpsZmvVlXWyQuJ9I6dEMs,5268
120
122
  netbox_dns/models/nameserver.py,sha256=oVfyc_iWRzxVE2tIhfRb1Vuj2gZmlfFFzEtXj9ZEr6s,3848
121
- netbox_dns/models/record.py,sha256=hXQDW28mau6DJ1p6clol3-5-N-OF2L_PYS--CW9QhrE,31275
123
+ netbox_dns/models/record.py,sha256=2HSxvroCGhvb7eg4qSXl1ACN7yzGGywbyBjhPR6siEk,31867
122
124
  netbox_dns/models/record_template.py,sha256=Qr43_YZm1z3Od1cBdDY9wpNlV-UCzvpn2c6_dDzFzN8,5145
123
125
  netbox_dns/models/registrar.py,sha256=-ozazecvd-oryEoDlOUvTWhEQKKQp3my6YVTEzWlUuI,1747
124
126
  netbox_dns/models/registration_contact.py,sha256=9ehnTjg8KUrUYJKRRu2SaJX-NE5dO4wy90FRPlT2ys4,3620
125
127
  netbox_dns/models/view.py,sha256=pwo7i8gtukIRgAC1A4rm58jcEpIbsSW_IUq6vSv-mRo,4618
126
- netbox_dns/models/zone.py,sha256=olGZyUsSF0orwefxNUtilsxByr3UceDdF8g8QIYCcsE,35642
127
- netbox_dns/models/zone_template.py,sha256=aUkMtWL7SAcmmBd-w33Z5HN6N9LlSlKmYNwf9MlwNq4,5051
128
+ netbox_dns/models/zone.py,sha256=8MB8p6R9K-5K8eR2AKZXb6rwnnWDvcd-_KFLi5JqviQ,35825
129
+ netbox_dns/models/zone_template.py,sha256=ShPg6_ts6W-dpdGzUg3oZnGHEEQ-_Jf0EdYwVWzaPwI,5093
128
130
  netbox_dns/signals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
131
  netbox_dns/signals/dnssec.py,sha256=o4MOEg6ftxoDWFAhDtajkXzb7Nb6KuUHjtx1zNu7C1w,1040
130
132
  netbox_dns/signals/ipam_dnssync.py,sha256=1zhlf4cMcJLlFosX7YzyqVYdFFHV4MFwTz5KCdL8xQc,7730
@@ -143,19 +145,19 @@ netbox_dns/tables/zone_template.py,sha256=90geASGP6jSqKnvx2t-DaSxNZpp7j67lH1t0Uz
143
145
  netbox_dns/templates/netbox_dns/dnsseckeytemplate.html,sha256=dSEyHgUp0k_5JSdR4s4m_7Rom67TqvRIQN0zbQKYfjE,2839
144
146
  netbox_dns/templates/netbox_dns/dnssecpolicy.html,sha256=dXHAt8ISsSWv-vK_kaJMcAzUBh4TZ2hAmeaYa47u0PU,7694
145
147
  netbox_dns/templates/netbox_dns/nameserver.html,sha256=MawPiuAmjFrbv0zRi-7xkm8vr-dT1tlEno8EcoQ9peU,1714
146
- netbox_dns/templates/netbox_dns/record.html,sha256=8r-tulEu2_Is4b2RU4pjUKS2eASFdZh8z5GfHsRFz6s,6619
148
+ netbox_dns/templates/netbox_dns/record.html,sha256=aFvbIEhhfp0AH5tRDNSgc2nQIymGgnVilk5Q8lCpKKw,7055
147
149
  netbox_dns/templates/netbox_dns/recordtemplate.html,sha256=a29PAUl-KI_I1lxWpVdPp2loJtzgis9DG9erOWrOZM0,3708
148
150
  netbox_dns/templates/netbox_dns/registrar.html,sha256=4kJuj3biiDxQrIMQEQUEmF4iGRE4psr6Fh0CBP1evz8,2308
149
151
  netbox_dns/templates/netbox_dns/registrationcontact.html,sha256=sljVp_MrPSJRc2vJCPFXq9MiWOw4wjbr1kI_YStBntw,3094
150
152
  netbox_dns/templates/netbox_dns/view.html,sha256=1MuzOYNQezRrryNjlklgxErjGTFoVnwqcxf4qceuglw,3320
151
- netbox_dns/templates/netbox_dns/zone.html,sha256=3G80d3_oJM8LfLZNBGR2mO_UHadGK4Glr1sk5MO92dA,7997
153
+ netbox_dns/templates/netbox_dns/zone.html,sha256=Hx2SL9gk7IKzBv5q45eESQADBPOCgbsW1yGe96-wlik,8262
152
154
  netbox_dns/templates/netbox_dns/zonetemplate.html,sha256=a3QD0O_8CW2MUBnU_nXGweGhCwo5pYDVlwJHzovC1RU,4344
153
155
  netbox_dns/templates/netbox_dns/record/managed.html,sha256=uwpxQTxyfAXkWqThLT-T2ZssKNUhXTDDMnLWJSVuDNU,119
154
156
  netbox_dns/templates/netbox_dns/record/related.html,sha256=R59aPhE4CyIZtTH0ncwDyS6_wAe_Y-oZjuN_j4qk8iA,1158
155
157
  netbox_dns/templates/netbox_dns/view/button.html,sha256=EMOB5x78XpyfN1qi-pY1CKKKLjyHo9rFUa4Uhq6rFMc,322
156
158
  netbox_dns/templates/netbox_dns/view/prefix.html,sha256=Eaur1fd0YHeGttp2vRucz-ix7itxNu6To3NXwliGZco,1560
157
159
  netbox_dns/templates/netbox_dns/view/related.html,sha256=C5P6IuRmQ_S2hAC44ceFyNJn8JVqRxMwIXkS0dEL500,1239
158
- netbox_dns/templates/netbox_dns/zone/base.html,sha256=KqxYgIwCru1rc73Z9QfNbEXwX0QzALsMLv-oXtFcrUQ,525
160
+ netbox_dns/templates/netbox_dns/zone/base.html,sha256=TWmFHnwRNjtBxidmSbiF7DzUmb6Poc2wnKNZDq9Karw,552
159
161
  netbox_dns/templates/netbox_dns/zone/child.html,sha256=zvRHvgWiRmd58YlJCjVTPK4tdyH1UYXOJt8SzUuLMcM,2191
160
162
  netbox_dns/templates/netbox_dns/zone/child_zone.html,sha256=b9CSGWEfWT7hLQ80gApMnu7mXM8w2LT-3UaOYe6HIRQ,510
161
163
  netbox_dns/templates/netbox_dns/zone/delegation_record.html,sha256=bpJoyEYb5CVCoeH2260KMwwL6pUJxKA-Dt0qUruBEdk,517
@@ -169,7 +171,7 @@ netbox_dns/templatetags/netbox_dns.py,sha256=DND1DMPzv636Rak3M6Hor_Vw6pjqUfSTquo
169
171
  netbox_dns/utilities/__init__.py,sha256=cSGf-nGaRWx9b-Xrh3dLMJYoWNsZ6FF-qdmV4F1uOgg,74
170
172
  netbox_dns/utilities/conversions.py,sha256=qYnzecmR28l8Je_H0vFvzJ2sikTiEiyxr6drl_aRocg,3016
171
173
  netbox_dns/utilities/dns.py,sha256=UBiyQe8thiOTnKOmU9e2iRHHnGF9toVLe4efU623kX4,322
172
- netbox_dns/utilities/ipam_dnssync.py,sha256=_yuHoah_QN-opsZB51yGCkwjkij7nrmTgKHUZ-bQrBI,9625
174
+ netbox_dns/utilities/ipam_dnssync.py,sha256=cJ1P1RuLE_MmlF7yHuLXiv5TNBtinzj2dL7U4S7eAWw,10318
173
175
  netbox_dns/validators/__init__.py,sha256=X0hPZlC3VZcXMcvXKZ2_5LSoEJdXPNSBr4QtEIFSBJ0,94
174
176
  netbox_dns/validators/dns_name.py,sha256=1MKnYAmkSTIQGf6zInqkpbIj5SCeCM0YGKmYOqFzUK4,3770
175
177
  netbox_dns/validators/dns_value.py,sha256=cADhgTohXAtOLPzaoMKO9DahEUiDanpdiuKonrwFw0E,5278
@@ -184,10 +186,10 @@ netbox_dns/views/record_template.py,sha256=Cye1rjlpAewRgIv7QGD7o5n-knjzqjEUJzZHV
184
186
  netbox_dns/views/registrar.py,sha256=gYpMyz3rRJDmBfEeRfVENvR6fdWXN1y0XbN4JBlXoHc,2625
185
187
  netbox_dns/views/registration_contact.py,sha256=5bJWjNBisqCkBo6d2TJyyBJlc95WM7VcSA6wsEB184k,3383
186
188
  netbox_dns/views/view.py,sha256=xLXt7sKrda3FpNXsBSJk8L8P2XhZ1sVb5OOXovCsKEU,3089
187
- netbox_dns/views/zone.py,sha256=tJiQWMmcuWX6OBtsflQwoTNVjp_GzeZ3-jmywRp74ZU,7065
189
+ netbox_dns/views/zone.py,sha256=rxf0ETFnBF88JbhxUZWtcid_CAm7tssYfp2EFjk7zyg,7160
188
190
  netbox_dns/views/zone_template.py,sha256=5P9DT3XBRL-TiM5zFhBTMlMusL4bP2jTu3GHxKz5ojc,2553
189
- netbox_plugin_dns-1.3.1.dist-info/licenses/LICENSE,sha256=I3tDu11bZfhFm3EkV4zOD5TmWgLjnUNLEFwrdjniZYs,1112
190
- netbox_plugin_dns-1.3.1.dist-info/METADATA,sha256=WTrrtHmaWlCmJS3nQRbylLWz445zCDpvXyBzW058wq0,7787
191
- netbox_plugin_dns-1.3.1.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
192
- netbox_plugin_dns-1.3.1.dist-info/top_level.txt,sha256=sA1Rwl1mRKvMC6XHe2ylZ1GF-Q1NGd08XedK9Y4xZc4,11
193
- netbox_plugin_dns-1.3.1.dist-info/RECORD,,
191
+ netbox_plugin_dns-1.3.3.dist-info/licenses/LICENSE,sha256=I3tDu11bZfhFm3EkV4zOD5TmWgLjnUNLEFwrdjniZYs,1112
192
+ netbox_plugin_dns-1.3.3.dist-info/METADATA,sha256=UIlvFMPfFbgR1wHgZSwJNmjmqIjKbDKFSjRPkrB8G50,7787
193
+ netbox_plugin_dns-1.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
194
+ netbox_plugin_dns-1.3.3.dist-info/top_level.txt,sha256=sA1Rwl1mRKvMC6XHe2ylZ1GF-Q1NGd08XedK9Y4xZc4,11
195
+ netbox_plugin_dns-1.3.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.4.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5