netbox-plugin-dns 1.1.0b5__py3-none-any.whl → 1.1.0b7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of netbox-plugin-dns might be problematic. Click here for more details.
- netbox_dns/__init__.py +2 -1
- netbox_dns/management/commands/rebuild_dnssync.py +18 -0
- netbox_dns/models/record.py +27 -16
- netbox_dns/models/zone.py +35 -18
- netbox_dns/signals/ipam_dnssync.py +6 -2
- netbox_dns/tables/record.py +0 -2
- netbox_dns/utilities/ipam_dnssync.py +34 -19
- netbox_dns/validators/dns_name.py +9 -0
- netbox_dns/views/record.py +0 -4
- {netbox_plugin_dns-1.1.0b5.dist-info → netbox_plugin_dns-1.1.0b7.dist-info}/METADATA +2 -1
- {netbox_plugin_dns-1.1.0b5.dist-info → netbox_plugin_dns-1.1.0b7.dist-info}/RECORD +13 -12
- {netbox_plugin_dns-1.1.0b5.dist-info → netbox_plugin_dns-1.1.0b7.dist-info}/LICENSE +0 -0
- {netbox_plugin_dns-1.1.0b5.dist-info → netbox_plugin_dns-1.1.0b7.dist-info}/WHEEL +0 -0
netbox_dns/__init__.py
CHANGED
|
@@ -5,7 +5,7 @@ from ipam.choices import IPAddressStatusChoices
|
|
|
5
5
|
|
|
6
6
|
from netbox_dns.choices import RecordTypeChoices
|
|
7
7
|
|
|
8
|
-
__version__ = "1.1.
|
|
8
|
+
__version__ = "1.1.0b7"
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class DNSConfig(PluginConfig):
|
|
@@ -32,6 +32,7 @@ class DNSConfig(PluginConfig):
|
|
|
32
32
|
IPAddressStatusChoices.STATUS_SLAAC,
|
|
33
33
|
],
|
|
34
34
|
"dnssync_conflict_deactivate": False,
|
|
35
|
+
"dnssync_minimum_zone_labels": 2,
|
|
35
36
|
"tolerate_characters_in_zone_labels": "",
|
|
36
37
|
"tolerate_underscores_in_labels": False,
|
|
37
38
|
"tolerate_underscores_in_hostnames": False, # Deprecated, will be removed in 1.2.0
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from django.core.management.base import BaseCommand
|
|
2
|
+
|
|
3
|
+
from ipam.models import IPAddress
|
|
4
|
+
|
|
5
|
+
from netbox_dns.utilities import update_dns_records
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Command(BaseCommand):
|
|
9
|
+
help = "Rebuild DNSsync relationships between IP addresses and records"
|
|
10
|
+
|
|
11
|
+
def handle(self, *model_names, **options):
|
|
12
|
+
ip_addresses = IPAddress.objects.all()
|
|
13
|
+
for ip_address in ip_addresses:
|
|
14
|
+
if options.get("verbosity") >= 2:
|
|
15
|
+
self.stdout.write(
|
|
16
|
+
f"Updating DNS records for IP Address {ip_address}, VRF {ip_address.vrf}"
|
|
17
|
+
)
|
|
18
|
+
update_dns_records(ip_address)
|
netbox_dns/models/record.py
CHANGED
|
@@ -493,20 +493,33 @@ class Record(ObjectModificationMixin, NetBoxModel):
|
|
|
493
493
|
**data,
|
|
494
494
|
)
|
|
495
495
|
|
|
496
|
+
def update_fqdn(self, zone=None):
|
|
497
|
+
if zone is None:
|
|
498
|
+
zone = self.zone
|
|
499
|
+
|
|
500
|
+
_zone = dns_name.from_text(zone.name, origin=dns_name.root)
|
|
501
|
+
name = dns_name.from_text(self.name, origin=None)
|
|
502
|
+
fqdn = dns_name.from_text(self.name, origin=_zone)
|
|
503
|
+
|
|
504
|
+
if not fqdn.is_subdomain(_zone):
|
|
505
|
+
raise ValidationError(
|
|
506
|
+
{
|
|
507
|
+
"name": f"{self.name} is not a name in {zone.name}",
|
|
508
|
+
}
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
_zone.to_unicode()
|
|
512
|
+
name.to_unicode()
|
|
513
|
+
|
|
514
|
+
self.name = name.relativize(_zone).to_text()
|
|
515
|
+
self.fqdn = fqdn.to_text()
|
|
516
|
+
|
|
496
517
|
def validate_name(self, new_zone=None):
|
|
497
518
|
if new_zone is None:
|
|
498
519
|
new_zone = self.zone
|
|
499
520
|
|
|
500
521
|
try:
|
|
501
|
-
|
|
502
|
-
name = dns_name.from_text(self.name, origin=None)
|
|
503
|
-
fqdn = dns_name.from_text(self.name, origin=_zone)
|
|
504
|
-
|
|
505
|
-
_zone.to_unicode()
|
|
506
|
-
name.to_unicode()
|
|
507
|
-
|
|
508
|
-
self.name = name.relativize(_zone).to_text()
|
|
509
|
-
self.fqdn = fqdn.to_text()
|
|
522
|
+
self.update_fqdn(zone=new_zone)
|
|
510
523
|
|
|
511
524
|
except dns.exception.DNSException as exc:
|
|
512
525
|
raise ValidationError(
|
|
@@ -515,13 +528,6 @@ class Record(ObjectModificationMixin, NetBoxModel):
|
|
|
515
528
|
}
|
|
516
529
|
)
|
|
517
530
|
|
|
518
|
-
if not fqdn.is_subdomain(_zone):
|
|
519
|
-
raise ValidationError(
|
|
520
|
-
{
|
|
521
|
-
"name": f"{self.name} is not a name in {new_zone.name}",
|
|
522
|
-
}
|
|
523
|
-
)
|
|
524
|
-
|
|
525
531
|
if self.type not in get_plugin_config(
|
|
526
532
|
"netbox_dns", "tolerate_non_rfc1035_types", default=[]
|
|
527
533
|
):
|
|
@@ -613,6 +619,11 @@ class Record(ObjectModificationMixin, NetBoxModel):
|
|
|
613
619
|
if not get_plugin_config("netbox_dns", "enforce_unique_rrset_ttl", False):
|
|
614
620
|
return
|
|
615
621
|
|
|
622
|
+
if self.ipam_ip_address is not None and get_plugin_config(
|
|
623
|
+
"netbox_dns", "dnssync_conflict_deactivate", False
|
|
624
|
+
):
|
|
625
|
+
return
|
|
626
|
+
|
|
616
627
|
if self.type == RecordTypeChoices.PTR and self.managed:
|
|
617
628
|
return
|
|
618
629
|
|
netbox_dns/models/zone.py
CHANGED
|
@@ -3,6 +3,7 @@ from math import ceil
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
|
|
5
5
|
from dns import name as dns_name
|
|
6
|
+
from dns.exception import DNSException
|
|
6
7
|
from dns.rdtypes.ANY import SOA
|
|
7
8
|
from dns.exception import DNSException
|
|
8
9
|
|
|
@@ -37,6 +38,7 @@ from netbox_dns.utilities import (
|
|
|
37
38
|
)
|
|
38
39
|
from netbox_dns.validators import (
|
|
39
40
|
validate_fqdn,
|
|
41
|
+
validate_rname,
|
|
40
42
|
validate_domain_name,
|
|
41
43
|
)
|
|
42
44
|
from netbox_dns.mixins import ObjectModificationMixin
|
|
@@ -78,6 +80,7 @@ class Zone(ObjectModificationMixin, NetBoxModel):
|
|
|
78
80
|
super().__init__(*args, **kwargs)
|
|
79
81
|
|
|
80
82
|
self._soa_serial_dirty = False
|
|
83
|
+
self._ip_addresses_checked = False
|
|
81
84
|
|
|
82
85
|
view = models.ForeignKey(
|
|
83
86
|
to="View",
|
|
@@ -280,7 +283,7 @@ class Zone(ObjectModificationMixin, NetBoxModel):
|
|
|
280
283
|
else:
|
|
281
284
|
try:
|
|
282
285
|
name = dns_name.from_text(self.name, origin=None).to_unicode()
|
|
283
|
-
except
|
|
286
|
+
except DNSException:
|
|
284
287
|
name = self.name
|
|
285
288
|
|
|
286
289
|
try:
|
|
@@ -308,6 +311,14 @@ class Zone(ObjectModificationMixin, NetBoxModel):
|
|
|
308
311
|
def soa_serial_dirty(self, soa_serial_dirty):
|
|
309
312
|
self._soa_serial_dirty = soa_serial_dirty
|
|
310
313
|
|
|
314
|
+
@property
|
|
315
|
+
def ip_addresses_checked(self):
|
|
316
|
+
return self._ip_addresses_checked
|
|
317
|
+
|
|
318
|
+
@ip_addresses_checked.setter
|
|
319
|
+
def ip_addresses_checked(self, ip_addresses_checked):
|
|
320
|
+
self._ip_addresses_checked = ip_addresses_checked
|
|
321
|
+
|
|
311
322
|
@property
|
|
312
323
|
def display_name(self):
|
|
313
324
|
return name_to_unicode(self.name)
|
|
@@ -621,7 +632,7 @@ class Zone(ObjectModificationMixin, NetBoxModel):
|
|
|
621
632
|
raise ValidationError("soa_rname not set and no default value defined")
|
|
622
633
|
try:
|
|
623
634
|
dns_name.from_text(self.soa_rname, origin=dns_name.root)
|
|
624
|
-
|
|
635
|
+
validate_rname(self.soa_rname)
|
|
625
636
|
except (DNSException, ValidationError) as exc:
|
|
626
637
|
raise ValidationError(
|
|
627
638
|
{
|
|
@@ -653,24 +664,26 @@ class Zone(ObjectModificationMixin, NetBoxModel):
|
|
|
653
664
|
}
|
|
654
665
|
)
|
|
655
666
|
|
|
656
|
-
if
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
raise ValidationError(exc.messages)
|
|
662
|
-
|
|
667
|
+
if (
|
|
668
|
+
not self.ip_addresses_checked
|
|
669
|
+
and old_zone.name != self.name
|
|
670
|
+
or old_zone.view != self.view
|
|
671
|
+
):
|
|
663
672
|
ip_addresses = IPAddress.objects.filter(
|
|
664
673
|
netbox_dns_records__in=self.record_set.filter(
|
|
665
674
|
ipam_ip_address__isnull=False
|
|
666
675
|
)
|
|
667
676
|
)
|
|
668
|
-
|
|
677
|
+
ip_addresses |= get_ip_addresses_by_zone(self)
|
|
678
|
+
|
|
679
|
+
for ip_address in ip_addresses.distinct():
|
|
669
680
|
try:
|
|
670
681
|
check_dns_records(ip_address, zone=self)
|
|
671
682
|
except ValidationError as exc:
|
|
672
683
|
raise ValidationError(exc.messages)
|
|
673
684
|
|
|
685
|
+
self.ip_addresses_checked = True
|
|
686
|
+
|
|
674
687
|
if self.is_reverse_zone:
|
|
675
688
|
self.arpa_network = self.network_from_name
|
|
676
689
|
|
|
@@ -785,12 +798,13 @@ class Zone(ObjectModificationMixin, NetBoxModel):
|
|
|
785
798
|
|
|
786
799
|
elif changed_fields is not None and {"name", "view", "status"} & changed_fields:
|
|
787
800
|
for address_record in self.record_set.filter(
|
|
788
|
-
type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA)
|
|
801
|
+
type__in=(RecordTypeChoices.A, RecordTypeChoices.AAAA),
|
|
802
|
+
ipam_ip_address__isnull=True,
|
|
789
803
|
):
|
|
790
804
|
address_record.save(update_fields=["ptr_record"])
|
|
791
805
|
|
|
792
806
|
if changed_fields is not None and "name" in changed_fields:
|
|
793
|
-
for _record in self.record_set.
|
|
807
|
+
for _record in self.record_set.filter(ipam_ip_address__isnull=True):
|
|
794
808
|
_record.save(
|
|
795
809
|
update_fields=["fqdn"],
|
|
796
810
|
save_zone_serial=False,
|
|
@@ -799,13 +813,14 @@ class Zone(ObjectModificationMixin, NetBoxModel):
|
|
|
799
813
|
)
|
|
800
814
|
|
|
801
815
|
if changed_fields is None or {"name", "view"} & changed_fields:
|
|
802
|
-
|
|
803
|
-
|
|
816
|
+
ip_addresses = IPAddress.objects.filter(
|
|
817
|
+
netbox_dns_records__in=self.record_set.filter(
|
|
804
818
|
ipam_ip_address__isnull=False
|
|
805
|
-
)
|
|
819
|
+
)
|
|
806
820
|
)
|
|
807
|
-
|
|
808
|
-
|
|
821
|
+
ip_addresses |= get_ip_addresses_by_zone(self)
|
|
822
|
+
|
|
823
|
+
for ip_address in ip_addresses.distinct():
|
|
809
824
|
update_dns_records(ip_address)
|
|
810
825
|
|
|
811
826
|
self.save_soa_serial()
|
|
@@ -848,7 +863,9 @@ class Zone(ObjectModificationMixin, NetBoxModel):
|
|
|
848
863
|
netbox_dns_records__in=self.record_set.filter(
|
|
849
864
|
ipam_ip_address__isnull=False
|
|
850
865
|
)
|
|
851
|
-
)
|
|
866
|
+
)
|
|
867
|
+
.distinct()
|
|
868
|
+
.values_list("pk", flat=True)
|
|
852
869
|
)
|
|
853
870
|
|
|
854
871
|
super().delete(*args, **kwargs)
|
|
@@ -215,6 +215,10 @@ def ipam_dnssync_view_prefix_changed(**kwargs):
|
|
|
215
215
|
return
|
|
216
216
|
|
|
217
217
|
check_view = action != "post_remove"
|
|
218
|
+
|
|
219
|
+
ip_addresses = IPAddress.objects.none()
|
|
218
220
|
for prefix in Prefix.objects.filter(pk__in=kwargs.get("pk_set")):
|
|
219
|
-
|
|
220
|
-
|
|
221
|
+
ip_addresses |= get_ip_addresses_by_prefix(prefix, check_view=check_view)
|
|
222
|
+
|
|
223
|
+
for ip_address in ip_addresses.distinct():
|
|
224
|
+
update_dns_records(ip_address)
|
netbox_dns/tables/record.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import django_tables2 as tables
|
|
2
|
-
from django_tables2.utils import Accessor
|
|
3
2
|
from django.utils.html import format_html
|
|
4
3
|
|
|
5
4
|
|
|
@@ -9,7 +8,6 @@ from netbox.tables import (
|
|
|
9
8
|
TagColumn,
|
|
10
9
|
ActionsColumn,
|
|
11
10
|
)
|
|
12
|
-
from ipam.lookups import Host, Inet
|
|
13
11
|
from tenancy.tables import TenancyColumnsMixin
|
|
14
12
|
|
|
15
13
|
from netbox_dns.models import Record
|
|
@@ -44,7 +44,7 @@ def _get_assigned_views(ip_address):
|
|
|
44
44
|
|
|
45
45
|
def _get_record_status(ip_address):
|
|
46
46
|
return (
|
|
47
|
-
RecordStatusChoices.
|
|
47
|
+
RecordStatusChoices.STATUS_ACTIVE
|
|
48
48
|
if ip_address.status
|
|
49
49
|
in settings.PLUGINS_CONFIG["netbox_dns"].get(
|
|
50
50
|
"dnssync_ipaddress_active_status", []
|
|
@@ -59,6 +59,20 @@ def _valid_entry(ip_address, zone):
|
|
|
59
59
|
).is_subdomain(dns_name.from_text(zone.name))
|
|
60
60
|
|
|
61
61
|
|
|
62
|
+
def _match_data(ip_address, record):
|
|
63
|
+
cf_disable_ptr = ip_address.custom_field_data.get(
|
|
64
|
+
"ipaddress_dns_record_disable_ptr"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
record.fqdn.rstrip(".") == ip_address.dns_name.rstrip(".")
|
|
69
|
+
and record.value == str(ip_address.address.ip)
|
|
70
|
+
and record.status == _get_record_status(ip_address)
|
|
71
|
+
and record.ttl == ip_address.custom_field_data.get("ipaddress_dns_record_ttl")
|
|
72
|
+
and (cf_disable_ptr is None or record.disable_ptr == cf_disable_ptr)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
62
76
|
def get_zones(ip_address, view=None, old_zone=None):
|
|
63
77
|
if view is None:
|
|
64
78
|
views = _get_assigned_views(ip_address)
|
|
@@ -68,9 +82,13 @@ def get_zones(ip_address, view=None, old_zone=None):
|
|
|
68
82
|
else:
|
|
69
83
|
views = [view]
|
|
70
84
|
|
|
85
|
+
min_labels = settings.PLUGINS_CONFIG["netbox_dns"].get(
|
|
86
|
+
"dnssync_minimum_zone_labels", 2
|
|
87
|
+
)
|
|
71
88
|
fqdn = dns_name.from_text(ip_address.dns_name)
|
|
72
89
|
zone_name_candidates = [
|
|
73
|
-
fqdn.split(i)[1].to_text().rstrip(".")
|
|
90
|
+
fqdn.split(i)[1].to_text().rstrip(".")
|
|
91
|
+
for i in range(min_labels + 1, len(fqdn.labels))
|
|
74
92
|
]
|
|
75
93
|
|
|
76
94
|
zones = _zone.Zone.objects.filter(
|
|
@@ -104,11 +122,7 @@ def check_dns_records(ip_address, zone=None, view=None):
|
|
|
104
122
|
|
|
105
123
|
if ip_address.pk is not None:
|
|
106
124
|
for record in ip_address.netbox_dns_records.filter(zone__in=zones):
|
|
107
|
-
if (
|
|
108
|
-
record.fqdn != ip_address.dns_name
|
|
109
|
-
or record.value != ip_address.address.ip
|
|
110
|
-
or record.status != _get_record_status(ip_address)
|
|
111
|
-
):
|
|
125
|
+
if not _match_data(ip_address, record):
|
|
112
126
|
record.update_from_ip_address(ip_address)
|
|
113
127
|
|
|
114
128
|
if record is not None:
|
|
@@ -117,9 +131,7 @@ def check_dns_records(ip_address, zone=None, view=None):
|
|
|
117
131
|
zones = _zone.Zone.objects.filter(
|
|
118
132
|
pk__in=[zone.pk for zone in zones]
|
|
119
133
|
).exclude(
|
|
120
|
-
pk__in=set(
|
|
121
|
-
ip_address.netbox_dns_records.all().values_list("zone", flat=True)
|
|
122
|
-
)
|
|
134
|
+
pk__in=set(ip_address.netbox_dns_records.values_list("zone", flat=True))
|
|
123
135
|
)
|
|
124
136
|
|
|
125
137
|
for zone in zones:
|
|
@@ -155,15 +167,14 @@ def update_dns_records(ip_address):
|
|
|
155
167
|
|
|
156
168
|
if ip_address.pk is not None:
|
|
157
169
|
for record in ip_address.netbox_dns_records.all():
|
|
158
|
-
if record.zone not in zones
|
|
170
|
+
if record.zone not in zones or ip_address.custom_field_data.get(
|
|
171
|
+
"ipaddress_dns_disabled"
|
|
172
|
+
):
|
|
159
173
|
record.delete()
|
|
160
174
|
continue
|
|
161
175
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
or record.value != ip_address.address.ip
|
|
165
|
-
or record.status != _get_record_status(ip_address)
|
|
166
|
-
):
|
|
176
|
+
record.update_fqdn()
|
|
177
|
+
if not _match_data(ip_address, record):
|
|
167
178
|
record.update_from_ip_address(ip_address)
|
|
168
179
|
|
|
169
180
|
if record is not None:
|
|
@@ -217,7 +228,9 @@ def get_ip_addresses_by_prefix(prefix, check_view=True):
|
|
|
217
228
|
vrf=prefix.vrf, address__net_host_contained=prefix.prefix
|
|
218
229
|
)
|
|
219
230
|
|
|
220
|
-
for exclude_child in
|
|
231
|
+
for exclude_child in (
|
|
232
|
+
prefix.get_children().filter(netbox_dns_views__isnull=False).distinct()
|
|
233
|
+
):
|
|
221
234
|
queryset = queryset.exclude(
|
|
222
235
|
vrf=exclude_child.vrf,
|
|
223
236
|
address__net_host_contained=exclude_child.prefix,
|
|
@@ -258,9 +271,11 @@ def get_ip_addresses_by_zone(zone):
|
|
|
258
271
|
are the IPAddress objects in prefixes assigned to the same view, if the
|
|
259
272
|
'dns_name' attribute of the IPAddress object ends in the zone's name.
|
|
260
273
|
"""
|
|
261
|
-
queryset = get_ip_addresses_by_view(zone.view)
|
|
274
|
+
queryset = get_ip_addresses_by_view(zone.view).filter(
|
|
275
|
+
dns_name__regex=rf"\.{re.escape(zone.name)}\.?$"
|
|
276
|
+
)
|
|
262
277
|
|
|
263
|
-
return queryset
|
|
278
|
+
return queryset
|
|
264
279
|
|
|
265
280
|
|
|
266
281
|
def check_record_permission(add=True, change=True, delete=True):
|
|
@@ -7,6 +7,7 @@ from netbox.plugins.utils import get_plugin_config
|
|
|
7
7
|
|
|
8
8
|
__all__ = (
|
|
9
9
|
"validate_fqdn",
|
|
10
|
+
"validate_rname",
|
|
10
11
|
"validate_generic_name",
|
|
11
12
|
"validate_domain_name",
|
|
12
13
|
)
|
|
@@ -57,6 +58,14 @@ def validate_fqdn(name, always_tolerant=False):
|
|
|
57
58
|
raise ValidationError(f"{name} is not a valid fully qualified DNS host name")
|
|
58
59
|
|
|
59
60
|
|
|
61
|
+
def validate_rname(name, always_tolerant=False):
|
|
62
|
+
label, zone_label = _get_label(always_tolerant=always_tolerant)
|
|
63
|
+
regex = rf"^(\*|{label})(\\\.{label})*(\.{zone_label}){{2,}}\.?$"
|
|
64
|
+
|
|
65
|
+
if not re.match(regex, name, flags=re.IGNORECASE) or _has_invalid_double_dash(name):
|
|
66
|
+
raise ValidationError(f"{name} is not a valid RNAME")
|
|
67
|
+
|
|
68
|
+
|
|
60
69
|
def validate_generic_name(
|
|
61
70
|
name, tolerate_leading_underscores=False, always_tolerant=False
|
|
62
71
|
):
|
netbox_dns/views/record.py
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
from dns import name as dns_name
|
|
2
2
|
|
|
3
|
-
from django.db.models import F, Q, Case, When, OuterRef, Subquery
|
|
4
|
-
|
|
5
3
|
from netbox.views import generic
|
|
6
|
-
from ipam.fields import IPAddressField
|
|
7
|
-
from ipam.models import IPAddress
|
|
8
4
|
|
|
9
5
|
from netbox_dns.filtersets import RecordFilterSet
|
|
10
6
|
from netbox_dns.forms import (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: netbox-plugin-dns
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.0b7
|
|
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
|
|
@@ -48,6 +48,7 @@ The main focus of the plugin is to ensure the quality of the data stored in it.
|
|
|
48
48
|
* Validation of record types such as CNAME and singletons, to ensure DNS zone validity
|
|
49
49
|
* Support for [RFC 2317](https://datatracker.ietf.org/doc/html/rfc2317) delegation of PTR zones for IPv4 subnets longer than 24 bits
|
|
50
50
|
* Templating for zones and records enables faster creations of zones with given boilerplate object relations, such as name servers, tags, tenants or registration information, or records like standard SPF or MX records that are the same for a subset of zones
|
|
51
|
+
* IPAM DNSsync can be used to automatically create address and pointer records for IP addresses by assigning prefixes to DNS views. When an IP address has a DNS name assigned and there are zones with matching names in the DNS views linked to the IP address' prefix, a matching DNS record will be created in these zones
|
|
51
52
|
|
|
52
53
|
Other main features include:
|
|
53
54
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
netbox_dns/__init__.py,sha256=
|
|
1
|
+
netbox_dns/__init__.py,sha256=1AdZCvNRkwwusc3colDNrsJmuW9OS2XSJ-VdVfLXeJA,1922
|
|
2
2
|
netbox_dns/api/nested_serializers.py,sha256=-ZhAiyf-8UHlkcBomBp1J7ci1dSwrxWRbbfskD-D_yQ,3172
|
|
3
3
|
netbox_dns/api/serializers.py,sha256=u-kQurUftGkUGAMh-VkMgXPebLYeZq9WDz9uKzkk2No,370
|
|
4
4
|
netbox_dns/api/serializers_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -46,6 +46,7 @@ netbox_dns/graphql/schema.py,sha256=P-oQ8ei3sC6XLhgCa_riRbRTrMkPCVTJXkGv0U2rPYw,
|
|
|
46
46
|
netbox_dns/graphql/types.py,sha256=Obr9JDsMJlMaJLKbTau7prZUYI6pQj6aIpT-nT4JnZs,6210
|
|
47
47
|
netbox_dns/management/commands/cleanup_database.py,sha256=kfnyybudwKGigjJmrOwafPWSUasZr9jQsxN4eWAgMvY,5969
|
|
48
48
|
netbox_dns/management/commands/cleanup_rrset_ttl.py,sha256=UFRURLBcFeGHUS2lrYFv7UWIebjI72aG1EUQJt0XsXw,2046
|
|
49
|
+
netbox_dns/management/commands/rebuild_dnssync.py,sha256=56YGEsAO_NYCXRmuL9Ju_Ni3FLtMD0MO4ObZAAPefLk,617
|
|
49
50
|
netbox_dns/management/commands/setup_dnssync.py,sha256=qtVj6egSjclaQbuI60hLfl-zg89VJVbX-TB17f1k77Y,5730
|
|
50
51
|
netbox_dns/management/commands/update_soa.py,sha256=Rj_Xk-qpwkAVRubVnM5OqSTwgzi93E0PqjwGb3rYjf0,660
|
|
51
52
|
netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py,sha256=3U0810NWSHPu2dTSHpfzlleDgwMS04FhJ_CkO76SDaw,10283
|
|
@@ -72,20 +73,20 @@ netbox_dns/mixins/object_modification.py,sha256=JbGi8a52wkZ3fFBlfat590CfqRJcEWxB
|
|
|
72
73
|
netbox_dns/models/__init__.py,sha256=wjwNsRttUVYQHZODZi806a_iUDoq_o7mdKObqh1N7N4,300
|
|
73
74
|
netbox_dns/models/contact.py,sha256=oNLyD_6TOTNQQTcCvv6TAC7OkzPTMIRy2NP5nwNKaNg,3009
|
|
74
75
|
netbox_dns/models/nameserver.py,sha256=yKo4Fwqnv5VtTndU2px7tRS3voF3Cal7OWQ6AImLwl0,3208
|
|
75
|
-
netbox_dns/models/record.py,sha256
|
|
76
|
+
netbox_dns/models/record.py,sha256=-PWs4QnnPFlYriTVxekA5rOJN41S7Lc4f0KSABCdFEI,26226
|
|
76
77
|
netbox_dns/models/record_template.py,sha256=3t9VceviX3kNIo5o0VPVFupLFDqPxpHIVLp5U3pBKB4,4661
|
|
77
78
|
netbox_dns/models/registrar.py,sha256=T_oMUlTWTDixOVlIbEZGvOBdvUrKxRkkS41xgM2Oee8,1557
|
|
78
79
|
netbox_dns/models/view.py,sha256=SYmhNYyRCv0rSCK5jrHtug4QgfWCBbjsAjZEEHk02QU,2873
|
|
79
|
-
netbox_dns/models/zone.py,sha256=
|
|
80
|
+
netbox_dns/models/zone.py,sha256=NcOckZ7cA4Sd_ik4WuT1ktjqglTKZHWf0ayBB-_Vnwo,29442
|
|
80
81
|
netbox_dns/models/zone_template.py,sha256=lkiSIfx8KM0Cs3Mb3dLBxKbSpcssVUzQiSmD5W46was,3753
|
|
81
82
|
netbox_dns/navigation.py,sha256=EITDZkbpu4KCC9u4Noj7OORWnkL3EYT2RIRvYlTw34Q,5961
|
|
82
83
|
netbox_dns/signals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
83
|
-
netbox_dns/signals/ipam_dnssync.py,sha256=
|
|
84
|
+
netbox_dns/signals/ipam_dnssync.py,sha256=ToGg2Z_L3wvM6gNHX-oU8QTEkbrsXuVt7J6IcQbGb9A,7964
|
|
84
85
|
netbox_dns/tables/__init__.py,sha256=s41w4o77tIwmhnLjsOsg08R9m3wrlomkkfCLTVQuPzc,196
|
|
85
86
|
netbox_dns/tables/contact.py,sha256=sPs7d1ZhVC5dOS37dPYFqebNd7WGvsV_eYzX_TMcbzY,804
|
|
86
87
|
netbox_dns/tables/ipam_dnssync.py,sha256=7gxf6nXn2zgpnpCr5E5qebXv7QCzrgIqfSzyka53USU,272
|
|
87
88
|
netbox_dns/tables/nameserver.py,sha256=fFiE-yH-_GyRDaV4SVw094r6uH58Kx56NSWDGaMR58g,764
|
|
88
|
-
netbox_dns/tables/record.py,sha256=
|
|
89
|
+
netbox_dns/tables/record.py,sha256=jkb595NEl1iWwkKoS1V97UdxLCnzPUgxrDDNfhNJ57U,4277
|
|
89
90
|
netbox_dns/tables/record_template.py,sha256=16Lu-WDjs2m9Uxx6WkURL39NlyJ8lWzj5Kl6C6lz3E8,2159
|
|
90
91
|
netbox_dns/tables/registrar.py,sha256=M-ckyQUs6dqjTCPf7bAr6UuLEA-q9f9CxKW7yp3rGoM,680
|
|
91
92
|
netbox_dns/tables/view.py,sha256=jf2S4TiOdMq6-wWk0ndR1uBJpkOx_f3pqAuM1nSXTBo,1178
|
|
@@ -123,21 +124,21 @@ netbox_dns/urls/zone.py,sha256=rmB1BkzmWNG06ILUf-39Aj6-SBFkwQouyixMQiamqPc,2005
|
|
|
123
124
|
netbox_dns/urls/zone_template.py,sha256=w3Gu8qfLCWyHofeLkGZd1HpYSlcslomVlBQJZyqh8kk,1690
|
|
124
125
|
netbox_dns/utilities/__init__.py,sha256=mmR0JdH1DJVhUKesnO3CZFj0Rw_wrsMPoYTpOOKHl9I,55
|
|
125
126
|
netbox_dns/utilities/conversions.py,sha256=NS37SoMqXc13wNWRkKnLfyQbVi6QKD33fu5ovTKRo74,1979
|
|
126
|
-
netbox_dns/utilities/ipam_dnssync.py,sha256=
|
|
127
|
+
netbox_dns/utilities/ipam_dnssync.py,sha256=nopMJ3So1OjD0RDkbinnLLtR-8OHIlrh-0WtDHSZKRY,8622
|
|
127
128
|
netbox_dns/validators/__init__.py,sha256=Mr8TvmcJTa8Pubj8TzbFBKfbHhEmGcr5JdQvczEJ39A,72
|
|
128
|
-
netbox_dns/validators/dns_name.py,sha256=
|
|
129
|
+
netbox_dns/validators/dns_name.py,sha256=4JojiP6pb1Z1m_PmDv4g65Ckhg5rQkVqm8JAwHW28nA,3432
|
|
129
130
|
netbox_dns/validators/dns_value.py,sha256=y2Zga4hmywqDrTBXcMC-sWaFbw4eoY8pySq7cWnMP8Y,2822
|
|
130
131
|
netbox_dns/validators/rfc2317.py,sha256=ivylEiNKlmX2x41rwqDrFkD5CFf9FtpNEfsKHX_prbE,585
|
|
131
132
|
netbox_dns/views/__init__.py,sha256=s41w4o77tIwmhnLjsOsg08R9m3wrlomkkfCLTVQuPzc,196
|
|
132
133
|
netbox_dns/views/contact.py,sha256=qM9F6MQBvO8ERR7quGLdQ5kW4roNLJ61As8m0qQTapg,2471
|
|
133
134
|
netbox_dns/views/nameserver.py,sha256=DFr0eybMshc1FW06g4cy9Nk4VRMxRqakI5KtHFiAVRc,3286
|
|
134
|
-
netbox_dns/views/record.py,sha256=
|
|
135
|
+
netbox_dns/views/record.py,sha256=Il4WpsIp9MDsYhW-QmJ1uJm6uneRhKC4j8GfaVc9cmg,4563
|
|
135
136
|
netbox_dns/views/record_template.py,sha256=BkemTBEramLhYqB6HrA80sNgtduW1ZOJwbYs3i7srik,2510
|
|
136
137
|
netbox_dns/views/registrar.py,sha256=yRQgFm3vgBD21ZQex9asjs0QWegvSHlcyHXLnjvc5xs,2324
|
|
137
138
|
netbox_dns/views/view.py,sha256=iXBJTc3JD5cD5z0RTcHVTtYV-KNIJGneeoxymXChdUE,2759
|
|
138
139
|
netbox_dns/views/zone.py,sha256=SKhf_WHcFVpKqFTuUMf-Dmxu1AwFHBeo_DtD8UGFrJ8,5483
|
|
139
140
|
netbox_dns/views/zone_template.py,sha256=qvXl-bpc1fMc1WFngynj4-Q3-JJDgKdT-r54s4M1D0s,2118
|
|
140
|
-
netbox_plugin_dns-1.1.
|
|
141
|
-
netbox_plugin_dns-1.1.
|
|
142
|
-
netbox_plugin_dns-1.1.
|
|
143
|
-
netbox_plugin_dns-1.1.
|
|
141
|
+
netbox_plugin_dns-1.1.0b7.dist-info/LICENSE,sha256=I3tDu11bZfhFm3EkV4zOD5TmWgLjnUNLEFwrdjniZYs,1112
|
|
142
|
+
netbox_plugin_dns-1.1.0b7.dist-info/METADATA,sha256=edfR8h5Vk9TnZGYkbpUGQXmeF7mhNmzl2hsPYJ_FJ4Y,6725
|
|
143
|
+
netbox_plugin_dns-1.1.0b7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
144
|
+
netbox_plugin_dns-1.1.0b7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|