netbox-plugin-dns 1.2.11__py3-none-any.whl → 1.2.13__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 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.2.11"
7
+ __version__ = "1.2.13"
8
8
 
9
9
 
10
10
  def _check_list(setting):
@@ -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.")
@@ -353,6 +353,21 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
353
353
  def is_delegation_record(self):
354
354
  return self in self.zone.delegation_records
355
355
 
356
+ def get_ptr_name(self, ptr_zone=None):
357
+ if ptr_zone is None:
358
+ ptr_zone = self.ptr_zone
359
+
360
+ if ptr_zone.is_rfc2317_zone:
361
+ ptr_name = self.rfc2317_ptr_name
362
+ else:
363
+ ptr_name = (
364
+ dns_name.from_text(ipaddress.ip_address(self.value).reverse_pointer)
365
+ .relativize(dns_name.from_text(ptr_zone.name))
366
+ .to_text()
367
+ )
368
+
369
+ return ptr_name
370
+
356
371
  def update_ptr_record(self, update_rfc2317_cname=True, save_zone_serial=True):
357
372
  ptr_zone = self.ptr_zone
358
373
 
@@ -368,15 +383,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
368
383
  self.ptr_record = None
369
384
  return
370
385
 
371
- if ptr_zone.is_rfc2317_zone:
372
- ptr_name = self.rfc2317_ptr_name
373
- else:
374
- ptr_name = (
375
- dns_name.from_text(ipaddress.ip_address(self.value).reverse_pointer)
376
- .relativize(dns_name.from_text(ptr_zone.name))
377
- .to_text()
378
- )
379
-
386
+ ptr_name = self.get_ptr_name(ptr_zone)
380
387
  ptr_value = self.fqdn
381
388
  ptr_record = self.ptr_record
382
389
 
@@ -647,6 +654,36 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
647
654
  }
648
655
  )
649
656
 
657
+ def check_unique_ptr_record(self):
658
+ if (
659
+ self.disable_ptr
660
+ or not self.is_active
661
+ or not self.is_address_record
662
+ or not (ptr_zone := self.ptr_zone)
663
+ or not get_plugin_config("netbox_dns", "enforce_unique_records", False)
664
+ ):
665
+ return
666
+
667
+ ptr_record = Record.objects.filter(
668
+ zone__view=self.zone.view,
669
+ zone=self.ptr_zone,
670
+ name=self.get_ptr_name(ptr_zone),
671
+ value=self.fqdn,
672
+ status__in=RECORD_ACTIVE_STATUS_LIST,
673
+ )
674
+
675
+ if not self._state.adding and self.ptr_record is not None:
676
+ ptr_record = ptr_record.exclude(pk=self.ptr_record.pk)
677
+
678
+ if ptr_record.exists():
679
+ raise ValidationError(
680
+ {
681
+ "value": _(
682
+ "There is already an active PTR record for {value} with value {fqdn}."
683
+ ).format(fqdn=self.fqdn, value=self.value)
684
+ }
685
+ )
686
+
650
687
  @property
651
688
  def absolute_value(self):
652
689
  if self.type in RecordTypeChoices.CUSTOM_TYPES:
@@ -790,6 +827,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
790
827
  self.validate_name(new_zone=new_zone)
791
828
  self.validate_value()
792
829
  self.check_unique_record(new_zone=new_zone)
830
+ self.check_unique_ptr_record()
793
831
  if self._state.adding:
794
832
  self.check_unique_rrset_ttl()
795
833
 
netbox_dns/models/zone.py CHANGED
@@ -664,6 +664,27 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
664
664
  }
665
665
  )
666
666
 
667
+ def check_ptr_records(self):
668
+ if self._state.adding:
669
+ return
670
+
671
+ validation_errors = []
672
+
673
+ address_records = self.records.filter(
674
+ type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA),
675
+ disable_ptr=False,
676
+ status__in=RECORD_ACTIVE_STATUS_LIST,
677
+ )
678
+
679
+ for record in address_records:
680
+ try:
681
+ record.check_unique_ptr_record()
682
+ except ValidationError as exc:
683
+ validation_errors.append(exc)
684
+
685
+ if validation_errors:
686
+ raise ValidationError(validation_errors)
687
+
667
688
  def get_auto_serial(self):
668
689
  records = Record.objects.filter(zone_id=self.pk).exclude(
669
690
  type=RecordTypeChoices.SOA
@@ -888,6 +909,8 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
888
909
  if self.is_reverse_zone:
889
910
  self.arpa_network = self.network_from_name
890
911
 
912
+ self.check_ptr_records()
913
+
891
914
  if self.is_rfc2317_zone:
892
915
  if self.arpa_network is not None:
893
916
  raise ValidationError(
@@ -156,6 +156,7 @@ class RecordView(generic.ObjectView):
156
156
 
157
157
  if Zone.objects.filter(
158
158
  active=True,
159
+ view=instance.zone.view,
159
160
  name__iregex=regex_from_list(
160
161
  get_parent_zone_names(
161
162
  instance.fqdn,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-plugin-dns
3
- Version: 1.2.11
3
+ Version: 1.2.13
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,4 +1,4 @@
1
- netbox_dns/__init__.py,sha256=J3IJiBb3U8rQEKBa-KZ1ArvhWpqxHgtz5pA2Fngr-jY,4891
1
+ netbox_dns/__init__.py,sha256=ypuFIfHwUIr6Bnloc-3OMM0JZQC0I_zn8vDO_NnXBc4,4891
2
2
  netbox_dns/apps.py,sha256=JCW5eS-AQBUubDJve1DjP-IRFKTFGQh1NLGWzJpC5MI,151
3
3
  netbox_dns/navigation.py,sha256=u90MwWBySg1Z9yfZEdvUctYWEkab5z1Y3019J7U_-3g,7741
4
4
  netbox_dns/template_content.py,sha256=irgHJe91TnmmL9K1Xnv07uGmOeJMn9zTrIKtJev88XI,4283
@@ -65,6 +65,7 @@ netbox_dns/locale/fr/LC_MESSAGES/django.mo,sha256=vL8TcVYyBiDFZ3GVdZe4Kkc42mmtbM
65
65
  netbox_dns/management/commands/cleanup_database.py,sha256=1-tAl0Sht80qaNZyfFyUW19Eh9gBUuc7GdbHN4aemGU,5935
66
66
  netbox_dns/management/commands/cleanup_rrset_ttl.py,sha256=UFRURLBcFeGHUS2lrYFv7UWIebjI72aG1EUQJt0XsXw,2046
67
67
  netbox_dns/management/commands/rebuild_dnssync.py,sha256=Tcl385u6kJTX47SvSyRzKm1RIx4nYRYCMcKr3uVnV60,1246
68
+ netbox_dns/management/commands/remove_orphaned_ptr_records.py,sha256=vYYvI2yr4U1EiAoWm26PkULzaz3rr_Yfaw2eg9i4oIw,1142
68
69
  netbox_dns/management/commands/setup_dnssync.py,sha256=qtVj6egSjclaQbuI60hLfl-zg89VJVbX-TB17f1k77Y,5730
69
70
  netbox_dns/management/commands/update_soa.py,sha256=Rj_Xk-qpwkAVRubVnM5OqSTwgzi93E0PqjwGb3rYjf0,660
70
71
  netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py,sha256=3U0810NWSHPu2dTSHpfzlleDgwMS04FhJ_CkO76SDaw,10283
@@ -105,12 +106,12 @@ netbox_dns/models/__init__.py,sha256=CuwFENIVUv0FNMDlY18Am-mvN5kBGkPOGavCP0cle7c
105
106
  netbox_dns/models/dnssec_key_template.py,sha256=h6YniKfLx1ILAbvko6Mps-bhsI743uHIOiLgtfStZTI,2790
106
107
  netbox_dns/models/dnssec_policy.py,sha256=eD13F_zTUgpP8fNGg0FssMNBUtpBRvkJiM6ZSYh1Pws,5466
107
108
  netbox_dns/models/nameserver.py,sha256=ivZpIVfgQLdDhrtqYPi-zRbygVgl3aff2FMsq1M3qA8,4044
108
- netbox_dns/models/record.py,sha256=GAl4JQCGX5Ip_R4zAQ-ZA-2Kn-Pr7zBmSgFCGsfbM5M,29806
109
+ netbox_dns/models/record.py,sha256=cchwU_KO0qIL9gKbrjZH4ZXF-utl4bZGU4nTiVjFBRo,31040
109
110
  netbox_dns/models/record_template.py,sha256=kt-_sMFSMKmuKU8voVqz1-Lh7Wi7lPcA2ExPFQYLoxM,5345
110
111
  netbox_dns/models/registrar.py,sha256=L5tbO8rtOa0VCs_y90nHYLKSRKBnnUhh_6sxZ3Mm2kk,1942
111
112
  netbox_dns/models/registration_contact.py,sha256=O7T1clUjuilZnDjvhJKaHZdmNEF4aLg2h8K5p4llWOs,3825
112
113
  netbox_dns/models/view.py,sha256=gQvKNr_FmhG2EMz2T8kWbdK4b8CyqI-Qc67-Dgrx2SI,4808
113
- netbox_dns/models/zone.py,sha256=oKPWEFfe6AHea4mV1Z28U4TpusMK7-o-mEsch4rZkKE,35830
114
+ netbox_dns/models/zone.py,sha256=YWJuase7OyXbMfJ9O7lV673Gu5X04uItI1YyM_5pgsE,36466
114
115
  netbox_dns/models/zone_template.py,sha256=TpM4LNBStwoyHXkvMGa8zUdBp28ZnauolkbFntt9hPk,5249
115
116
  netbox_dns/signals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
117
  netbox_dns/signals/dnssec.py,sha256=o4MOEg6ftxoDWFAhDtajkXzb7Nb6KuUHjtx1zNu7C1w,1040
@@ -166,15 +167,15 @@ netbox_dns/views/__init__.py,sha256=tObkTOHw_6kVtEcwdyshN0Ql-8VGhwsgQw7owL_s2lI,
166
167
  netbox_dns/views/dnssec_key_template.py,sha256=TfBtODl7EzGvmC2NVDLd-P1zMalLCjClb9pKgPzIsBk,3050
167
168
  netbox_dns/views/dnssec_policy.py,sha256=7bQRr9X-7U4RM3I_9k-SEfX2_WoZnHlbGpgXTG_HH7M,4807
168
169
  netbox_dns/views/nameserver.py,sha256=6lHg8fqBjc_SoITzFj1FiRARpPF7nSn9knAZxe9x5Rg,3932
169
- netbox_dns/views/record.py,sha256=6tOTC7BbQ5XOC7wr94LjFMR3epOi47HP5qIETNvj5sE,6715
170
+ netbox_dns/views/record.py,sha256=lplgHzGABrucFB5Kflu7IhGpVyn2g7pEvExYafioCD8,6760
170
171
  netbox_dns/views/record_template.py,sha256=CbSyckBvyEvcZCeZgK3q0fJsa1_5HbwUflh_iM7JjH0,3134
171
172
  netbox_dns/views/registrar.py,sha256=Um_2wnzmP2bqbdMUhBPhny2My0R8fMXScQ9GLiTCrvg,2808
172
173
  netbox_dns/views/registration_contact.py,sha256=c9KrNkfFNsb55pL74A5rN1CNx32M82V6mdwBYduNxas,3596
173
174
  netbox_dns/views/view.py,sha256=VfrKaLC9D_KNZNmRyFVohRlmMlMbtblAuPgNg0LNyf8,3421
174
175
  netbox_dns/views/zone.py,sha256=DU_esPOMHGMRQIgy5vS8miZe-FNozBcIyMLZPwZK4_c,7453
175
176
  netbox_dns/views/zone_template.py,sha256=IIW1lr6RQmhShtqJu6A6LnHdxdBrkkZQHxIDSTqQeyc,2705
176
- netbox_plugin_dns-1.2.11.dist-info/licenses/LICENSE,sha256=I3tDu11bZfhFm3EkV4zOD5TmWgLjnUNLEFwrdjniZYs,1112
177
- netbox_plugin_dns-1.2.11.dist-info/METADATA,sha256=f5dwyaXsyAwarK5_ELsBgX9CMlxQ9mXxoulyzHeGVAU,7659
178
- netbox_plugin_dns-1.2.11.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
179
- netbox_plugin_dns-1.2.11.dist-info/top_level.txt,sha256=sA1Rwl1mRKvMC6XHe2ylZ1GF-Q1NGd08XedK9Y4xZc4,11
180
- netbox_plugin_dns-1.2.11.dist-info/RECORD,,
177
+ netbox_plugin_dns-1.2.13.dist-info/licenses/LICENSE,sha256=I3tDu11bZfhFm3EkV4zOD5TmWgLjnUNLEFwrdjniZYs,1112
178
+ netbox_plugin_dns-1.2.13.dist-info/METADATA,sha256=tPSQO9L5Vo1nWGJk17xt78APuRsd5M4pXTDPw6nw8zo,7659
179
+ netbox_plugin_dns-1.2.13.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
180
+ netbox_plugin_dns-1.2.13.dist-info/top_level.txt,sha256=sA1Rwl1mRKvMC6XHe2ylZ1GF-Q1NGd08XedK9Y4xZc4,11
181
+ netbox_plugin_dns-1.2.13.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.1.0)
2
+ Generator: setuptools (80.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5