netbox-plugin-dns 1.0.1__tar.gz → 1.0.2__tar.gz

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 (114) hide show
  1. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/LICENSE +2 -1
  2. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/PKG-INFO +2 -1
  3. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/README.md +1 -0
  4. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/__init__.py +1 -1
  5. netbox_plugin_dns-1.0.2/netbox_dns/mixins/__init__.py +1 -0
  6. netbox_plugin_dns-1.0.2/netbox_dns/mixins/object_modification.py +26 -0
  7. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/models/nameserver.py +4 -5
  8. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/models/record.py +10 -4
  9. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/models/view.py +10 -8
  10. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/models/zone.py +10 -21
  11. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/tables/view.py +1 -1
  12. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/validators/dns_name.py +3 -3
  13. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/pyproject.toml +1 -1
  14. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/nested_serializers.py +0 -0
  15. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/serializers.py +0 -0
  16. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/serializers_/__init__.py +0 -0
  17. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/serializers_/contact.py +0 -0
  18. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/serializers_/nameserver.py +0 -0
  19. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/serializers_/record.py +0 -0
  20. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/serializers_/registrar.py +0 -0
  21. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/serializers_/view.py +0 -0
  22. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/serializers_/zone.py +0 -0
  23. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/urls.py +0 -0
  24. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/api/views.py +0 -0
  25. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/apps.py +0 -0
  26. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/fields/__init__.py +0 -0
  27. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/fields/address.py +0 -0
  28. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/fields/network.py +0 -0
  29. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/fields/rfc2317.py +0 -0
  30. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/filtersets/__init__.py +0 -0
  31. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/filtersets/contact.py +0 -0
  32. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/filtersets/nameserver.py +0 -0
  33. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/filtersets/record.py +0 -0
  34. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/filtersets/registrar.py +0 -0
  35. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/filtersets/view.py +0 -0
  36. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/filtersets/zone.py +0 -0
  37. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/forms/__init__.py +0 -0
  38. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/forms/contact.py +0 -0
  39. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/forms/nameserver.py +0 -0
  40. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/forms/record.py +0 -0
  41. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/forms/registrar.py +0 -0
  42. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/forms/view.py +0 -0
  43. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/forms/zone.py +0 -0
  44. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/graphql/__init__.py +0 -0
  45. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/graphql/filters.py +0 -0
  46. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/graphql/schema.py +0 -0
  47. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/graphql/types.py +0 -0
  48. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/management/commands/cleanup_database.py +0 -0
  49. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/management/commands/cleanup_rrset_ttl.py +0 -0
  50. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/management/commands/setup_coupling.py +0 -0
  51. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/management/commands/update_soa.py +0 -0
  52. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
  53. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +0 -0
  54. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0002_contact_description_registrar_description.py +0 -0
  55. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0003_default_view.py +0 -0
  56. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0004_create_and_assign_default_view.py +0 -0
  57. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0005_alter_zone_view_not_null.py +0 -0
  58. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
  59. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
  60. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0022_search.py +0 -0
  61. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
  62. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0024_tenancy.py +0 -0
  63. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
  64. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0026_domain_registration.py +0 -0
  65. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
  66. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
  67. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/0029_record_fqdn.py +0 -0
  68. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/migrations/__init__.py +0 -0
  69. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/models/__init__.py +0 -0
  70. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/models/contact.py +0 -0
  71. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/models/registrar.py +0 -0
  72. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/navigation.py +0 -0
  73. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/signals/__init__.py +0 -0
  74. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/signals/ipam_coupling.py +0 -0
  75. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/tables/__init__.py +0 -0
  76. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/tables/contact.py +0 -0
  77. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/tables/nameserver.py +0 -0
  78. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/tables/record.py +0 -0
  79. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/tables/registrar.py +0 -0
  80. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/tables/zone.py +0 -0
  81. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/template_content.py +0 -0
  82. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/contact.html +0 -0
  83. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/nameserver.html +0 -0
  84. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
  85. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
  86. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/record.html +0 -0
  87. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/registrar.html +0 -0
  88. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/related_dns_objects.html +0 -0
  89. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/view.html +0 -0
  90. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
  91. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
  92. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
  93. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
  94. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
  95. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
  96. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/templates/netbox_dns/zone.html +0 -0
  97. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/urls/__init__.py +0 -0
  98. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/urls/contact.py +0 -0
  99. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/urls/nameserver.py +0 -0
  100. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/urls/record.py +0 -0
  101. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/urls/registrar.py +0 -0
  102. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/urls/view.py +0 -0
  103. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/urls/zone.py +0 -0
  104. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/utilities/__init__.py +0 -0
  105. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/utilities/ipam_coupling.py +0 -0
  106. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/validators/__init__.py +0 -0
  107. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/validators/rfc2317.py +0 -0
  108. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/views/__init__.py +0 -0
  109. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/views/contact.py +0 -0
  110. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/views/nameserver.py +0 -0
  111. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/views/record.py +0 -0
  112. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/views/registrar.py +0 -0
  113. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/views/view.py +0 -0
  114. {netbox_plugin_dns-1.0.1 → netbox_plugin_dns-1.0.2}/netbox_dns/views/zone.py +0 -0
@@ -1,6 +1,7 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Aurora Research Lab
3
+ Copyright (c) 2021-2023 Aurora Research Lab
4
+ Copyright (c) 2023 Peter Eckel
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-plugin-dns
3
- Version: 1.0.1
3
+ Version: 1.0.2
4
4
  Summary: NetBox DNS is a NetBox plugin for managing DNS data.
5
5
  Home-page: https://github.com/peteeckel/netbox-plugin-dns
6
6
  License: MIT
@@ -44,6 +44,7 @@ The main focus of the plugin is to ensure the quality of the data stored in it.
44
44
  * Validation of record names and values
45
45
  * Automatic maintenance of PTR records for IPv6 and IPv4 address records
46
46
  * Automatic generation of SOA records, optionally including the serial number of the zone data
47
+ * Validation of changes to the SOA SERIAL number, whether they are done automatically or manually
47
48
  * Validation of record types such as CNAME and singletons, to ensure DNS zone validity
48
49
  * Support for [RFC 2317](https://datatracker.ietf.org/doc/html/rfc2317) delegation of PTR zones for IPv4 subnets longer than 24 bits
49
50
 
@@ -24,6 +24,7 @@ The main focus of the plugin is to ensure the quality of the data stored in it.
24
24
  * Validation of record names and values
25
25
  * Automatic maintenance of PTR records for IPv6 and IPv4 address records
26
26
  * Automatic generation of SOA records, optionally including the serial number of the zone data
27
+ * Validation of changes to the SOA SERIAL number, whether they are done automatically or manually
27
28
  * Validation of record types such as CNAME and singletons, to ensure DNS zone validity
28
29
  * Support for [RFC 2317](https://datatracker.ietf.org/doc/html/rfc2317) delegation of PTR zones for IPv4 subnets longer than 24 bits
29
30
 
@@ -1,6 +1,6 @@
1
1
  from netbox.plugins import PluginConfig
2
2
 
3
- __version__ = "1.0.1"
3
+ __version__ = "1.0.2"
4
4
 
5
5
 
6
6
  class DNSConfig(PluginConfig):
@@ -0,0 +1 @@
1
+ from .object_modification import *
@@ -0,0 +1,26 @@
1
+ from netbox.models import NetBoxModel
2
+
3
+
4
+ class ObjectModificationMixin:
5
+ def __init__(self, *args, **kwargs):
6
+ super().__init__(*args, **kwargs)
7
+
8
+ if not hasattr(self.__class__, "check_fields"):
9
+ self.__class__.check_fields = (
10
+ {field.name for field in self._meta.fields}
11
+ - {field.name for field in NetBoxModel._meta.fields}
12
+ - {"id"}
13
+ )
14
+
15
+ @property
16
+ def changed_fields(self):
17
+ if self.pk is None:
18
+ return None
19
+
20
+ saved = self.__class__.objects.get(pk=self.pk)
21
+
22
+ return {
23
+ field
24
+ for field in self.check_fields
25
+ if getattr(self, field) != getattr(saved, field)
26
+ }
@@ -14,11 +14,12 @@ from netbox_dns.utilities import (
14
14
  NameFormatError,
15
15
  )
16
16
  from netbox_dns.validators import validate_fqdn
17
+ from netbox_dns.mixins import ObjectModificationMixin
17
18
 
18
19
  from .record import Record, RecordTypeChoices
19
20
 
20
21
 
21
- class NameServer(NetBoxModel):
22
+ class NameServer(ObjectModificationMixin, NetBoxModel):
22
23
  name = models.CharField(
23
24
  unique=True,
24
25
  max_length=255,
@@ -79,14 +80,12 @@ class NameServer(NetBoxModel):
79
80
  def save(self, *args, **kwargs):
80
81
  self.full_clean()
81
82
 
82
- name_changed = (
83
- self.pk is not None and self.name != NameServer.objects.get(pk=self.pk).name
84
- )
83
+ changed_fields = self.changed_fields
85
84
 
86
85
  with transaction.atomic():
87
86
  super().save(*args, **kwargs)
88
87
 
89
- if name_changed:
88
+ if changed_fields is not None and "name" in changed_fields:
90
89
  soa_zones = self.zones_soa.all()
91
90
  for soa_zone in soa_zones:
92
91
  soa_zone.update_soa_record()
@@ -25,6 +25,7 @@ from netbox_dns.validators import (
25
25
  validate_extended_hostname,
26
26
  validate_domain_name,
27
27
  )
28
+ from netbox_dns.mixins import ObjectModificationMixin
28
29
 
29
30
  # +
30
31
  # This is a hack designed to break cyclic imports between Record and Zone
@@ -102,7 +103,7 @@ class RecordStatusChoices(ChoiceSet):
102
103
  ]
103
104
 
104
105
 
105
- class Record(NetBoxModel):
106
+ class Record(ObjectModificationMixin, NetBoxModel):
106
107
  ACTIVE_STATUS_LIST = (RecordStatusChoices.STATUS_ACTIVE,)
107
108
 
108
109
  unique_ptr_qs = Q(
@@ -211,9 +212,12 @@ class Record(NetBoxModel):
211
212
 
212
213
  def __str__(self):
213
214
  try:
214
- name = dns_name.from_text(self.fqdn).relativize(dns_name.root).to_unicode()
215
+ fqdn = dns_name.from_text(
216
+ self.name, origin=dns_name.from_text(self.zone.name)
217
+ ).relativize(dns_name.root)
218
+ name = fqdn.to_unicode()
215
219
  except dns_name.IDNAException:
216
- name = self.name
220
+ name = fqdn.to_text()
217
221
  except dns_name.LabelTooLong:
218
222
  name = f"{self.name[:59]}..."
219
223
 
@@ -783,7 +787,9 @@ class Record(NetBoxModel):
783
787
  self.ptr_record.delete()
784
788
  self.ptr_record = None
785
789
 
786
- super().save(*args, **kwargs)
790
+ changed_fields = self.changed_fields
791
+ if changed_fields is None or changed_fields:
792
+ super().save(*args, **kwargs)
787
793
 
788
794
  _zone = self.zone
789
795
  if self.type != RecordTypeChoices.SOA and _zone.soa_serial_auto:
@@ -7,8 +7,10 @@ from netbox.search import SearchIndex, register_search
7
7
  from netbox.context import current_request
8
8
  from utilities.exceptions import AbortRequest
9
9
 
10
+ from netbox_dns.mixins import ObjectModificationMixin
10
11
 
11
- class View(NetBoxModel):
12
+
13
+ class View(ObjectModificationMixin, NetBoxModel):
12
14
  name = models.CharField(
13
15
  unique=True,
14
16
  max_length=255,
@@ -53,13 +55,11 @@ class View(NetBoxModel):
53
55
  super().delete(*args, **kwargs)
54
56
 
55
57
  def clean(self, *args, old_state=None, **kwargs):
56
- if self.pk is None:
58
+ if (changed_fields := self.changed_fields) is None:
57
59
  return
58
60
 
59
- old_state = View.objects.get(pk=self.pk)
60
-
61
61
  if (
62
- old_state.default_view
62
+ "default_view" in changed_fields
63
63
  and not self.default_view
64
64
  and not View.objects.filter(default_view=True).exclude(pk=self.pk).exists()
65
65
  ):
@@ -74,12 +74,14 @@ class View(NetBoxModel):
74
74
  def save(self, *args, **kwargs):
75
75
  self.clean()
76
76
 
77
- old_state = None if self.pk is None else View.objects.get(pk=self.pk)
77
+ changed_fields = self.changed_fields
78
78
 
79
79
  super().save(*args, **kwargs)
80
80
 
81
- if (old_state is None and self.default_view) or (
82
- old_state is not None and self.default_view and not old_state.default_view
81
+ if (changed_fields is None and self.default_view) or (
82
+ changed_fields is not None
83
+ and self.default_view
84
+ and "default_view" in changed_fields
83
85
  ):
84
86
  other_views = View.objects.filter(default_view=True).exclude(pk=self.pk)
85
87
  for view in other_views:
@@ -35,6 +35,7 @@ from netbox_dns.validators import (
35
35
  validate_fqdn,
36
36
  validate_domain_name,
37
37
  )
38
+ from netbox_dns.mixins import ObjectModificationMixin
38
39
 
39
40
  # +
40
41
  # This is a hack designed to break cyclic imports between View, Record and Zone
@@ -77,7 +78,7 @@ class ZoneStatusChoices(ChoiceSet):
77
78
  ]
78
79
 
79
80
 
80
- class Zone(NetBoxModel):
81
+ class Zone(ObjectModificationMixin, NetBoxModel):
81
82
  ACTIVE_STATUS_LIST = (ZoneStatusChoices.STATUS_ACTIVE,)
82
83
 
83
84
  view = models.ForeignKey(
@@ -683,17 +684,7 @@ class Zone(NetBoxModel):
683
684
  def save(self, *args, **kwargs):
684
685
  self.full_clean()
685
686
 
686
- new_zone = self.pk is None
687
- if not new_zone:
688
- old_zone = Zone.objects.get(pk=self.pk)
689
-
690
- name_changed = not new_zone and old_zone.name != self.name
691
- view_changed = not new_zone and old_zone.view != self.view
692
- status_changed = not new_zone and old_zone.status != self.status
693
- rfc2317_changed = not new_zone and (
694
- old_zone.rfc2317_prefix != self.rfc2317_prefix
695
- or old_zone.rfc2317_parent_managed != self.rfc2317_parent_managed
696
- )
687
+ changed_fields = self.changed_fields
697
688
 
698
689
  if self.soa_serial_auto:
699
690
  self.soa_serial = self.get_auto_serial()
@@ -701,7 +692,7 @@ class Zone(NetBoxModel):
701
692
  super().save(*args, **kwargs)
702
693
 
703
694
  if (
704
- new_zone or name_changed or view_changed or status_changed
695
+ changed_fields is None or {"name", "view", "status"} & changed_fields
705
696
  ) and self.is_reverse_zone:
706
697
  zones = Zone.objects.filter(
707
698
  view=self.view,
@@ -733,11 +724,9 @@ class Zone(NetBoxModel):
733
724
  child_zone.update_rfc2317_parent_zone()
734
725
 
735
726
  if (
736
- new_zone
737
- or name_changed
738
- or view_changed
739
- or status_changed
740
- or rfc2317_changed
727
+ changed_fields is None
728
+ or {"name", "view", "status", "rfc2317_prefix", "rfc2317_parent_managed"}
729
+ & changed_fields
741
730
  ) and self.is_rfc2317_zone:
742
731
  zones = Zone.objects.filter(
743
732
  view=self.view,
@@ -763,7 +752,7 @@ class Zone(NetBoxModel):
763
752
 
764
753
  self.update_rfc2317_parent_zone()
765
754
 
766
- elif name_changed or view_changed or status_changed:
755
+ elif changed_fields is not None and {"name", "view", "status"} & changed_fields:
767
756
  for address_record in self.record_set.filter(
768
757
  type__in=(record.RecordTypeChoices.A, record.RecordTypeChoices.AAAA)
769
758
  ):
@@ -772,7 +761,7 @@ class Zone(NetBoxModel):
772
761
  # Fix name in IP Address when zone name is changed
773
762
  if (
774
763
  get_plugin_config("netbox_dns", "feature_ipam_coupling")
775
- and name_changed
764
+ and "name" in changed_fields
776
765
  ):
777
766
  for ip in IPAddress.objects.filter(
778
767
  custom_field_data__ipaddress_dns_zone_id=self.pk
@@ -780,7 +769,7 @@ class Zone(NetBoxModel):
780
769
  ip.dns_name = f'{ip.custom_field_data["ipaddress_dns_record_name"]}.{self.name}'
781
770
  ip.save(update_fields=["dns_name"])
782
771
 
783
- if name_changed:
772
+ if changed_fields is not None and "name" in changed_fields:
784
773
  for _record in self.record_set.all():
785
774
  _record.save(
786
775
  update_fields=["fqdn"],
@@ -10,7 +10,7 @@ class ViewTable(TenancyColumnsMixin, NetBoxTable):
10
10
  name = tables.Column(
11
11
  linkify=True,
12
12
  )
13
- default_view = tables.Column(
13
+ default_view = tables.BooleanColumn(
14
14
  verbose_name="Default View",
15
15
  )
16
16
  tags = TagColumn(url_name="plugins:netbox_dns:view_list")
@@ -54,9 +54,9 @@ def validate_domain_name(name, always_tolerant=False, allow_empty_label=False):
54
54
  ):
55
55
  return
56
56
 
57
- if always_tolerant or get_plugin_config(
58
- "netbox_dns", "tolerate_underscores_in_hostnames"
59
- ):
57
+ if always_tolerant:
58
+ regex = rf"^{TOLERANT_LEADING_UNDERSCORE_LABEL}(\.{TOLERANT_LEADING_UNDERSCORE_LABEL})*\.?$"
59
+ elif get_plugin_config("netbox_dns", "tolerate_underscores_in_hostnames"):
60
60
  regex = rf"^{TOLERANT_LABEL}(\.{TOLERANT_LABEL})*\.?$"
61
61
  else:
62
62
  regex = rf"^{LABEL}(\.{LABEL})*\.?$"
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "netbox-plugin-dns"
3
- version = "1.0.1"
3
+ version = "1.0.2"
4
4
  description = "NetBox DNS is a NetBox plugin for managing DNS data."
5
5
  authors = ["Peter Eckel <pete@netbox-dns.org>"]
6
6
  homepage = "https://github.com/peteeckel/netbox-plugin-dns"