netbox-plugin-dns 1.3.3__py3-none-any.whl → 1.3.5__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.3.3"
7
+ __version__ = "1.3.5"
8
8
 
9
9
 
10
10
  def _check_list(setting):
@@ -1,176 +1,205 @@
1
- from netaddr import IPAddress, IPNetwork, AddrFormatError
1
+ from netaddr import IPAddress
2
2
 
3
3
  from django.core.management.base import BaseCommand
4
4
 
5
5
  from netbox_dns.models import Zone, Record
6
- from netbox_dns.choices import ZoneStatusChoices, RecordTypeChoices
6
+ from netbox_dns.choices import RecordTypeChoices
7
7
 
8
8
 
9
- def zone_rename_passive_status_to_parked(verbose=False):
10
- passive_zones = Zone.objects.filter(status="passive")
11
- if passive_zones:
12
- if verbose:
13
- print("Renaming 'passive' zone status to 'parked'")
14
-
15
- for zone in passive_zones:
16
- zone.status = ZoneStatusChoices.STATUS_PARKED
17
- zone.save()
18
-
19
-
20
- def zone_cleanup_ns_records(verbose=False):
21
- ns_name = "@"
22
-
23
- for zone in Zone.objects.all():
24
- nameservers = zone.nameservers.all()
25
- nameserver_names = [f'{ns.name.rstrip(".")}.' for ns in nameservers]
26
-
27
- delete_ns = zone.records.filter(
28
- name=ns_name, type=RecordTypeChoices.NS
29
- ).exclude(value__in=nameserver_names)
30
- for record in delete_ns:
31
- if verbose:
32
- print(f"Deleting obsolete NS record {record}")
33
- record.delete()
34
-
35
- for ns in nameserver_names:
36
- ns_records = zone.records.filter(
37
- name=ns_name,
38
- type=RecordTypeChoices.NS,
39
- value=ns,
40
- )
9
+ class Command(BaseCommand):
10
+ help = "Clean up NetBox DNS database"
41
11
 
42
- delete_ns = ns_records[1:]
12
+ def handle(self, *model_names, **options):
13
+ self._zone_cleanup_ns_records(**options)
14
+ self._zone_cleanup_soa_records(**options)
15
+ self._zone_update_arpa_network(**options)
16
+ self._record_cleanup_disable_ptr(**options)
17
+ self._record_update_ptr_records(**options)
18
+ self._record_update_ip_address(**options)
19
+ self._record_remove_orphaned_ptr_records(**options)
20
+ self._record_remove_orphaned_address_records(**options)
21
+
22
+ if options.get("verbosity"):
23
+ self.stdout.write("Database cleanup completed.")
24
+
25
+ def _zone_cleanup_ns_records(self, **options):
26
+ if options.get("verbosity"):
27
+ self.stdout.write("Cleaning up the NS records for all zones")
28
+
29
+ ns_name = "@"
30
+
31
+ for zone in Zone.objects.all():
32
+ nameservers = zone.nameservers.all()
33
+ nameserver_names = [f'{ns.name.rstrip(".")}.' for ns in nameservers]
34
+
35
+ delete_ns = zone.records.filter(
36
+ name=ns_name, type=RecordTypeChoices.NS
37
+ ).exclude(value__in=nameserver_names)
43
38
  for record in delete_ns:
44
- if verbose:
45
- print(f"Deleting duplicate NS record {record}")
39
+ if options.get("verbosity") > 1:
40
+ self.stdout.write(
41
+ f"Removing obsolete NS record '{record}' with value '{record.value}'"
42
+ )
46
43
  record.delete()
47
44
 
48
- try:
49
- ns_record = zone.records.get(
45
+ for ns in nameserver_names:
46
+ ns_records = zone.records.filter(
50
47
  name=ns_name,
51
48
  type=RecordTypeChoices.NS,
52
49
  value=ns,
53
50
  )
54
51
 
55
- if ns_record.ttl is not None or not ns_record.managed:
56
- if verbose:
57
- print(f"Updating NS record '{ns_record}'")
58
- ns_record.ttl = None
59
- ns_record.managed = True
60
- ns_record.save()
61
-
62
- except Record.DoesNotExist:
63
- if verbose:
64
- print(f"Creating NS record for '{ns.rstrip('.')}' in zone '{zone}'")
65
- Record.objects.create(
66
- name=ns_name,
67
- zone=zone,
68
- type=RecordTypeChoices.NS,
69
- value=ns,
70
- ttl=None,
71
- managed=True,
72
- )
52
+ delete_ns = ns_records[1:]
53
+ for record in delete_ns:
54
+ if options.get("verbosity") > 1:
55
+ self.stdout.write(
56
+ f"Removing duplicate NS record '{record}' with value '{record.value}'"
57
+ )
58
+ record.delete()
59
+
60
+ try:
61
+ ns_record = zone.records.get(
62
+ name=ns_name,
63
+ type=RecordTypeChoices.NS,
64
+ value=ns,
65
+ )
73
66
 
67
+ if ns_record.ttl is not None or not ns_record.managed:
68
+ if options.get("verbosity") > 1:
69
+ self.stdout.write(
70
+ f"Updating NS record '{ns_record}' with value '{record.value}'"
71
+ )
72
+ ns_record.ttl = None
73
+ ns_record.managed = True
74
+ ns_record.save()
75
+
76
+ except Record.DoesNotExist:
77
+ if options.get("verbosity") > 1:
78
+ self.stdout.write(
79
+ f"Creating NS record for '{ns.rstrip('.')}' in zone '{zone}'"
80
+ )
81
+ Record.objects.create(
82
+ name=ns_name,
83
+ zone=zone,
84
+ type=RecordTypeChoices.NS,
85
+ value=ns,
86
+ ttl=None,
87
+ managed=True,
88
+ )
74
89
 
75
- def zone_update_soa_records(verbose=False):
76
- soa_name = "@"
90
+ def _zone_cleanup_soa_records(self, **options):
91
+ if options.get("verbosity"):
92
+ self.stdout.write("Cleaning up the SOA record for all zones")
77
93
 
78
- for zone in Zone.objects.all():
79
- delete_soa = zone.records.filter(name=soa_name, type=RecordTypeChoices.SOA)[1:]
80
- for record in delete_soa:
81
- if verbose:
82
- print(f"Deleting duplicate SOA record {record}")
83
- record.delete()
94
+ soa_name = "@"
84
95
 
85
- zone.update_soa_record()
96
+ for zone in Zone.objects.all():
97
+ delete_soa = zone.records.filter(name=soa_name, type=RecordTypeChoices.SOA)[
98
+ 1:
99
+ ]
100
+ for record in delete_soa:
101
+ if options.get("verbosity") > 1:
102
+ self.stdout.write(
103
+ f"Deleting duplicate SOA record '{record}' for zone '{zone}'"
104
+ )
105
+ record.delete()
86
106
 
107
+ zone.update_soa_record()
87
108
 
88
- def zone_update_arpa_network(verbose=False):
89
- for zone in Zone.objects.filter(name__endswith=".arpa"):
90
- name = zone.name
109
+ def _zone_update_arpa_network(self, **options):
110
+ if options.get("verbosity"):
111
+ self.stdout.write("Updating the ARPA network for reverse zones")
91
112
 
92
- # TODO: Rewrite with utility function
93
- if name.endswith(".in-addr.arpa"):
94
- address = ".".join(reversed(name.replace(".in-addr.arpa", "").split(".")))
95
- mask = len(address.split(".")) * 8
113
+ for zone in Zone.objects.filter(name__endswith=".arpa"):
114
+ if zone.arpa_network != (arpa_network := zone.network_from_name):
115
+ if options.get("verbosity") > 1:
116
+ self.stdout.write(
117
+ f"Setting the ARPA network for zone '{zone}' to '{arpa_network}'"
118
+ )
96
119
 
97
- try:
98
- prefix = IPNetwork(f"{address}/{mask}")
99
- except AddrFormatError:
100
- prefix = None
120
+ zone.arpa_network = arpa_network
121
+ zone.save()
101
122
 
102
- elif name.endswith("ip6.arpa"):
103
- address = "".join(reversed(name.replace(".ip6.arpa", "").split(".")))
104
- mask = len(address)
105
- address = address + "0" * (32 - mask)
123
+ def _record_cleanup_disable_ptr(self, **options):
124
+ if options.get("verbosity"):
125
+ self.stdout.write("Updating 'Disable PTR' for non-address records")
106
126
 
107
- try:
108
- prefix = IPNetwork(
109
- f"{':'.join([(address[i:i+4]) for i in range(0, 32, 4)])}/{mask*4}"
127
+ records = Record.objects.filter(
128
+ disable_ptr=True,
129
+ ).exclude(type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA))
130
+
131
+ for record in records:
132
+ if options.get("verbosity") > 1:
133
+ self.stdout.write(
134
+ f"Setting 'Disable PTR' to False for record '{record}'"
110
135
  )
111
- except AddrFormatError:
112
- prefix = None
113
- # TODO: End
114
-
115
- if zone.arpa_network != prefix:
116
- if verbose:
117
- print(f"Updating ARPA prefix for zone '{zone}' to '{prefix}'")
118
- zone.arpa_network = prefix
119
- zone.save()
120
-
121
-
122
- def record_cleanup_disable_ptr(verbose=False):
123
- Record.objects.filter(
124
- disable_ptr=False,
125
- ).exclude(
126
- type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA)
127
- ).update(disable_ptr=True)
128
-
129
-
130
- def record_update_ptr_records(verbose=False):
131
- for record in Record.objects.filter(
132
- type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA)
133
- ):
134
- record.save(update_fields=["ptr_record"])
135
-
136
-
137
- def record_update_ip_address(verbose=False):
138
- for record in Record.objects.filter(
139
- type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA, RecordTypeChoices.PTR)
140
- ):
141
- if record.is_ptr_record:
142
- if record.ip_address != record.address_from_name:
143
- if verbose:
144
- print(
145
- f"Updating IP address of pointer record {record} to {record.address_from_name}"
146
- )
147
- record.ip_address = record.address_from_name
148
- record.save()
149
- else:
150
- if record.ip_address != IPAddress(record.value):
151
- if verbose:
152
- print(
153
- f"Updating IP address of address record {record} to {IPAddress(record.value)}"
154
- )
155
- record.ip_address = record.value
156
- record.save()
157
136
 
137
+ record.disable_ptr = False
138
+ record.save(update_fields=["disable_ptr"])
158
139
 
159
- class Command(BaseCommand):
160
- help = "Clean up NetBox DNS database"
140
+ def _record_update_ptr_records(self, **options):
141
+ if options.get("verbosity"):
142
+ self.stdout.write("Updating the PTR record for all address records")
143
+
144
+ for record in Record.objects.filter(
145
+ type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA)
146
+ ):
147
+ record.save(update_fields=["ptr_record"])
161
148
 
162
- def add_arguments(self, parser):
163
- parser.add_argument(
164
- "--verbose", action="store_true", help="Increase output verbosity"
149
+ def _record_update_ip_address(self, **options):
150
+ if options.get("verbosity"):
151
+ self.stdout.write("Updating the IP address for all address and PTR records")
152
+
153
+ for record in Record.objects.filter(
154
+ type__in=(
155
+ RecordTypeChoices.A,
156
+ RecordTypeChoices.AAAA,
157
+ RecordTypeChoices.PTR,
158
+ )
159
+ ):
160
+ if record.is_ptr_record:
161
+ if record.ip_address != record.address_from_name:
162
+ if options.get("verbosity") > 1:
163
+ self.stdout.write(
164
+ f"Setting the IP Address for pointer record '{record}' to '{record.address_from_name}'"
165
+ )
166
+ record.ip_address = record.address_from_name
167
+ record.save()
168
+ else:
169
+ if record.ip_address != IPAddress(record.value):
170
+ if options.get("verbosity") > 1:
171
+ self.stdout.write(
172
+ f"Updating the IP address for address record '{record}' to '{IPAddress(record.value)}'"
173
+ )
174
+ record.ip_address = record.value
175
+ record.save()
176
+
177
+ def _record_remove_orphaned_ptr_records(self, **options):
178
+ if options.get("verbosity"):
179
+ self.stdout.write("Removing orphaned managed PTR records")
180
+
181
+ orphaned_ptr_records = Record.objects.filter(
182
+ type=RecordTypeChoices.PTR,
183
+ managed=True,
184
+ address_records__isnull=True,
165
185
  )
166
186
 
167
- def handle(self, *model_names, **options):
168
- zone_rename_passive_status_to_parked(options["verbose"])
169
- zone_cleanup_ns_records(options["verbose"])
170
- zone_update_soa_records(options["verbose"])
171
- zone_update_arpa_network(options["verbose"])
172
- record_cleanup_disable_ptr(options["verbose"])
173
- record_update_ptr_records(options["verbose"])
174
- record_update_ip_address(options["verbose"])
175
-
176
- self.stdout.write("Database cleanup completed.")
187
+ for record in orphaned_ptr_records:
188
+ if options.get("verbosity") > 1:
189
+ self.stdout.write("Removing orphaned PTR record '{record}'")
190
+ record.delete()
191
+
192
+ def _record_remove_orphaned_address_records(self, **options):
193
+ if options.get("verbosity"):
194
+ self.stdout.write("Removing orphaned managed address records")
195
+
196
+ orphaned_address_records = Record.objects.filter(
197
+ type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA),
198
+ managed=True,
199
+ ipam_ip_address__isnull=True,
200
+ )
201
+
202
+ for record in orphaned_address_records:
203
+ if options.get("verbosity") > 1:
204
+ self.stdout.write("Removing orphaned address record '{record}'")
205
+ record.delete()
@@ -22,11 +22,12 @@ class Command(BaseCommand):
22
22
  )
23
23
 
24
24
  def handle(self, *model_names, **options):
25
- self.cleanup_rrset_ttl(**options)
25
+ self._cleanup_rrset_ttl(**options)
26
26
 
27
- self.stdout.write("RRSet cleanup completed.")
27
+ def _cleanup_rrset_ttl(self, **options):
28
+ if options.get("verbosity"):
29
+ self.stdout.write("Cleaning up diverging RRset TTL values")
28
30
 
29
- def cleanup_rrset_ttl(self, **options):
30
31
  ttl_records = (
31
32
  Record.objects.filter(ttl__isnull=False)
32
33
  .exclude(type=RecordTypeChoices.SOA)
@@ -37,11 +38,13 @@ class Command(BaseCommand):
37
38
  name=record.name,
38
39
  zone=record.zone,
39
40
  type=record.type,
40
- ).exclude(type=RecordTypeChoices.PTR, maanged=True)
41
+ ).exclude(type=RecordTypeChoices.PTR, managed=True)
41
42
 
42
43
  if records.count() == 1:
43
44
  if options.get("verbosity") > 2:
44
- self.stdout.write(f"Ignoring single record {record.pk} ({record})")
45
+ self.stdout.write(
46
+ f"Ignoring single record '{record.pk}' ('{record}')"
47
+ )
45
48
  continue
46
49
 
47
50
  if options.get("max"):
@@ -52,7 +55,10 @@ class Command(BaseCommand):
52
55
  for record in records.exclude(ttl=ttl):
53
56
  if options.get("verbosity") > 1:
54
57
  self.stdout.write(
55
- f"Updating TTL for record {record.pk} ({record}) to {ttl}"
58
+ f"Setting TTL for record '{record.pk}' ('{record}') to {ttl}"
56
59
  )
57
60
  record.ttl = ttl
58
61
  record.save(update_fields=["ttl"], update_rrset_ttl=False)
62
+
63
+ if options.get("verbosity"):
64
+ self.stdout.write("RRSet TTL cleanup completed.")
@@ -12,7 +12,7 @@ class Command(BaseCommand):
12
12
  parser.add_argument(
13
13
  "--force",
14
14
  action="store_true",
15
- help="Update records even if DNS name was not changed (required for rebuilding filtered views",
15
+ help="Update records even if DNS name was not changed (required for rebuilding filtered views)",
16
16
  )
17
17
 
18
18
  def handle(self, *model_names, **options):
@@ -418,6 +418,26 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
418
418
  ):
419
419
  return
420
420
 
421
+ # +
422
+ # If the existing PTR record no longer matches the address record,
423
+ # check whether there is an existing PTR record that does. In that
424
+ # case, mark the old PTR record for cleanup and use the existing one.
425
+ # -
426
+ try:
427
+ existing_ptr_record = Record.objects.get(
428
+ name=ptr_name,
429
+ zone=ptr_zone,
430
+ type=RecordTypeChoices.PTR,
431
+ value=ptr_value,
432
+ )
433
+
434
+ self.cleanup_ptr_record = self.ptr_record
435
+ self.ptr_record = existing_ptr_record
436
+ ptr_record = self.ptr_record
437
+
438
+ except Record.DoesNotExist:
439
+ pass
440
+
421
441
  # +
422
442
  # If there is an RFC2317 CNAME for the PTR record and it is either
423
443
  # not required or needs to be changed, remove it.
@@ -435,10 +455,12 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
435
455
  # modified to match the new name, zone, value and TTL.
436
456
  # -
437
457
  if ptr_record.address_records.count() == 1:
458
+ ptr_record.snapshot()
438
459
  ptr_record.zone = ptr_zone
439
460
  ptr_record.name = ptr_name
440
461
  ptr_record.value = ptr_value
441
462
  ptr_record.ttl = self.ttl
463
+ ptr_record.managed = True
442
464
  ptr_record.save(
443
465
  update_rfc2317_cname=update_rfc2317_cname,
444
466
  save_zone_serial=save_zone_serial,
@@ -447,7 +469,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
447
469
 
448
470
  # +
449
471
  # 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.
472
+ # so we need to either find a matching PTR record or create a new one.
451
473
  # -
452
474
  try:
453
475
  ptr_record = Record.objects.get(
@@ -846,6 +868,9 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
846
868
  if self._state.adding:
847
869
  self.check_unique_rrset_ttl()
848
870
 
871
+ if not self.is_address_record:
872
+ self.disable_ptr = False
873
+
849
874
  if not self.is_active:
850
875
  return
851
876
 
netbox_dns/models/zone.py CHANGED
@@ -550,7 +550,12 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
550
550
  try:
551
551
  soa_record = self.records.get(type=RecordTypeChoices.SOA, name=soa_name)
552
552
 
553
- if soa_record.ttl != soa_ttl or soa_record.value != soa_rdata.to_text():
553
+ if (
554
+ soa_record.ttl != soa_ttl
555
+ or soa_record.value != soa_rdata.to_text()
556
+ or not soa_record.managed
557
+ ):
558
+ soa_record.snapshot()
554
559
  soa_record.ttl = soa_ttl
555
560
  soa_record.value = soa_rdata.to_text()
556
561
  soa_record.managed = True
@@ -177,6 +177,8 @@ def update_dns_records(ip_address, view=None, force=False):
177
177
  address_records = ip_address.netbox_dns_records.filter(zone__view=view)
178
178
 
179
179
  for record in address_records:
180
+ record.snapshot()
181
+
180
182
  if record.zone not in zones or ip_address.custom_field_data.get(
181
183
  "ipaddress_dns_disabled"
182
184
  ):
@@ -227,10 +229,15 @@ def delete_dns_records(ip_address, view=None):
227
229
  # TODO: Find something better. This is really awful.
228
230
  # -
229
231
  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,
232
+ Q(
233
+ Q(ipam_ip_address=ip_address)
234
+ | Q(
235
+ type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA),
236
+ managed=True,
237
+ ip_address=ip_address.address,
238
+ ipam_ip_address__isnull=True,
239
+ )
240
+ ),
234
241
  )
235
242
 
236
243
  if view is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-plugin-dns
3
- Version: 1.3.3
3
+ Version: 1.3.5
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=MVztNOPEPnEVgDW3bm96rasp3q0E34dt-SgScdi7_Lg,4890
1
+ netbox_dns/__init__.py,sha256=-aNWTjZrScH61wzPGKzqdWwZf8ojcrz1HXDy7OBqi1o,4890
2
2
  netbox_dns/apps.py,sha256=JCW5eS-AQBUubDJve1DjP-IRFKTFGQh1NLGWzJpC5MI,151
3
3
  netbox_dns/navigation.py,sha256=ZF2-bKRfuxXnLArSCvozyRXRd7GME14sVJZdmDEMhBk,7741
4
4
  netbox_dns/template_content.py,sha256=nwjbWkMc02vpTmcFQdiAA1TdopJiZ0MkRy6qa18_wLI,4848
@@ -74,12 +74,10 @@ netbox_dns/graphql/filters/zone_template.py,sha256=6ZxBN_VPXvBDGXXwcYlkX6wJXx_Il
74
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
76
  netbox_dns/locale/fr/LC_MESSAGES/django.mo,sha256=hZjbClaXZndP8VtqAiXWBdYEFVD9CQrKJXelL6kMOPE,30021
77
- netbox_dns/management/commands/cleanup_database.py,sha256=1-tAl0Sht80qaNZyfFyUW19Eh9gBUuc7GdbHN4aemGU,5935
78
- netbox_dns/management/commands/cleanup_rrset_ttl.py,sha256=UFRURLBcFeGHUS2lrYFv7UWIebjI72aG1EUQJt0XsXw,2046
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
77
+ netbox_dns/management/commands/cleanup_database.py,sha256=bkMdDlZpSzqIRx18N86wyda2ufFzNlejefyeRdHg5Nk,7951
78
+ netbox_dns/management/commands/cleanup_rrset_ttl.py,sha256=7W4_qRzm_Crnb1L4X8lfrXRJanBqDGLC1yCLvrIaGG4,2256
79
+ netbox_dns/management/commands/rebuild_dnssync.py,sha256=SlY-NsMu4BJ7Bi1lnswfVHjhCzsgL6hRue6pJXSO_0w,1247
81
80
  netbox_dns/management/commands/setup_dnssync.py,sha256=qtVj6egSjclaQbuI60hLfl-zg89VJVbX-TB17f1k77Y,5730
82
- netbox_dns/management/commands/update_soa.py,sha256=Rj_Xk-qpwkAVRubVnM5OqSTwgzi93E0PqjwGb3rYjf0,660
83
81
  netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py,sha256=3U0810NWSHPu2dTSHpfzlleDgwMS04FhJ_CkO76SDaw,10283
84
82
  netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py,sha256=ML6Hp17lrXiaG0eUlBjKMm6HUNhw0AHPnKrb9AN-F6E,20279
85
83
  netbox_dns/migrations/0002_contact_description_registrar_description.py,sha256=ZrI-L3jJ5GzdVx21pomgM4waE-njixHQjl_grjsGr0I,583
@@ -120,12 +118,12 @@ netbox_dns/models/__init__.py,sha256=CuwFENIVUv0FNMDlY18Am-mvN5kBGkPOGavCP0cle7c
120
118
  netbox_dns/models/dnssec_key_template.py,sha256=Nv0vjdkOFWMptRYR1sT60bM6D8n_SnCpPZhI7WE5_UQ,2588
121
119
  netbox_dns/models/dnssec_policy.py,sha256=REsE8p04bgJVF8yJuWuUITXpsZmvVlXWyQuJ9I6dEMs,5268
122
120
  netbox_dns/models/nameserver.py,sha256=oVfyc_iWRzxVE2tIhfRb1Vuj2gZmlfFFzEtXj9ZEr6s,3848
123
- netbox_dns/models/record.py,sha256=2HSxvroCGhvb7eg4qSXl1ACN7yzGGywbyBjhPR6siEk,31867
121
+ netbox_dns/models/record.py,sha256=7f4h3ngUvPpQ4IQroTJAWO8wD2fqy1u8j-LuA23PWtM,32761
124
122
  netbox_dns/models/record_template.py,sha256=Qr43_YZm1z3Od1cBdDY9wpNlV-UCzvpn2c6_dDzFzN8,5145
125
123
  netbox_dns/models/registrar.py,sha256=-ozazecvd-oryEoDlOUvTWhEQKKQp3my6YVTEzWlUuI,1747
126
124
  netbox_dns/models/registration_contact.py,sha256=9ehnTjg8KUrUYJKRRu2SaJX-NE5dO4wy90FRPlT2ys4,3620
127
125
  netbox_dns/models/view.py,sha256=pwo7i8gtukIRgAC1A4rm58jcEpIbsSW_IUq6vSv-mRo,4618
128
- netbox_dns/models/zone.py,sha256=8MB8p6R9K-5K8eR2AKZXb6rwnnWDvcd-_KFLi5JqviQ,35825
126
+ netbox_dns/models/zone.py,sha256=qZ5yYNbj4mYm61zfq-aFL_5sVSxJo1PQSMY4cAj8vEQ,35953
129
127
  netbox_dns/models/zone_template.py,sha256=ShPg6_ts6W-dpdGzUg3oZnGHEEQ-_Jf0EdYwVWzaPwI,5093
130
128
  netbox_dns/signals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
129
  netbox_dns/signals/dnssec.py,sha256=o4MOEg6ftxoDWFAhDtajkXzb7Nb6KuUHjtx1zNu7C1w,1040
@@ -171,7 +169,7 @@ netbox_dns/templatetags/netbox_dns.py,sha256=DND1DMPzv636Rak3M6Hor_Vw6pjqUfSTquo
171
169
  netbox_dns/utilities/__init__.py,sha256=cSGf-nGaRWx9b-Xrh3dLMJYoWNsZ6FF-qdmV4F1uOgg,74
172
170
  netbox_dns/utilities/conversions.py,sha256=qYnzecmR28l8Je_H0vFvzJ2sikTiEiyxr6drl_aRocg,3016
173
171
  netbox_dns/utilities/dns.py,sha256=UBiyQe8thiOTnKOmU9e2iRHHnGF9toVLe4efU623kX4,322
174
- netbox_dns/utilities/ipam_dnssync.py,sha256=cJ1P1RuLE_MmlF7yHuLXiv5TNBtinzj2dL7U4S7eAWw,10318
172
+ netbox_dns/utilities/ipam_dnssync.py,sha256=qVbJAL2GcTpKZaz4XBfTc4Gn8xREukQy0VvhK6jIpQ8,10493
175
173
  netbox_dns/validators/__init__.py,sha256=X0hPZlC3VZcXMcvXKZ2_5LSoEJdXPNSBr4QtEIFSBJ0,94
176
174
  netbox_dns/validators/dns_name.py,sha256=1MKnYAmkSTIQGf6zInqkpbIj5SCeCM0YGKmYOqFzUK4,3770
177
175
  netbox_dns/validators/dns_value.py,sha256=cADhgTohXAtOLPzaoMKO9DahEUiDanpdiuKonrwFw0E,5278
@@ -188,8 +186,8 @@ netbox_dns/views/registration_contact.py,sha256=5bJWjNBisqCkBo6d2TJyyBJlc95WM7Vc
188
186
  netbox_dns/views/view.py,sha256=xLXt7sKrda3FpNXsBSJk8L8P2XhZ1sVb5OOXovCsKEU,3089
189
187
  netbox_dns/views/zone.py,sha256=rxf0ETFnBF88JbhxUZWtcid_CAm7tssYfp2EFjk7zyg,7160
190
188
  netbox_dns/views/zone_template.py,sha256=5P9DT3XBRL-TiM5zFhBTMlMusL4bP2jTu3GHxKz5ojc,2553
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,,
189
+ netbox_plugin_dns-1.3.5.dist-info/licenses/LICENSE,sha256=I3tDu11bZfhFm3EkV4zOD5TmWgLjnUNLEFwrdjniZYs,1112
190
+ netbox_plugin_dns-1.3.5.dist-info/METADATA,sha256=eG5VsqM5B-Boc4GvUAc8VG7GuUQTXiFkcrMHEz0I1WA,7787
191
+ netbox_plugin_dns-1.3.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
192
+ netbox_plugin_dns-1.3.5.dist-info/top_level.txt,sha256=sA1Rwl1mRKvMC6XHe2ylZ1GF-Q1NGd08XedK9Y4xZc4,11
193
+ netbox_plugin_dns-1.3.5.dist-info/RECORD,,
@@ -1,35 +0,0 @@
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.")
@@ -1,22 +0,0 @@
1
- from django.core.management.base import BaseCommand
2
-
3
- from netbox_dns.models import Zone
4
-
5
-
6
- class Command(BaseCommand):
7
- help = "Create or update SOA records for all zones"
8
-
9
- def add_arguments(self, parser):
10
- parser.add_argument(
11
- "--verbose", action="store_true", help="Increase output verbosity"
12
- )
13
-
14
- def handle(self, *model_names, **options):
15
- zones = Zone.objects.all()
16
-
17
- for zone in zones:
18
- if options["verbose"]:
19
- self.stdout.write(f"Updating the SOA record for zone {zone.name}")
20
- zone.update_soa_record()
21
-
22
- self.stdout.write("All SOA records have been updated")