netbox-plugin-dns 1.1.0__py3-none-any.whl → 1.1.0b1__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 +6 -9
- netbox_dns/api/nested_serializers.py +16 -17
- netbox_dns/api/serializers.py +1 -1
- netbox_dns/api/serializers_/{registration_contact.py → contact.py} +5 -5
- netbox_dns/api/serializers_/record.py +0 -1
- netbox_dns/api/serializers_/zone.py +5 -5
- netbox_dns/api/serializers_/zone_template.py +5 -5
- netbox_dns/api/urls.py +2 -2
- netbox_dns/api/views.py +35 -9
- netbox_dns/fields/ipam.py +3 -0
- netbox_dns/filtersets/__init__.py +1 -1
- netbox_dns/filtersets/{registration_contact.py → contact.py} +4 -4
- netbox_dns/filtersets/record.py +1 -1
- netbox_dns/filtersets/zone.py +15 -15
- netbox_dns/filtersets/zone_template.py +15 -15
- netbox_dns/forms/__init__.py +1 -1
- netbox_dns/forms/{registration_contact.py → contact.py} +16 -16
- netbox_dns/forms/view.py +7 -95
- netbox_dns/forms/zone.py +17 -22
- netbox_dns/forms/zone_template.py +13 -13
- netbox_dns/graphql/__init__.py +2 -2
- netbox_dns/graphql/filters.py +5 -5
- netbox_dns/graphql/schema.py +44 -24
- netbox_dns/graphql/types.py +12 -40
- netbox_dns/management/commands/{setup_dnssync.py → setup_autodns.py} +28 -48
- netbox_dns/migrations/{0008_view_prefixes.py → 0007_view_prefixes.py} +1 -1
- netbox_dns/models/__init__.py +1 -1
- netbox_dns/models/{registration_contact.py → contact.py} +9 -15
- netbox_dns/models/nameserver.py +3 -8
- netbox_dns/models/record.py +28 -93
- netbox_dns/models/record_template.py +1 -4
- netbox_dns/models/registrar.py +1 -7
- netbox_dns/models/view.py +2 -9
- netbox_dns/models/zone.py +22 -59
- netbox_dns/models/zone_template.py +9 -12
- netbox_dns/navigation.py +7 -7
- netbox_dns/signals/ipam_autodns.py +138 -0
- netbox_dns/tables/__init__.py +1 -1
- netbox_dns/tables/{registration_contact.py → contact.py} +6 -5
- netbox_dns/tables/nameserver.py +7 -1
- netbox_dns/tables/record.py +30 -43
- netbox_dns/tables/record_template.py +17 -0
- netbox_dns/tables/registrar.py +2 -0
- netbox_dns/tables/view.py +8 -1
- netbox_dns/tables/zone.py +15 -0
- netbox_dns/tables/zone_template.py +16 -2
- netbox_dns/template_content.py +2 -14
- netbox_dns/templates/netbox_dns/{registrationcontact.html → contact.html} +1 -1
- netbox_dns/templates/netbox_dns/view.html +7 -3
- netbox_dns/urls/__init__.py +2 -2
- netbox_dns/urls/contact.py +51 -0
- netbox_dns/urls/nameserver.py +38 -14
- netbox_dns/urls/record.py +19 -7
- netbox_dns/urls/record_template.py +27 -18
- netbox_dns/urls/registrar.py +35 -11
- netbox_dns/urls/view.py +20 -12
- netbox_dns/urls/zone.py +46 -8
- netbox_dns/urls/zone_template.py +26 -16
- netbox_dns/utilities/__init__.py +1 -1
- netbox_dns/utilities/{ipam_dnssync.py → ipam_autodns.py} +32 -122
- netbox_dns/validators/dns_name.py +0 -9
- netbox_dns/views/__init__.py +1 -1
- netbox_dns/views/contact.py +95 -0
- netbox_dns/views/nameserver.py +3 -7
- netbox_dns/views/record.py +7 -12
- netbox_dns/views/record_template.py +1 -1
- netbox_dns/views/registrar.py +1 -0
- netbox_dns/views/view.py +2 -32
- netbox_dns/views/zone.py +6 -7
- netbox_dns/views/zone_template.py +2 -2
- {netbox_plugin_dns-1.1.0.dist-info → netbox_plugin_dns-1.1.0b1.dist-info}/METADATA +2 -3
- netbox_plugin_dns-1.1.0b1.dist-info/RECORD +140 -0
- netbox_dns/management/commands/rebuild_dnssync.py +0 -18
- netbox_dns/migrations/0007_alter_ordering_options.py +0 -25
- netbox_dns/migrations/0009_rename_contact_registrationcontact.py +0 -27
- netbox_dns/signals/ipam_dnssync.py +0 -224
- netbox_dns/tables/ipam_dnssync.py +0 -11
- netbox_dns/templates/netbox_dns/view/button.html +0 -9
- netbox_dns/templates/netbox_dns/view/prefix.html +0 -41
- netbox_dns/urls/registration_contact.py +0 -60
- netbox_dns/views/registration_contact.py +0 -94
- netbox_plugin_dns-1.1.0.dist-info/RECORD +0 -146
- {netbox_plugin_dns-1.1.0.dist-info → netbox_plugin_dns-1.1.0b1.dist-info}/LICENSE +0 -0
- {netbox_plugin_dns-1.1.0.dist-info → netbox_plugin_dns-1.1.0b1.dist-info}/WHEEL +0 -0
|
@@ -7,7 +7,7 @@ from ipam.models import IPAddress
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class Command(BaseCommand):
|
|
10
|
-
help = "Setup IPAddress custom fields for IPAM
|
|
10
|
+
help = "Setup IPAddress custom fields for IPAM AutoDNS"
|
|
11
11
|
|
|
12
12
|
def add_arguments(self, parser):
|
|
13
13
|
parser.add_argument(
|
|
@@ -19,7 +19,7 @@ class Command(BaseCommand):
|
|
|
19
19
|
|
|
20
20
|
if options.get("remove"):
|
|
21
21
|
if options.get("verbosity"):
|
|
22
|
-
self.stdout.write("Trying to remove IPAM
|
|
22
|
+
self.stdout.write(f"Trying to remove IPAM AutoDNS custom fields")
|
|
23
23
|
for cf in (
|
|
24
24
|
"ipaddress_dns_disabled",
|
|
25
25
|
"ipaddress_dns_record_ttl",
|
|
@@ -29,8 +29,8 @@ class Command(BaseCommand):
|
|
|
29
29
|
CustomField.objects.get(
|
|
30
30
|
name=cf, object_types=ipaddress_object_type
|
|
31
31
|
).delete()
|
|
32
|
-
if options.get("verbosity"):
|
|
33
|
-
self.stdout.write(f"
|
|
32
|
+
if options.get("verbosity") >= 2:
|
|
33
|
+
self.stdout.write(f"Custom field '{cf}' removed")
|
|
34
34
|
except CustomField.DoesNotExist:
|
|
35
35
|
pass
|
|
36
36
|
return
|
|
@@ -38,8 +38,8 @@ class Command(BaseCommand):
|
|
|
38
38
|
# +
|
|
39
39
|
# Remove pre-existing IPAM Coupling custom fields
|
|
40
40
|
# -
|
|
41
|
-
if options.get("verbosity")
|
|
42
|
-
self.stdout.write("Trying to remove obsolete IPAM Coupling custom fields")
|
|
41
|
+
if options.get("verbosity"):
|
|
42
|
+
self.stdout.write(f"Trying to remove obsolete IPAM Coupling custom fields")
|
|
43
43
|
for cf in (
|
|
44
44
|
"ipaddress_dns_record_name",
|
|
45
45
|
"ipaddress_dns_zone_id",
|
|
@@ -48,47 +48,39 @@ class Command(BaseCommand):
|
|
|
48
48
|
CustomField.objects.get(
|
|
49
49
|
name=cf, object_types=ipaddress_object_type
|
|
50
50
|
).delete()
|
|
51
|
-
if options.get("verbosity"):
|
|
51
|
+
if options.get("verbosity") >= 2:
|
|
52
52
|
self.stdout.write(f"Removed custom field '{cf}'")
|
|
53
53
|
except CustomField.DoesNotExist:
|
|
54
54
|
pass
|
|
55
55
|
|
|
56
|
-
if options.get("verbosity")
|
|
57
|
-
self.stdout.write("Creating IPAM
|
|
56
|
+
if options.get("verbosity"):
|
|
57
|
+
self.stdout.write(f"Creating IPAM AutoDNS custom fields")
|
|
58
58
|
|
|
59
59
|
if not CustomField.objects.filter(
|
|
60
60
|
name="ipaddress_dns_disabled",
|
|
61
61
|
type=CustomFieldTypeChoices.TYPE_BOOLEAN,
|
|
62
62
|
object_types=ipaddress_object_type,
|
|
63
63
|
).exists():
|
|
64
|
-
|
|
64
|
+
cf_disable_ptr = CustomField.objects.create(
|
|
65
65
|
name="ipaddress_dns_disabled",
|
|
66
|
-
label="Disable
|
|
66
|
+
label="Disable AutoDNS",
|
|
67
67
|
description="Disable DNS address and pointer record generation for this address",
|
|
68
68
|
type=CustomFieldTypeChoices.TYPE_BOOLEAN,
|
|
69
69
|
required=False,
|
|
70
70
|
default=False,
|
|
71
|
-
group_name="
|
|
71
|
+
group_name="AutoDNS",
|
|
72
72
|
is_cloneable=True,
|
|
73
73
|
weight=100,
|
|
74
74
|
)
|
|
75
|
-
|
|
76
|
-
if options.get("verbosity"):
|
|
75
|
+
cf_disable_ptr.object_types.set([ipaddress_object_type])
|
|
76
|
+
if options.get("verbosity") >= 2:
|
|
77
77
|
self.stdout.write("Created custom field 'ipaddress_dns_disabled'")
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
)
|
|
85
|
-
if cf_ttl.group_name != "DNSsync":
|
|
86
|
-
cf_ttl.group_name = "DNSsync"
|
|
87
|
-
cf_ttl.description = ("TTL for DNS records created for this address",)
|
|
88
|
-
cf_ttl.save()
|
|
89
|
-
if options.get("verbosity"):
|
|
90
|
-
self.stdout.write("Updated custom field 'ipaddress_dns_record_ttl'")
|
|
91
|
-
except CustomField.DoesNotExist:
|
|
79
|
+
if not CustomField.objects.filter(
|
|
80
|
+
name="ipaddress_dns_record_ttl",
|
|
81
|
+
type=CustomFieldTypeChoices.TYPE_INTEGER,
|
|
82
|
+
object_types=ipaddress_object_type,
|
|
83
|
+
).exists():
|
|
92
84
|
cf_ttl = CustomField.objects.create(
|
|
93
85
|
name="ipaddress_dns_record_ttl",
|
|
94
86
|
description="TTL for DNS records created for this address",
|
|
@@ -97,31 +89,19 @@ class Command(BaseCommand):
|
|
|
97
89
|
validation_minimum=0,
|
|
98
90
|
validation_maximum=2147483647,
|
|
99
91
|
required=False,
|
|
100
|
-
group_name="
|
|
92
|
+
group_name="AutoDNS",
|
|
101
93
|
is_cloneable=True,
|
|
102
94
|
weight=200,
|
|
103
95
|
)
|
|
104
96
|
cf_ttl.object_types.set([ipaddress_object_type])
|
|
105
|
-
if options.get("verbosity"):
|
|
97
|
+
if options.get("verbosity") >= 2:
|
|
106
98
|
self.stdout.write("Created custom field 'ipaddress_dns_record_ttl'")
|
|
107
99
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
)
|
|
114
|
-
if cf_disable_ptr.group_name != "DNSsync":
|
|
115
|
-
cf_disable_ptr.group_name = "DNSsync"
|
|
116
|
-
cf_disable_ptr.description = (
|
|
117
|
-
"Disable DNS PTR record generation for this address",
|
|
118
|
-
)
|
|
119
|
-
cf_disable_ptr.save()
|
|
120
|
-
if options.get("verbosity"):
|
|
121
|
-
self.stdout.write(
|
|
122
|
-
"Updated custom field 'ipaddress_dns_record_disable_ptr'"
|
|
123
|
-
)
|
|
124
|
-
except CustomField.DoesNotExist:
|
|
100
|
+
if not CustomField.objects.filter(
|
|
101
|
+
name="ipaddress_dns_record_disable_ptr",
|
|
102
|
+
type=CustomFieldTypeChoices.TYPE_BOOLEAN,
|
|
103
|
+
object_types=ipaddress_object_type,
|
|
104
|
+
).exists():
|
|
125
105
|
cf_disable_ptr = CustomField.objects.create(
|
|
126
106
|
name="ipaddress_dns_record_disable_ptr",
|
|
127
107
|
description="Disable DNS PTR record generation for this address",
|
|
@@ -129,12 +109,12 @@ class Command(BaseCommand):
|
|
|
129
109
|
type=CustomFieldTypeChoices.TYPE_BOOLEAN,
|
|
130
110
|
required=False,
|
|
131
111
|
default=False,
|
|
132
|
-
group_name="
|
|
112
|
+
group_name="AutoDNS",
|
|
133
113
|
is_cloneable=True,
|
|
134
114
|
weight=300,
|
|
135
115
|
)
|
|
136
116
|
cf_disable_ptr.object_types.set([ipaddress_object_type])
|
|
137
|
-
if options.get("verbosity"):
|
|
117
|
+
if options.get("verbosity") >= 2:
|
|
138
118
|
self.stdout.write(
|
|
139
119
|
"Created custom field 'ipaddress_dns_record_disable_ptr'"
|
|
140
120
|
)
|
netbox_dns/models/__init__.py
CHANGED
|
@@ -8,12 +8,12 @@ from taggit.managers import TaggableManager
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
__all__ = (
|
|
11
|
-
"
|
|
12
|
-
"
|
|
11
|
+
"Contact",
|
|
12
|
+
"ContactIndex",
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
class
|
|
16
|
+
class Contact(NetBoxModel):
|
|
17
17
|
# +
|
|
18
18
|
# Data fields according to https://www.icann.org/resources/pages/rdds-labeling-policy-2017-02-01-en
|
|
19
19
|
# -
|
|
@@ -87,7 +87,7 @@ class RegistrationContact(NetBoxModel):
|
|
|
87
87
|
related_name="netbox_dns_contact_set",
|
|
88
88
|
)
|
|
89
89
|
|
|
90
|
-
clone_fields =
|
|
90
|
+
clone_fields = [
|
|
91
91
|
"name",
|
|
92
92
|
"description",
|
|
93
93
|
"organization",
|
|
@@ -102,10 +102,10 @@ class RegistrationContact(NetBoxModel):
|
|
|
102
102
|
"fax_ext",
|
|
103
103
|
"email",
|
|
104
104
|
"tags",
|
|
105
|
-
|
|
105
|
+
]
|
|
106
106
|
|
|
107
107
|
def get_absolute_url(self):
|
|
108
|
-
return reverse("plugins:netbox_dns:
|
|
108
|
+
return reverse("plugins:netbox_dns:contact", kwargs={"pk": self.pk})
|
|
109
109
|
|
|
110
110
|
def __str__(self):
|
|
111
111
|
if self.name is not None:
|
|
@@ -114,13 +114,7 @@ class RegistrationContact(NetBoxModel):
|
|
|
114
114
|
return self.contact_id
|
|
115
115
|
|
|
116
116
|
class Meta:
|
|
117
|
-
|
|
118
|
-
verbose_name_plural = "Registration Contacts"
|
|
119
|
-
|
|
120
|
-
ordering = (
|
|
121
|
-
"name",
|
|
122
|
-
"contact_id",
|
|
123
|
-
)
|
|
117
|
+
ordering = ("name", "contact_id")
|
|
124
118
|
|
|
125
119
|
@property
|
|
126
120
|
def zones(self):
|
|
@@ -133,8 +127,8 @@ class RegistrationContact(NetBoxModel):
|
|
|
133
127
|
|
|
134
128
|
|
|
135
129
|
@register_search
|
|
136
|
-
class
|
|
137
|
-
model =
|
|
130
|
+
class ContactIndex(SearchIndex):
|
|
131
|
+
model = Contact
|
|
138
132
|
fields = (
|
|
139
133
|
("name", 100),
|
|
140
134
|
("contact_id", 100),
|
netbox_dns/models/nameserver.py
CHANGED
|
@@ -7,7 +7,6 @@ from django.urls import reverse
|
|
|
7
7
|
|
|
8
8
|
from netbox.models import NetBoxModel
|
|
9
9
|
from netbox.search import SearchIndex, register_search
|
|
10
|
-
from netbox.models.features import ContactsMixin
|
|
11
10
|
|
|
12
11
|
from netbox_dns.utilities import (
|
|
13
12
|
name_to_unicode,
|
|
@@ -27,7 +26,7 @@ __all__ = (
|
|
|
27
26
|
)
|
|
28
27
|
|
|
29
28
|
|
|
30
|
-
class NameServer(ObjectModificationMixin,
|
|
29
|
+
class NameServer(ObjectModificationMixin, NetBoxModel):
|
|
31
30
|
name = models.CharField(
|
|
32
31
|
unique=True,
|
|
33
32
|
max_length=255,
|
|
@@ -44,17 +43,13 @@ class NameServer(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
44
43
|
null=True,
|
|
45
44
|
)
|
|
46
45
|
|
|
47
|
-
clone_fields =
|
|
48
|
-
"name",
|
|
49
|
-
"description",
|
|
50
|
-
)
|
|
46
|
+
clone_fields = ["name", "description"]
|
|
51
47
|
|
|
52
48
|
class Meta:
|
|
49
|
+
ordering = ("name",)
|
|
53
50
|
verbose_name = "Nameserver"
|
|
54
51
|
verbose_name_plural = "Nameservers"
|
|
55
52
|
|
|
56
|
-
ordering = ("name",)
|
|
57
|
-
|
|
58
53
|
def __str__(self):
|
|
59
54
|
try:
|
|
60
55
|
return dns_name.from_text(self.name, origin=None).to_unicode()
|
netbox_dns/models/record.py
CHANGED
|
@@ -10,7 +10,6 @@ from django.urls import reverse
|
|
|
10
10
|
from django.conf import settings
|
|
11
11
|
|
|
12
12
|
from netbox.models import NetBoxModel
|
|
13
|
-
from netbox.models.features import ContactsMixin
|
|
14
13
|
from netbox.search import SearchIndex, register_search
|
|
15
14
|
from netbox.plugins.utils import get_plugin_config
|
|
16
15
|
from utilities.querysets import RestrictedQuerySet
|
|
@@ -59,7 +58,7 @@ def record_data_from_ip_address(ip_address, zone):
|
|
|
59
58
|
RecordStatusChoices.STATUS_ACTIVE
|
|
60
59
|
if ip_address.status
|
|
61
60
|
in settings.PLUGINS_CONFIG["netbox_dns"].get(
|
|
62
|
-
"
|
|
61
|
+
"autodns_ipaddress_active_status", []
|
|
63
62
|
)
|
|
64
63
|
else RecordStatusChoices.STATUS_INACTIVE
|
|
65
64
|
),
|
|
@@ -101,7 +100,7 @@ class RecordManager(models.Manager.from_queryset(RestrictedQuerySet)):
|
|
|
101
100
|
)
|
|
102
101
|
|
|
103
102
|
|
|
104
|
-
class Record(ObjectModificationMixin,
|
|
103
|
+
class Record(ObjectModificationMixin, NetBoxModel):
|
|
105
104
|
ACTIVE_STATUS_LIST = (RecordStatusChoices.STATUS_ACTIVE,)
|
|
106
105
|
|
|
107
106
|
unique_ptr_qs = Q(
|
|
@@ -194,7 +193,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
194
193
|
objects = RecordManager()
|
|
195
194
|
raw_objects = RestrictedQuerySet.as_manager()
|
|
196
195
|
|
|
197
|
-
clone_fields =
|
|
196
|
+
clone_fields = [
|
|
198
197
|
"zone",
|
|
199
198
|
"type",
|
|
200
199
|
"name",
|
|
@@ -203,20 +202,10 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
203
202
|
"ttl",
|
|
204
203
|
"disable_ptr",
|
|
205
204
|
"description",
|
|
206
|
-
|
|
205
|
+
]
|
|
207
206
|
|
|
208
207
|
class Meta:
|
|
209
|
-
|
|
210
|
-
verbose_name_plural = "Records"
|
|
211
|
-
|
|
212
|
-
ordering = (
|
|
213
|
-
"fqdn",
|
|
214
|
-
"zone",
|
|
215
|
-
"name",
|
|
216
|
-
"type",
|
|
217
|
-
"value",
|
|
218
|
-
"status",
|
|
219
|
-
)
|
|
208
|
+
ordering = ("zone", "name", "type", "value", "status")
|
|
220
209
|
|
|
221
210
|
def __str__(self):
|
|
222
211
|
try:
|
|
@@ -472,11 +461,8 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
472
461
|
self.rfc2317_cname_record.delete(save_zone_serial=save_zone_serial)
|
|
473
462
|
self.rfc2317_cname_record = None
|
|
474
463
|
|
|
475
|
-
def update_from_ip_address(self, ip_address
|
|
476
|
-
|
|
477
|
-
zone = self.zone
|
|
478
|
-
|
|
479
|
-
data = record_data_from_ip_address(ip_address, zone)
|
|
464
|
+
def update_from_ip_address(self, ip_address):
|
|
465
|
+
data = record_data_from_ip_address(ip_address, self.zone)
|
|
480
466
|
|
|
481
467
|
if data is None:
|
|
482
468
|
self.delete()
|
|
@@ -504,38 +490,29 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
504
490
|
**data,
|
|
505
491
|
)
|
|
506
492
|
|
|
507
|
-
def
|
|
508
|
-
|
|
509
|
-
|
|
493
|
+
def validate_name(self):
|
|
494
|
+
try:
|
|
495
|
+
_zone = dns_name.from_text(self.zone.name, origin=dns_name.root)
|
|
496
|
+
name = dns_name.from_text(self.name, origin=None)
|
|
497
|
+
fqdn = dns_name.from_text(self.name, origin=_zone)
|
|
498
|
+
|
|
499
|
+
_zone.to_unicode()
|
|
500
|
+
name.to_unicode()
|
|
510
501
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
fqdn = dns_name.from_text(self.name, origin=_zone)
|
|
502
|
+
self.name = name.relativize(_zone).to_text()
|
|
503
|
+
self.fqdn = fqdn.to_text()
|
|
514
504
|
|
|
515
|
-
|
|
505
|
+
except dns.exception.DNSException as exc:
|
|
516
506
|
raise ValidationError(
|
|
517
507
|
{
|
|
518
|
-
"name":
|
|
508
|
+
"name": str(exc),
|
|
519
509
|
}
|
|
520
510
|
)
|
|
521
511
|
|
|
522
|
-
|
|
523
|
-
name.to_unicode()
|
|
524
|
-
|
|
525
|
-
self.name = name.relativize(_zone).to_text()
|
|
526
|
-
self.fqdn = fqdn.to_text()
|
|
527
|
-
|
|
528
|
-
def validate_name(self, new_zone=None):
|
|
529
|
-
if new_zone is None:
|
|
530
|
-
new_zone = self.zone
|
|
531
|
-
|
|
532
|
-
try:
|
|
533
|
-
self.update_fqdn(zone=new_zone)
|
|
534
|
-
|
|
535
|
-
except dns.exception.DNSException as exc:
|
|
512
|
+
if not fqdn.is_subdomain(_zone):
|
|
536
513
|
raise ValidationError(
|
|
537
514
|
{
|
|
538
|
-
"name":
|
|
515
|
+
"name": f"{self.name} is not a name in {self.zone.name}",
|
|
539
516
|
}
|
|
540
517
|
)
|
|
541
518
|
|
|
@@ -567,18 +544,15 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
567
544
|
except ValidationError as exc:
|
|
568
545
|
raise ValidationError({"value": exc}) from None
|
|
569
546
|
|
|
570
|
-
def check_unique_record(self
|
|
547
|
+
def check_unique_record(self):
|
|
571
548
|
if not get_plugin_config("netbox_dns", "enforce_unique_records", False):
|
|
572
549
|
return
|
|
573
550
|
|
|
574
551
|
if not self.is_active:
|
|
575
552
|
return
|
|
576
553
|
|
|
577
|
-
if new_zone is None:
|
|
578
|
-
new_zone = self.zone
|
|
579
|
-
|
|
580
554
|
records = Record.objects.filter(
|
|
581
|
-
zone=
|
|
555
|
+
zone=self.zone,
|
|
582
556
|
name=self.name,
|
|
583
557
|
type=self.type,
|
|
584
558
|
value=self.value,
|
|
@@ -588,41 +562,13 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
588
562
|
if self.pk is not None:
|
|
589
563
|
records = records.exclude(pk=self.pk)
|
|
590
564
|
|
|
591
|
-
if records
|
|
592
|
-
if self.ipam_ip_address is not None:
|
|
593
|
-
if not records.filter(
|
|
594
|
-
ipam_ip_address__isnull=True
|
|
595
|
-
).exists() or get_plugin_config(
|
|
596
|
-
"netbox_dns", "dnssync_conflict_deactivate", False
|
|
597
|
-
):
|
|
598
|
-
return
|
|
599
|
-
|
|
565
|
+
if len(records):
|
|
600
566
|
raise ValidationError(
|
|
601
567
|
{
|
|
602
568
|
"value": f"There is already an active {self.type} record for name {self.name} in zone {self.zone} with value {self.value}."
|
|
603
569
|
}
|
|
604
570
|
) from None
|
|
605
571
|
|
|
606
|
-
def handle_conflicting_address_records(self):
|
|
607
|
-
if self.ipam_ip_address is None or not self.is_active:
|
|
608
|
-
return
|
|
609
|
-
|
|
610
|
-
if not get_plugin_config("netbox_dns", "dnssync_conflict_deactivate", False):
|
|
611
|
-
return
|
|
612
|
-
|
|
613
|
-
records = Record.objects.filter(
|
|
614
|
-
zone=self.zone,
|
|
615
|
-
name=self.name,
|
|
616
|
-
type=self.type,
|
|
617
|
-
value=self.value,
|
|
618
|
-
status__in=Record.ACTIVE_STATUS_LIST,
|
|
619
|
-
ipam_ip_address__isnull=True,
|
|
620
|
-
)
|
|
621
|
-
|
|
622
|
-
for record in records:
|
|
623
|
-
record.status = RecordStatusChoices.STATUS_INACTIVE
|
|
624
|
-
record.save(update_fields=["status"])
|
|
625
|
-
|
|
626
572
|
def check_unique_rrset_ttl(self):
|
|
627
573
|
if self.pk is not None:
|
|
628
574
|
return
|
|
@@ -630,11 +576,6 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
630
576
|
if not get_plugin_config("netbox_dns", "enforce_unique_rrset_ttl", False):
|
|
631
577
|
return
|
|
632
578
|
|
|
633
|
-
if self.ipam_ip_address is not None and get_plugin_config(
|
|
634
|
-
"netbox_dns", "dnssync_conflict_deactivate", False
|
|
635
|
-
):
|
|
636
|
-
return
|
|
637
|
-
|
|
638
579
|
if self.type == RecordTypeChoices.PTR and self.managed:
|
|
639
580
|
return
|
|
640
581
|
|
|
@@ -646,16 +587,12 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
646
587
|
)
|
|
647
588
|
.exclude(ttl=self.ttl)
|
|
648
589
|
.exclude(type=RecordTypeChoices.PTR, managed=True)
|
|
649
|
-
.exclude(status=RecordStatusChoices.STATUS_INACTIVE)
|
|
650
590
|
)
|
|
651
591
|
|
|
652
|
-
if self.ipam_ip_address is not None:
|
|
653
|
-
records = records.exclude(ipam_ip_address__isnull=False)
|
|
654
|
-
|
|
655
592
|
if not records.exists():
|
|
656
593
|
return
|
|
657
594
|
|
|
658
|
-
conflicting_ttls = ", ".join(
|
|
595
|
+
conflicting_ttls = ", ".join(set(str(record.ttl) for record in records))
|
|
659
596
|
raise ValidationError(
|
|
660
597
|
{
|
|
661
598
|
"ttl": f"There is at least one active {self.type} record for name {self.name} in zone {self.zone} and TTL is different ({conflicting_ttls})."
|
|
@@ -684,7 +621,6 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
684
621
|
.exclude(pk=self.pk)
|
|
685
622
|
.exclude(ttl=ttl)
|
|
686
623
|
.exclude(type=RecordTypeChoices.PTR, managed=True)
|
|
687
|
-
.exclude(status=RecordStatusChoices.STATUS_INACTIVE)
|
|
688
624
|
)
|
|
689
625
|
|
|
690
626
|
for record in records:
|
|
@@ -695,10 +631,10 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
695
631
|
self.type = self.type.upper()
|
|
696
632
|
super().clean_fields(*args, **kwargs)
|
|
697
633
|
|
|
698
|
-
def clean(self, *args,
|
|
699
|
-
self.validate_name(
|
|
634
|
+
def clean(self, *args, **kwargs):
|
|
635
|
+
self.validate_name()
|
|
700
636
|
self.validate_value()
|
|
701
|
-
self.check_unique_record(
|
|
637
|
+
self.check_unique_record()
|
|
702
638
|
if self.pk is None:
|
|
703
639
|
self.check_unique_rrset_ttl()
|
|
704
640
|
|
|
@@ -804,7 +740,6 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
804
740
|
self.ip_address = None
|
|
805
741
|
|
|
806
742
|
if self.is_address_record:
|
|
807
|
-
self.handle_conflicting_address_records()
|
|
808
743
|
self.update_ptr_record(
|
|
809
744
|
update_rfc2317_cname=update_rfc2317_cname,
|
|
810
745
|
save_zone_serial=save_zone_serial,
|
netbox_dns/models/registrar.py
CHANGED
|
@@ -59,13 +59,7 @@ class Registrar(NetBoxModel):
|
|
|
59
59
|
return str(self.name)
|
|
60
60
|
|
|
61
61
|
class Meta:
|
|
62
|
-
|
|
63
|
-
verbose_name_plural = "Registrars"
|
|
64
|
-
|
|
65
|
-
ordering = (
|
|
66
|
-
"name",
|
|
67
|
-
"iana_id",
|
|
68
|
-
)
|
|
62
|
+
ordering = ("name", "iana_id")
|
|
69
63
|
|
|
70
64
|
|
|
71
65
|
@register_search
|
netbox_dns/models/view.py
CHANGED
|
@@ -3,7 +3,6 @@ from django.urls import reverse
|
|
|
3
3
|
from django.core.exceptions import ValidationError
|
|
4
4
|
|
|
5
5
|
from netbox.models import NetBoxModel
|
|
6
|
-
from netbox.models.features import ContactsMixin
|
|
7
6
|
from netbox.search import SearchIndex, register_search
|
|
8
7
|
from netbox.context import current_request
|
|
9
8
|
from utilities.exceptions import AbortRequest
|
|
@@ -17,7 +16,7 @@ __all__ = (
|
|
|
17
16
|
)
|
|
18
17
|
|
|
19
18
|
|
|
20
|
-
class View(ObjectModificationMixin,
|
|
19
|
+
class View(ObjectModificationMixin, NetBoxModel):
|
|
21
20
|
name = models.CharField(
|
|
22
21
|
unique=True,
|
|
23
22
|
max_length=255,
|
|
@@ -42,10 +41,7 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
42
41
|
null=True,
|
|
43
42
|
)
|
|
44
43
|
|
|
45
|
-
clone_fields =
|
|
46
|
-
"name",
|
|
47
|
-
"description",
|
|
48
|
-
)
|
|
44
|
+
clone_fields = ["name", "description"]
|
|
49
45
|
|
|
50
46
|
@classmethod
|
|
51
47
|
def get_default_view(cls):
|
|
@@ -58,9 +54,6 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
58
54
|
return str(self.name)
|
|
59
55
|
|
|
60
56
|
class Meta:
|
|
61
|
-
verbose_name = "View"
|
|
62
|
-
verbose_name_plural = "Views"
|
|
63
|
-
|
|
64
57
|
ordering = ("name",)
|
|
65
58
|
|
|
66
59
|
def delete(self, *args, **kwargs):
|