netbox-plugin-dns 1.1.1__py3-none-any.whl → 1.1.2__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 +3 -2
- netbox_dns/api/serializers_/view.py +1 -0
- netbox_dns/forms/view.py +29 -10
- netbox_dns/graphql/schema.py +0 -10
- netbox_dns/graphql/types.py +1 -0
- netbox_dns/migrations/0010_view_ip_address_filter.py +18 -0
- netbox_dns/mixins/object_modification.py +30 -8
- netbox_dns/models/record.py +32 -10
- netbox_dns/models/view.py +40 -0
- netbox_dns/models/zone.py +12 -7
- netbox_dns/signals/ipam_dnssync.py +4 -4
- netbox_dns/tables/view.py +1 -1
- netbox_dns/templates/netbox_dns/view.html +16 -0
- netbox_dns/utilities/ipam_dnssync.py +57 -25
- {netbox_plugin_dns-1.1.1.dist-info → netbox_plugin_dns-1.1.2.dist-info}/METADATA +1 -1
- {netbox_plugin_dns-1.1.1.dist-info → netbox_plugin_dns-1.1.2.dist-info}/RECORD +19 -18
- {netbox_plugin_dns-1.1.1.dist-info → netbox_plugin_dns-1.1.2.dist-info}/WHEEL +1 -1
- {netbox_plugin_dns-1.1.1.dist-info → netbox_plugin_dns-1.1.2.dist-info}/LICENSE +0 -0
- {netbox_plugin_dns-1.1.1.dist-info → netbox_plugin_dns-1.1.2.dist-info}/top_level.txt +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.2"
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class DNSConfig(PluginConfig):
|
|
@@ -37,8 +37,9 @@ class DNSConfig(PluginConfig):
|
|
|
37
37
|
"tolerate_underscores_in_labels": False,
|
|
38
38
|
"tolerate_underscores_in_hostnames": False, # Deprecated, will be removed in 1.2.0
|
|
39
39
|
"tolerate_leading_underscore_types": [
|
|
40
|
-
RecordTypeChoices.TXT,
|
|
41
40
|
RecordTypeChoices.SRV,
|
|
41
|
+
RecordTypeChoices.TLSA,
|
|
42
|
+
RecordTypeChoices.TXT,
|
|
42
43
|
],
|
|
43
44
|
"tolerate_non_rfc1035_types": [],
|
|
44
45
|
"enable_root_zones": False,
|
netbox_dns/forms/view.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from django import forms
|
|
2
2
|
from django.conf import settings
|
|
3
|
-
from django.core.exceptions import ValidationError
|
|
3
|
+
from django.core.exceptions import ValidationError, FieldError
|
|
4
4
|
from django.db.models import Q, Count
|
|
5
5
|
|
|
6
6
|
from netbox.forms import (
|
|
@@ -18,9 +18,10 @@ from utilities.forms.fields import (
|
|
|
18
18
|
)
|
|
19
19
|
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES
|
|
20
20
|
from utilities.forms.rendering import FieldSet
|
|
21
|
+
from utilities.forms.fields import JSONField
|
|
21
22
|
from tenancy.models import Tenant
|
|
22
23
|
from tenancy.forms import TenancyForm, TenancyFilterForm
|
|
23
|
-
from ipam.models import Prefix
|
|
24
|
+
from ipam.models import Prefix, IPAddress
|
|
24
25
|
from netbox.context import current_request
|
|
25
26
|
|
|
26
27
|
from netbox_dns.models import View
|
|
@@ -29,6 +30,7 @@ from netbox_dns.utilities import (
|
|
|
29
30
|
check_dns_records,
|
|
30
31
|
get_ip_addresses_by_prefix,
|
|
31
32
|
get_views_by_prefix,
|
|
33
|
+
get_query_from_filter,
|
|
32
34
|
)
|
|
33
35
|
|
|
34
36
|
|
|
@@ -45,7 +47,7 @@ class ViewPrefixUpdateMixin:
|
|
|
45
47
|
def clean(self, *args, **kwargs):
|
|
46
48
|
super().clean(*args, **kwargs)
|
|
47
49
|
|
|
48
|
-
if self.instance.
|
|
50
|
+
if self.instance._state.adding or "prefixes" not in self.changed_data:
|
|
49
51
|
return
|
|
50
52
|
|
|
51
53
|
prefixes = self.cleaned_data.get("prefixes")
|
|
@@ -97,6 +99,7 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
|
97
99
|
|
|
98
100
|
if settings.PLUGINS_CONFIG["netbox_dns"].get("dnssync_disabled"):
|
|
99
101
|
del self.fields["prefixes"]
|
|
102
|
+
del self.fields["ip_address_filter"]
|
|
100
103
|
|
|
101
104
|
if request := current_request.get():
|
|
102
105
|
if not request.user.has_perm("ipam.view_prefix"):
|
|
@@ -107,12 +110,6 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
|
107
110
|
"placeholder"
|
|
108
111
|
] = "You do not have permission to modify assigned prefixes"
|
|
109
112
|
|
|
110
|
-
def clean_prefixes(self):
|
|
111
|
-
if hasattr(self, "_saved_prefixes"):
|
|
112
|
-
return self._saved_prefixes
|
|
113
|
-
|
|
114
|
-
return self.cleaned_data["prefixes"]
|
|
115
|
-
|
|
116
113
|
prefixes = PrefixDynamicModelMultipleChoiceField(
|
|
117
114
|
queryset=Prefix.objects.all(),
|
|
118
115
|
required=False,
|
|
@@ -121,10 +118,15 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
|
121
118
|
"depth": None,
|
|
122
119
|
},
|
|
123
120
|
)
|
|
121
|
+
ip_address_filter = JSONField(
|
|
122
|
+
label="IP Address Filter",
|
|
123
|
+
required=False,
|
|
124
|
+
help_text="Specify criteria for address record creation in JSON form",
|
|
125
|
+
)
|
|
124
126
|
|
|
125
127
|
fieldsets = (
|
|
126
128
|
FieldSet("name", "default_view", "description", "tags", name="View"),
|
|
127
|
-
FieldSet("prefixes"),
|
|
129
|
+
FieldSet("prefixes", "ip_address_filter"),
|
|
128
130
|
FieldSet("tenant_group", "tenant", name="Tenancy"),
|
|
129
131
|
)
|
|
130
132
|
|
|
@@ -137,8 +139,25 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
|
137
139
|
"tags",
|
|
138
140
|
"tenant",
|
|
139
141
|
"prefixes",
|
|
142
|
+
"ip_address_filter",
|
|
140
143
|
)
|
|
141
144
|
|
|
145
|
+
def clean_prefixes(self):
|
|
146
|
+
if hasattr(self, "_saved_prefixes"):
|
|
147
|
+
return self._saved_prefixes
|
|
148
|
+
|
|
149
|
+
return self.cleaned_data["prefixes"]
|
|
150
|
+
|
|
151
|
+
def clean_ip_address_filter(self):
|
|
152
|
+
ip_address_filter = self.cleaned_data.get("ip_address_filter")
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
IPAddress.objects.filter(get_query_from_filter(ip_address_filter)).exists()
|
|
156
|
+
except (FieldError, ValueError) as exc:
|
|
157
|
+
self.add_error("ip_address_filter", f"Invalid filter for IPAddress: {exc}")
|
|
158
|
+
|
|
159
|
+
return ip_address_filter
|
|
160
|
+
|
|
142
161
|
|
|
143
162
|
class ViewFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
144
163
|
def __init__(self, *args, **kwargs):
|
netbox_dns/graphql/schema.py
CHANGED
|
@@ -3,16 +3,6 @@ from typing import List
|
|
|
3
3
|
import strawberry
|
|
4
4
|
import strawberry_django
|
|
5
5
|
|
|
6
|
-
from netbox_dns.models import (
|
|
7
|
-
NameServer,
|
|
8
|
-
View,
|
|
9
|
-
Zone,
|
|
10
|
-
Record,
|
|
11
|
-
RegistrationContact,
|
|
12
|
-
Registrar,
|
|
13
|
-
ZoneTemplate,
|
|
14
|
-
RecordTemplate,
|
|
15
|
-
)
|
|
16
6
|
from .types import (
|
|
17
7
|
NetBoxDNSNameServerType,
|
|
18
8
|
NetBoxDNSViewType,
|
netbox_dns/graphql/types.py
CHANGED
|
@@ -43,6 +43,7 @@ class NetBoxDNSViewType(NetBoxObjectType):
|
|
|
43
43
|
description: str
|
|
44
44
|
tenant: Annotated["TenantType", strawberry.lazy("tenancy.graphql.types")] | None
|
|
45
45
|
prefixes: List[Annotated["PrefixType", strawberry.lazy("ipam.graphql.types")]]
|
|
46
|
+
ip_address_filter: str | None
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
@strawberry_django.type(Zone, fields="__all__", filters=NetBoxDNSZoneFilter)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 5.0.9 on 2024-09-18 13:12
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("netbox_dns", "0009_rename_contact_registrationcontact"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="view",
|
|
15
|
+
name="ip_address_filter",
|
|
16
|
+
field=models.JSONField(blank=True, null=True),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -17,15 +17,37 @@ class ObjectModificationMixin:
|
|
|
17
17
|
|
|
18
18
|
self.__class__.check_fields.add("custom_field_data")
|
|
19
19
|
|
|
20
|
+
self._save_field_values()
|
|
21
|
+
|
|
22
|
+
def _save_field_values(self):
|
|
23
|
+
for field in self.check_fields:
|
|
24
|
+
if f"{field}_id" in self.__dict__:
|
|
25
|
+
setattr(self, f"_saved_{field}_id", self.__dict__.get(f"{field}_id"))
|
|
26
|
+
else:
|
|
27
|
+
setattr(self, f"_saved_{field}", self.__dict__.get(field))
|
|
28
|
+
|
|
29
|
+
def save(self, *args, **kwargs):
|
|
30
|
+
super().save(*args, **kwargs)
|
|
31
|
+
|
|
32
|
+
self._save_field_values()
|
|
33
|
+
|
|
20
34
|
@property
|
|
21
35
|
def changed_fields(self):
|
|
22
|
-
if self.
|
|
36
|
+
if self._state.adding:
|
|
23
37
|
return None
|
|
24
38
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
_changed_fields = set()
|
|
40
|
+
for field in self.check_fields:
|
|
41
|
+
if f"_saved_{field}_id" in self.__dict__:
|
|
42
|
+
if self.__dict__.get(f"_saved_{field}_id") != self.__dict__.get(
|
|
43
|
+
f"{field}_id"
|
|
44
|
+
):
|
|
45
|
+
_changed_fields.add(field)
|
|
46
|
+
else:
|
|
47
|
+
if self.__dict__.get(f"_saved_{field}") != self.__dict__.get(field):
|
|
48
|
+
_changed_fields.add(field)
|
|
49
|
+
|
|
50
|
+
return _changed_fields
|
|
51
|
+
|
|
52
|
+
def get_saved_value(self, field):
|
|
53
|
+
return self.__dict__.get(f"_saved_{field}")
|
netbox_dns/models/record.py
CHANGED
|
@@ -10,13 +10,14 @@ from django.urls import reverse
|
|
|
10
10
|
from django.conf import settings
|
|
11
11
|
|
|
12
12
|
from netbox.models import NetBoxModel
|
|
13
|
+
from ipam.models import IPAddress
|
|
13
14
|
from netbox.models.features import ContactsMixin
|
|
14
15
|
from netbox.search import SearchIndex, register_search
|
|
15
16
|
from netbox.plugins.utils import get_plugin_config
|
|
16
17
|
from utilities.querysets import RestrictedQuerySet
|
|
17
18
|
|
|
18
19
|
from netbox_dns.fields import AddressField
|
|
19
|
-
from netbox_dns.utilities import arpa_to_prefix, name_to_unicode
|
|
20
|
+
from netbox_dns.utilities import arpa_to_prefix, name_to_unicode, get_query_from_filter
|
|
20
21
|
from netbox_dns.validators import validate_generic_name, validate_record_value
|
|
21
22
|
from netbox_dns.mixins import ObjectModificationMixin
|
|
22
23
|
from netbox_dns.choices import RecordTypeChoices, RecordStatusChoices
|
|
@@ -41,6 +42,20 @@ def record_data_from_ip_address(ip_address, zone):
|
|
|
41
42
|
cf_data = ip_address.custom_field_data
|
|
42
43
|
|
|
43
44
|
if cf_data.get("ipaddress_dns_disabled"):
|
|
45
|
+
# +
|
|
46
|
+
# DNS record creation disabled for this address
|
|
47
|
+
# -
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
zone.view.ip_address_filter is not None
|
|
52
|
+
and not IPAddress.objects.filter(
|
|
53
|
+
Q(pk=ip_address.pk), get_query_from_filter(zone.view.ip_address_filter)
|
|
54
|
+
).exists()
|
|
55
|
+
):
|
|
56
|
+
# +
|
|
57
|
+
# IP address does not match the filter
|
|
58
|
+
# -
|
|
44
59
|
return None
|
|
45
60
|
|
|
46
61
|
data = {
|
|
@@ -473,22 +488,29 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
473
488
|
self.rfc2317_cname_record = None
|
|
474
489
|
|
|
475
490
|
def update_from_ip_address(self, ip_address, zone=None):
|
|
491
|
+
"""
|
|
492
|
+
Update an address record according to data from an IPAddress object.
|
|
493
|
+
|
|
494
|
+
Returns a tuple of two booleans: (update, delete).
|
|
495
|
+
|
|
496
|
+
update: The record was updated and needs to be cleaned and/or saved
|
|
497
|
+
delete: The record is no longer needed and needs to be deleted
|
|
498
|
+
"""
|
|
476
499
|
if zone is None:
|
|
477
500
|
zone = self.zone
|
|
478
501
|
|
|
479
502
|
data = record_data_from_ip_address(ip_address, zone)
|
|
480
503
|
|
|
481
504
|
if data is None:
|
|
482
|
-
|
|
483
|
-
return
|
|
505
|
+
return False, True
|
|
484
506
|
|
|
485
507
|
if all((getattr(self, attr) == data[attr] for attr in data.keys())):
|
|
486
|
-
return
|
|
508
|
+
return False, False
|
|
487
509
|
|
|
488
510
|
for attr, value in data.items():
|
|
489
511
|
setattr(self, attr, value)
|
|
490
512
|
|
|
491
|
-
return
|
|
513
|
+
return True, False
|
|
492
514
|
|
|
493
515
|
@classmethod
|
|
494
516
|
def create_from_ip_address(cls, ip_address, zone):
|
|
@@ -585,7 +607,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
585
607
|
status__in=Record.ACTIVE_STATUS_LIST,
|
|
586
608
|
)
|
|
587
609
|
|
|
588
|
-
if self.
|
|
610
|
+
if not self._state.adding:
|
|
589
611
|
records = records.exclude(pk=self.pk)
|
|
590
612
|
|
|
591
613
|
if records.exists():
|
|
@@ -624,7 +646,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
624
646
|
record.save(update_fields=["status"])
|
|
625
647
|
|
|
626
648
|
def check_unique_rrset_ttl(self):
|
|
627
|
-
if self.
|
|
649
|
+
if not self._state.adding:
|
|
628
650
|
return
|
|
629
651
|
|
|
630
652
|
if not get_plugin_config("netbox_dns", "enforce_unique_rrset_ttl", False):
|
|
@@ -663,7 +685,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
663
685
|
) from None
|
|
664
686
|
|
|
665
687
|
def update_rrset_ttl(self, ttl=None):
|
|
666
|
-
if self.
|
|
688
|
+
if self._state.adding:
|
|
667
689
|
return
|
|
668
690
|
|
|
669
691
|
if not get_plugin_config("netbox_dns", "enforce_unique_rrset_ttl", False):
|
|
@@ -699,7 +721,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
699
721
|
self.validate_name(new_zone=new_zone)
|
|
700
722
|
self.validate_value()
|
|
701
723
|
self.check_unique_record(new_zone=new_zone)
|
|
702
|
-
if self.
|
|
724
|
+
if self._state.adding:
|
|
703
725
|
self.check_unique_rrset_ttl()
|
|
704
726
|
|
|
705
727
|
if not self.is_active:
|
|
@@ -787,7 +809,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
787
809
|
):
|
|
788
810
|
self.full_clean()
|
|
789
811
|
|
|
790
|
-
if self.
|
|
812
|
+
if not self._state.adding and update_rrset_ttl:
|
|
791
813
|
self.update_rrset_ttl()
|
|
792
814
|
|
|
793
815
|
if self.is_ptr_record:
|
netbox_dns/models/view.py
CHANGED
|
@@ -9,6 +9,13 @@ from netbox.context import current_request
|
|
|
9
9
|
from utilities.exceptions import AbortRequest
|
|
10
10
|
|
|
11
11
|
from netbox_dns.mixins import ObjectModificationMixin
|
|
12
|
+
from netbox_dns.utilities import (
|
|
13
|
+
get_ip_addresses_by_view,
|
|
14
|
+
check_dns_records,
|
|
15
|
+
update_dns_records,
|
|
16
|
+
delete_dns_records,
|
|
17
|
+
get_query_from_filter,
|
|
18
|
+
)
|
|
12
19
|
|
|
13
20
|
|
|
14
21
|
__all__ = (
|
|
@@ -34,6 +41,11 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
34
41
|
related_name="netbox_dns_views",
|
|
35
42
|
blank=True,
|
|
36
43
|
)
|
|
44
|
+
ip_address_filter = models.JSONField(
|
|
45
|
+
verbose_name="IP Address Filter",
|
|
46
|
+
blank=True,
|
|
47
|
+
null=True,
|
|
48
|
+
)
|
|
37
49
|
tenant = models.ForeignKey(
|
|
38
50
|
to="tenancy.Tenant",
|
|
39
51
|
on_delete=models.PROTECT,
|
|
@@ -87,6 +99,21 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
87
99
|
}
|
|
88
100
|
)
|
|
89
101
|
|
|
102
|
+
if "ip_address_filter" in changed_fields and self.get_saved_value(
|
|
103
|
+
"ip_address_filter"
|
|
104
|
+
):
|
|
105
|
+
try:
|
|
106
|
+
for ip_address in get_ip_addresses_by_view(self).filter(
|
|
107
|
+
get_query_from_filter(self.ip_address_filter)
|
|
108
|
+
):
|
|
109
|
+
check_dns_records(ip_address, view=self)
|
|
110
|
+
except ValidationError as exc:
|
|
111
|
+
raise ValidationError(
|
|
112
|
+
{
|
|
113
|
+
"ip_address_filter": exc.messages,
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
|
|
90
117
|
super().clean(*args, **kwargs)
|
|
91
118
|
|
|
92
119
|
def save(self, *args, **kwargs):
|
|
@@ -106,6 +133,19 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
106
133
|
view.default_view = False
|
|
107
134
|
view.save()
|
|
108
135
|
|
|
136
|
+
if changed_fields is not None and "ip_address_filter" in changed_fields:
|
|
137
|
+
ip_addresses = get_ip_addresses_by_view(self)
|
|
138
|
+
|
|
139
|
+
for ip_address in ip_addresses.exclude(
|
|
140
|
+
get_query_from_filter(self.ip_address_filter)
|
|
141
|
+
):
|
|
142
|
+
delete_dns_records(ip_address, view=self)
|
|
143
|
+
|
|
144
|
+
for ip_address in ip_addresses.filter(
|
|
145
|
+
get_query_from_filter(self.ip_address_filter)
|
|
146
|
+
):
|
|
147
|
+
update_dns_records(ip_address, view=self)
|
|
148
|
+
|
|
109
149
|
|
|
110
150
|
@register_search
|
|
111
151
|
class ViewIndex(SearchIndex):
|
netbox_dns/models/zone.py
CHANGED
|
@@ -649,14 +649,16 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
649
649
|
}
|
|
650
650
|
)
|
|
651
651
|
|
|
652
|
-
if self.
|
|
653
|
-
|
|
652
|
+
if not self._state.adding:
|
|
653
|
+
old_soa_serial = self.get_saved_value("soa_serial")
|
|
654
|
+
old_soa_serial_auto = self.get_saved_value("soa_serial_auto")
|
|
655
|
+
|
|
654
656
|
if not self.soa_serial_auto:
|
|
655
|
-
self.check_soa_serial_increment(
|
|
656
|
-
elif not
|
|
657
|
+
self.check_soa_serial_increment(old_soa_serial, self.soa_serial)
|
|
658
|
+
elif not old_soa_serial_auto:
|
|
657
659
|
try:
|
|
658
660
|
self.check_soa_serial_increment(
|
|
659
|
-
|
|
661
|
+
old_soa_serial, self.get_auto_serial()
|
|
660
662
|
)
|
|
661
663
|
except ValidationError:
|
|
662
664
|
raise ValidationError(
|
|
@@ -665,10 +667,13 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
665
667
|
}
|
|
666
668
|
)
|
|
667
669
|
|
|
670
|
+
old_name = self.get_saved_value("name")
|
|
671
|
+
old_view_id = self.get_saved_value("view_id")
|
|
672
|
+
|
|
668
673
|
if (
|
|
669
674
|
not self.ip_addresses_checked
|
|
670
|
-
and
|
|
671
|
-
or
|
|
675
|
+
and old_name != self.name
|
|
676
|
+
or old_view_id != self.view_id
|
|
672
677
|
):
|
|
673
678
|
ip_addresses = IPAddress.objects.filter(
|
|
674
679
|
netbox_dns_records__in=self.record_set.filter(
|
|
@@ -52,7 +52,7 @@ def ipam_dnssync_ipaddress_post_clean(instance, **kwargs):
|
|
|
52
52
|
dns_name=instance.dns_name,
|
|
53
53
|
status__in=IPADDRESS_ACTIVE_STATUS,
|
|
54
54
|
)
|
|
55
|
-
if instance.
|
|
55
|
+
if not instance._state.adding:
|
|
56
56
|
duplicate_addresses = duplicate_addresses.exclude(pk=instance.pk)
|
|
57
57
|
|
|
58
58
|
if ENFORCE_UNIQUE_RECORDS and instance.status in IPADDRESS_ACTIVE_STATUS:
|
|
@@ -74,7 +74,7 @@ def ipam_dnssync_ipaddress_post_clean(instance, **kwargs):
|
|
|
74
74
|
if (request := current_request.get()) is not None:
|
|
75
75
|
cf_data = instance.custom_field_data
|
|
76
76
|
if (
|
|
77
|
-
instance.
|
|
77
|
+
not instance._state.adding
|
|
78
78
|
and any(
|
|
79
79
|
(
|
|
80
80
|
cf_data.get(cf, cf_default)
|
|
@@ -86,7 +86,7 @@ def ipam_dnssync_ipaddress_post_clean(instance, **kwargs):
|
|
|
86
86
|
)
|
|
87
87
|
and not check_record_permission()
|
|
88
88
|
) or (
|
|
89
|
-
instance.
|
|
89
|
+
instance._state.adding
|
|
90
90
|
and any(
|
|
91
91
|
(
|
|
92
92
|
cf_data.get(cf, cf_default) != cf_default
|
|
@@ -129,7 +129,7 @@ def ipam_dnssync_prefix_pre_save(instance, **kwargs):
|
|
|
129
129
|
"""
|
|
130
130
|
request = current_request.get()
|
|
131
131
|
|
|
132
|
-
if instance.
|
|
132
|
+
if instance._state.adding or not instance.netbox_dns_views.exists():
|
|
133
133
|
return
|
|
134
134
|
|
|
135
135
|
saved_prefix = Prefix.objects.prefetch_related("netbox_dns_views").get(
|
netbox_dns/tables/view.py
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
</h5>
|
|
43
43
|
<div class="card-body">
|
|
44
44
|
<table class="table table-hover attr-table">
|
|
45
|
+
{% if object.prefixes.exists %}
|
|
45
46
|
{% for prefix in object.prefixes.all %}
|
|
46
47
|
<tr>
|
|
47
48
|
<td>
|
|
@@ -56,9 +57,24 @@
|
|
|
56
57
|
{% endif %}
|
|
57
58
|
</tr>
|
|
58
59
|
{% endfor %}
|
|
60
|
+
{% else %}
|
|
61
|
+
<span class="text-muted">No prefixes assigned</span>
|
|
62
|
+
{% endif %}
|
|
59
63
|
</table>
|
|
60
64
|
</div>
|
|
61
65
|
</div>
|
|
66
|
+
<div class="card">
|
|
67
|
+
<h5 class="card-header">
|
|
68
|
+
IP Address Filters
|
|
69
|
+
</h5>
|
|
70
|
+
<div class="card-body">
|
|
71
|
+
{% if object.ip_address_filter %}
|
|
72
|
+
<pre>{{ object.ip_address_filter|json }}</pre>
|
|
73
|
+
{% else %}
|
|
74
|
+
<span class="text-muted">No filters defined</span>
|
|
75
|
+
{% endif %}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
62
78
|
{% endif %}
|
|
63
79
|
</div>
|
|
64
80
|
</div>
|
|
@@ -10,9 +10,6 @@ from django.db.models import Q
|
|
|
10
10
|
from netbox.context import current_request
|
|
11
11
|
from ipam.models import IPAddress, Prefix
|
|
12
12
|
|
|
13
|
-
from netbox_dns.models import zone as _zone
|
|
14
|
-
from netbox_dns.models import record as _record
|
|
15
|
-
from netbox_dns.models import view as _view
|
|
16
13
|
from netbox_dns.choices import RecordStatusChoices
|
|
17
14
|
|
|
18
15
|
|
|
@@ -26,6 +23,7 @@ __all__ = (
|
|
|
26
23
|
"get_ip_addresses_by_view",
|
|
27
24
|
"get_ip_addresses_by_zone",
|
|
28
25
|
"check_record_permission",
|
|
26
|
+
"get_query_from_filter",
|
|
29
27
|
)
|
|
30
28
|
|
|
31
29
|
|
|
@@ -74,6 +72,8 @@ def _match_data(ip_address, record):
|
|
|
74
72
|
|
|
75
73
|
|
|
76
74
|
def get_zones(ip_address, view=None, old_zone=None):
|
|
75
|
+
from netbox_dns.models import Zone
|
|
76
|
+
|
|
77
77
|
if view is None:
|
|
78
78
|
views = _get_assigned_views(ip_address)
|
|
79
79
|
if not views:
|
|
@@ -91,7 +91,7 @@ def get_zones(ip_address, view=None, old_zone=None):
|
|
|
91
91
|
for i in range(min_labels + 1, len(fqdn.labels) + 1)
|
|
92
92
|
]
|
|
93
93
|
|
|
94
|
-
zones =
|
|
94
|
+
zones = Zone.objects.filter(
|
|
95
95
|
view__in=views,
|
|
96
96
|
name__in=zone_name_candidates,
|
|
97
97
|
active=True,
|
|
@@ -114,28 +114,28 @@ def get_zones(ip_address, view=None, old_zone=None):
|
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
def check_dns_records(ip_address, zone=None, view=None):
|
|
117
|
+
from netbox_dns.models import Zone, Record
|
|
118
|
+
|
|
117
119
|
if ip_address.dns_name == "":
|
|
118
120
|
return
|
|
119
121
|
|
|
120
122
|
if zone is None:
|
|
121
123
|
zones = get_zones(ip_address, view=view)
|
|
122
124
|
|
|
123
|
-
if ip_address.
|
|
125
|
+
if not ip_address._state.adding:
|
|
124
126
|
for record in ip_address.netbox_dns_records.filter(zone__in=zones):
|
|
125
127
|
if not _match_data(ip_address, record):
|
|
126
|
-
record.update_from_ip_address(ip_address)
|
|
128
|
+
updated = record.update_from_ip_address(ip_address)
|
|
127
129
|
|
|
128
|
-
if
|
|
130
|
+
if updated:
|
|
129
131
|
record.clean()
|
|
130
132
|
|
|
131
|
-
zones =
|
|
132
|
-
pk__in=[zone.pk for zone in zones]
|
|
133
|
-
).exclude(
|
|
133
|
+
zones = Zone.objects.filter(pk__in=[zone.pk for zone in zones]).exclude(
|
|
134
134
|
pk__in=set(ip_address.netbox_dns_records.values_list("zone", flat=True))
|
|
135
135
|
)
|
|
136
136
|
|
|
137
137
|
for zone in zones:
|
|
138
|
-
record =
|
|
138
|
+
record = Record.create_from_ip_address(
|
|
139
139
|
ip_address,
|
|
140
140
|
zone,
|
|
141
141
|
)
|
|
@@ -143,7 +143,7 @@ def check_dns_records(ip_address, zone=None, view=None):
|
|
|
143
143
|
if record is not None:
|
|
144
144
|
record.clean()
|
|
145
145
|
|
|
146
|
-
if ip_address.
|
|
146
|
+
if ip_address._state.adding:
|
|
147
147
|
return
|
|
148
148
|
|
|
149
149
|
try:
|
|
@@ -152,21 +152,28 @@ def check_dns_records(ip_address, zone=None, view=None):
|
|
|
152
152
|
return
|
|
153
153
|
|
|
154
154
|
for record in ip_address.netbox_dns_records.filter(zone=zone):
|
|
155
|
-
record.update_from_ip_address(ip_address, new_zone)
|
|
155
|
+
updated = record.update_from_ip_address(ip_address, new_zone)
|
|
156
156
|
|
|
157
|
-
if
|
|
157
|
+
if updated:
|
|
158
158
|
record.clean(new_zone=new_zone)
|
|
159
159
|
|
|
160
160
|
|
|
161
|
-
def update_dns_records(ip_address):
|
|
161
|
+
def update_dns_records(ip_address, view=None):
|
|
162
|
+
from netbox_dns.models import Zone, Record
|
|
163
|
+
|
|
162
164
|
if ip_address.dns_name == "":
|
|
163
165
|
delete_dns_records(ip_address)
|
|
164
166
|
return
|
|
165
167
|
|
|
166
|
-
zones = get_zones(ip_address)
|
|
168
|
+
zones = get_zones(ip_address, view=view)
|
|
167
169
|
|
|
168
|
-
if ip_address.
|
|
169
|
-
|
|
170
|
+
if not ip_address._state.adding:
|
|
171
|
+
if view is None:
|
|
172
|
+
address_records = ip_address.netbox_dns_records.all()
|
|
173
|
+
else:
|
|
174
|
+
address_records = ip_address.netbox_dns_records.filter(zone__view=view)
|
|
175
|
+
|
|
176
|
+
for record in address_records:
|
|
170
177
|
if record.zone not in zones or ip_address.custom_field_data.get(
|
|
171
178
|
"ipaddress_dns_disabled"
|
|
172
179
|
):
|
|
@@ -175,19 +182,21 @@ def update_dns_records(ip_address):
|
|
|
175
182
|
|
|
176
183
|
record.update_fqdn()
|
|
177
184
|
if not _match_data(ip_address, record):
|
|
178
|
-
record.update_from_ip_address(ip_address)
|
|
185
|
+
updated, deleted = record.update_from_ip_address(ip_address)
|
|
179
186
|
|
|
180
|
-
if
|
|
187
|
+
if deleted:
|
|
188
|
+
record.delete()
|
|
189
|
+
elif updated:
|
|
181
190
|
record.save()
|
|
182
191
|
|
|
183
|
-
zones =
|
|
192
|
+
zones = Zone.objects.filter(pk__in=[zone.pk for zone in zones]).exclude(
|
|
184
193
|
pk__in=set(
|
|
185
194
|
ip_address.netbox_dns_records.all().values_list("zone", flat=True)
|
|
186
195
|
)
|
|
187
196
|
)
|
|
188
197
|
|
|
189
198
|
for zone in zones:
|
|
190
|
-
record =
|
|
199
|
+
record = Record.create_from_ip_address(
|
|
191
200
|
ip_address,
|
|
192
201
|
zone,
|
|
193
202
|
)
|
|
@@ -196,19 +205,27 @@ def update_dns_records(ip_address):
|
|
|
196
205
|
record.save()
|
|
197
206
|
|
|
198
207
|
|
|
199
|
-
def delete_dns_records(ip_address):
|
|
200
|
-
|
|
208
|
+
def delete_dns_records(ip_address, view=None):
|
|
209
|
+
|
|
210
|
+
if view is None:
|
|
211
|
+
address_records = ip_address.netbox_dns_records.all()
|
|
212
|
+
else:
|
|
213
|
+
address_records = ip_address.netbox_dns_records.filter(zone__view=view)
|
|
214
|
+
|
|
215
|
+
for record in address_records:
|
|
201
216
|
record.delete()
|
|
202
217
|
|
|
203
218
|
|
|
204
219
|
def get_views_by_prefix(prefix):
|
|
220
|
+
from netbox_dns.models import View
|
|
221
|
+
|
|
205
222
|
if (views := prefix.netbox_dns_views.all()).exists():
|
|
206
223
|
return views
|
|
207
224
|
|
|
208
225
|
if (parent := prefix.get_parents().filter(netbox_dns_views__isnull=False)).exists():
|
|
209
226
|
return parent.last().netbox_dns_views.all()
|
|
210
227
|
|
|
211
|
-
return
|
|
228
|
+
return View.objects.none()
|
|
212
229
|
|
|
213
230
|
|
|
214
231
|
def get_ip_addresses_by_prefix(prefix, check_view=True):
|
|
@@ -293,3 +310,18 @@ def check_record_permission(add=True, change=True, delete=True):
|
|
|
293
310
|
if check
|
|
294
311
|
)
|
|
295
312
|
)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def get_query_from_filter(ip_address_filter):
|
|
316
|
+
query = Q()
|
|
317
|
+
|
|
318
|
+
if not isinstance(ip_address_filter, list):
|
|
319
|
+
ip_address_filter = [ip_address_filter]
|
|
320
|
+
|
|
321
|
+
for condition in ip_address_filter:
|
|
322
|
+
if condition:
|
|
323
|
+
query |= Q(**condition)
|
|
324
|
+
else:
|
|
325
|
+
return Q()
|
|
326
|
+
|
|
327
|
+
return query
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
netbox_dns/__init__.py,sha256=
|
|
1
|
+
netbox_dns/__init__.py,sha256=6S7LL8UGPVpKSir7BCdth9yKtWtyRVKikVjQY58W62E,1956
|
|
2
2
|
netbox_dns/apps.py,sha256=JCW5eS-AQBUubDJve1DjP-IRFKTFGQh1NLGWzJpC5MI,151
|
|
3
3
|
netbox_dns/navigation.py,sha256=YAEfmqoNRSXLSf-n3HLImDXbAfzcRdCh57BVnofmWPQ,6046
|
|
4
4
|
netbox_dns/template_content.py,sha256=YzE-ZJlERhFybrUKJrmNwHk8_8RPNexkV66x62Sbzic,3718
|
|
@@ -13,7 +13,7 @@ netbox_dns/api/serializers_/record.py,sha256=62924HonaKflFXkTgFft_624BKEikAMkak1
|
|
|
13
13
|
netbox_dns/api/serializers_/record_template.py,sha256=qh-g-_f6M-eU4GzN-l0nPxiNBpZyYBgib26HwfOMtUc,1466
|
|
14
14
|
netbox_dns/api/serializers_/registrar.py,sha256=xLIaeBJ5ckV1Jf-uyCTFcvsLlsRMlpDtIg6q79vXZic,842
|
|
15
15
|
netbox_dns/api/serializers_/registration_contact.py,sha256=3IGWW5xB9XEBGApCGZCZIxpCmy1Y5jQUbA4GzmtaCik,1024
|
|
16
|
-
netbox_dns/api/serializers_/view.py,sha256=
|
|
16
|
+
netbox_dns/api/serializers_/view.py,sha256=_0fqdhvHU0scqc8ZNDSCcxaQDY-Auxu0Q9LLzlnrGqc,1756
|
|
17
17
|
netbox_dns/api/serializers_/zone.py,sha256=vQMKyC1Pcnvp7OjRnSZt-cMP5iae9HLuMts6_JyxrG4,4935
|
|
18
18
|
netbox_dns/api/serializers_/zone_template.py,sha256=itwcdMe8NxMbH95yXBJTQkzzMOWzOvzTOOHJWKfEFgg,3782
|
|
19
19
|
netbox_dns/choices/__init__.py,sha256=jOVs2VGV5SVADRlqVnrFeAy26i8BIeEAbGpiX7K8bL8,42
|
|
@@ -39,13 +39,13 @@ netbox_dns/forms/record.py,sha256=svBVAFy-egDEPLcRWkxNi_1bkabKmWgJ87pmdNt6dh4,71
|
|
|
39
39
|
netbox_dns/forms/record_template.py,sha256=Q77p9sExJ8Xbl-Co2Px2R0At5O3naQJwx4pnino6i2o,5573
|
|
40
40
|
netbox_dns/forms/registrar.py,sha256=FMnvrcq62R3wNp_2ZUEk3v_PIav0KrWPATaJ7_9KFAo,3758
|
|
41
41
|
netbox_dns/forms/registration_contact.py,sha256=WHpIRnwPD7nIDKi0-zRdv7tLUN2t_n3rmt_mZrqjfEk,5524
|
|
42
|
-
netbox_dns/forms/view.py,sha256=
|
|
42
|
+
netbox_dns/forms/view.py,sha256=x0Q22BlkQL60XEyRcrdgl6cTI3plzB4u8pqmcwZiJ2c,9808
|
|
43
43
|
netbox_dns/forms/zone.py,sha256=6NI3uiI2bXIhzPM7CTxR4pbv198xmU-QHEizy16Qb-E,23601
|
|
44
44
|
netbox_dns/forms/zone_template.py,sha256=D0JgQE03uQ_vR6zHkS78a5PzUziNSu1ho_mk61JTRo4,8317
|
|
45
45
|
netbox_dns/graphql/__init__.py,sha256=jghYD6uOSAis6YyLbtI3YJGZfwPw1uL2FBRsHs1EhNk,514
|
|
46
46
|
netbox_dns/graphql/filters.py,sha256=fHCjFIwbPBJJMk2W7HI8LhrfFhCtQtCM9IE8ZMgVafc,1766
|
|
47
|
-
netbox_dns/graphql/schema.py,sha256=
|
|
48
|
-
netbox_dns/graphql/types.py,sha256=
|
|
47
|
+
netbox_dns/graphql/schema.py,sha256=q9DQ_hfRB0e6Znq4-IS6UEeTOfMkZmrWkwxcAql1uOA,2270
|
|
48
|
+
netbox_dns/graphql/types.py,sha256=24m-qblJoauYzu5n1UDsw_IUvr_r3PRGO-VDt9aKQ3o,6686
|
|
49
49
|
netbox_dns/management/commands/cleanup_database.py,sha256=kfnyybudwKGigjJmrOwafPWSUasZr9jQsxN4eWAgMvY,5969
|
|
50
50
|
netbox_dns/management/commands/cleanup_rrset_ttl.py,sha256=UFRURLBcFeGHUS2lrYFv7UWIebjI72aG1EUQJt0XsXw,2046
|
|
51
51
|
netbox_dns/management/commands/rebuild_dnssync.py,sha256=56YGEsAO_NYCXRmuL9Ju_Ni3FLtMD0MO4ObZAAPefLk,617
|
|
@@ -61,6 +61,7 @@ netbox_dns/migrations/0006_templating.py,sha256=7MOZ2bLwkjK1BQCBPBaFWJ-mS_JNrok1
|
|
|
61
61
|
netbox_dns/migrations/0007_alter_ordering_options.py,sha256=IDGgxEWOaSs9_WKJK1C_5_6M1uJtYscn3Vco0UHAol8,639
|
|
62
62
|
netbox_dns/migrations/0008_view_prefixes.py,sha256=LInzrOXTflGd2WUmyXZtjEegg7S_KBNvrbdo3jE28fE,472
|
|
63
63
|
netbox_dns/migrations/0009_rename_contact_registrationcontact.py,sha256=-8IknnaIZxoBaf5uSQj8rVe0SRvYsuhcJ0_jzRh4EUk,1314
|
|
64
|
+
netbox_dns/migrations/0010_view_ip_address_filter.py,sha256=uARQADJB7u1vpx0TBlOfGTkqMCF4xZclMhITESHm-ok,420
|
|
64
65
|
netbox_dns/migrations/0020_netbox_3_4.py,sha256=UMcHdn8ZAuQjUaM_3rEGpktYrM0TuvhccD7Jt7WQnPs,1271
|
|
65
66
|
netbox_dns/migrations/0021_record_ip_address.py,sha256=EqdhWXmq7aiK4X79xTRUZng3zFncCl-8JoO65HqlJKw,3244
|
|
66
67
|
netbox_dns/migrations/0022_search.py,sha256=KW1ffEZ4-0dppGQ_KD1EN7iw8eQJOnDco-xfJFRZqKQ,172
|
|
@@ -73,18 +74,18 @@ netbox_dns/migrations/0028_rfc2317_fields.py,sha256=D8r43xxBjYXiL6ycmX8RY5_WG7tR
|
|
|
73
74
|
netbox_dns/migrations/0029_record_fqdn.py,sha256=UAAU38ekKQyiYDOJlcrz6Qbk4bqZfSHZyAHUZFFQrOw,808
|
|
74
75
|
netbox_dns/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
76
|
netbox_dns/mixins/__init__.py,sha256=LxTEfpod_RHCyMtnzDljv0_dwqp2z3Q6tqbXW8LTGD8,35
|
|
76
|
-
netbox_dns/mixins/object_modification.py,sha256=
|
|
77
|
+
netbox_dns/mixins/object_modification.py,sha256=biLbHOkayEdKPu-wxuYu7ZIXhB3cfv9k07asrQCtFb0,1658
|
|
77
78
|
netbox_dns/models/__init__.py,sha256=5Ns9RaemTe5L0L3c6a38RxembWhV-sX9cqfjl05aPQw,313
|
|
78
79
|
netbox_dns/models/nameserver.py,sha256=gvQRcTOVHRiX_rcBZfjNV6rTRKNJtA5HxgggYEgITPA,3296
|
|
79
|
-
netbox_dns/models/record.py,sha256=
|
|
80
|
+
netbox_dns/models/record.py,sha256=RDdGAZVKR--ix-r04bV32nMhKJnG_aUaFgMyt-SbRHo,27222
|
|
80
81
|
netbox_dns/models/record_template.py,sha256=pyzrtk-VFEHf9hrWTW6pwPKo2AH5cEKR0XI4ZG9nVHk,4753
|
|
81
82
|
netbox_dns/models/registrar.py,sha256=zCSVa6NSN9sRJzvvuSUNK4LcHBbe0OvEiTbIcrrdk9k,1671
|
|
82
83
|
netbox_dns/models/registration_contact.py,sha256=v5BxTtGPrR22TyqIQkgaSH26ozhzIVrkU-PuezHki-g,3217
|
|
83
|
-
netbox_dns/models/view.py,sha256=
|
|
84
|
-
netbox_dns/models/zone.py,sha256=
|
|
84
|
+
netbox_dns/models/view.py,sha256=skVcXB1krvSn1-gmvnNnj5o76AsTYPinaIkSXNbBOAg,4396
|
|
85
|
+
netbox_dns/models/zone.py,sha256=Mo63r1OLbbya4LGZbomIqjvibwojEwqEdV0I7umnK48,29780
|
|
85
86
|
netbox_dns/models/zone_template.py,sha256=LvNqUi_Ucj3zHb9b778kFM2EZ1s9aXp980Et5g7lvTY,3889
|
|
86
87
|
netbox_dns/signals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
87
|
-
netbox_dns/signals/ipam_dnssync.py,sha256=
|
|
88
|
+
netbox_dns/signals/ipam_dnssync.py,sha256=GXsKk2c9KlNb8b6Sb58sPZ-nDFKLkL0cN7TEgc08GGU,7976
|
|
88
89
|
netbox_dns/tables/__init__.py,sha256=axENVF9vX9BtDKCNxrapRjye1NnygUg9BS0BBj6a0io,209
|
|
89
90
|
netbox_dns/tables/ipam_dnssync.py,sha256=7gxf6nXn2zgpnpCr5E5qebXv7QCzrgIqfSzyka53USU,272
|
|
90
91
|
netbox_dns/tables/nameserver.py,sha256=GGi8x8QXbrFoFjxueL1zd5L-hDZwXGs1PcLZ2DyI4JI,652
|
|
@@ -92,7 +93,7 @@ netbox_dns/tables/record.py,sha256=QTK-AQMwEG7pjR3fkFo6E45FzGsdCKLpDZLzudRiJRQ,3
|
|
|
92
93
|
netbox_dns/tables/record_template.py,sha256=CcXvyGycwp16ZwQFdmdt5W5Tlt__i1sBi3mixVvht3E,1763
|
|
93
94
|
netbox_dns/tables/registrar.py,sha256=Vtl3RKjhWzUDv4wAfjbNV1prZHf6SyGYmSS0XKccI9g,640
|
|
94
95
|
netbox_dns/tables/registration_contact.py,sha256=xUszp7_vbZ79KHewBZkSyxNcWE3W3o8O6Pp0N-8VDXg,838
|
|
95
|
-
netbox_dns/tables/view.py,sha256=
|
|
96
|
+
netbox_dns/tables/view.py,sha256=u2XP66nrv1cmeBxQL9VM2c1wtoM_quZFB0B8O5-3IEE,1058
|
|
96
97
|
netbox_dns/tables/zone.py,sha256=bVi4sLFdw61kfIiRJnoJOtgkVGGlTZcogw-cAzFtAEQ,1507
|
|
97
98
|
netbox_dns/tables/zone_template.py,sha256=gezSSpbNkiHnstNq470OsTmkl13foFXTGx-NH8W87Hw,1204
|
|
98
99
|
netbox_dns/templates/netbox_dns/nameserver.html,sha256=DpTdetQVV_jKThDbi62LvbhiCay-1QxR-yiJEiPFm4w,1554
|
|
@@ -100,7 +101,7 @@ netbox_dns/templates/netbox_dns/record.html,sha256=o3z_D6Fqqn7nx1IwPXKQ75ZaPhU6k
|
|
|
100
101
|
netbox_dns/templates/netbox_dns/recordtemplate.html,sha256=9tkXtKqa5p3LdOU9REm99WSFwGJaH8OczpIqXZuXMcg,3099
|
|
101
102
|
netbox_dns/templates/netbox_dns/registrar.html,sha256=O5veGmW59Pf5yN25ihPLvRIkA2P7xmSGv0G3NrRG8vI,2152
|
|
102
103
|
netbox_dns/templates/netbox_dns/registrationcontact.html,sha256=4I3I7G38bIOVifoqgGMyPTAhD0UaD8ZCnXK7Fu9K9VQ,2868
|
|
103
|
-
netbox_dns/templates/netbox_dns/view.html,sha256=
|
|
104
|
+
netbox_dns/templates/netbox_dns/view.html,sha256=UmUTudA8CsTIInEXaM4ocRDRPlcZ4pTQfcolfPe_jIQ,3165
|
|
104
105
|
netbox_dns/templates/netbox_dns/zone.html,sha256=zPi1sLFnya-ytx8-Pcf_ujc1sKllCRuz48x2E-S1HSo,6285
|
|
105
106
|
netbox_dns/templates/netbox_dns/zonetemplate.html,sha256=qjUWqrg4uDaIFt9-g0OBxTi86i_ctf2Ps4qHh11djQE,3081
|
|
106
107
|
netbox_dns/templates/netbox_dns/record/managed.html,sha256=G6LPG1koUGuzUiwYdv1okdVa4sKaofiQegDBnsFL0kA,89
|
|
@@ -126,7 +127,7 @@ netbox_dns/urls/zone.py,sha256=EzZ_U5v9NfWB5TVAc0i35EI-SVyXl6KrI844sMT0x5Q,937
|
|
|
126
127
|
netbox_dns/urls/zone_template.py,sha256=nGrIaincQxCabUsLJL9JODoeTToMRSPllm7kuiPzeII,1378
|
|
127
128
|
netbox_dns/utilities/__init__.py,sha256=mmR0JdH1DJVhUKesnO3CZFj0Rw_wrsMPoYTpOOKHl9I,55
|
|
128
129
|
netbox_dns/utilities/conversions.py,sha256=NS37SoMqXc13wNWRkKnLfyQbVi6QKD33fu5ovTKRo74,1979
|
|
129
|
-
netbox_dns/utilities/ipam_dnssync.py,sha256=
|
|
130
|
+
netbox_dns/utilities/ipam_dnssync.py,sha256=b4up7GXuAc4ba-cHmS56vWFPEmYVSsQG_Dd-3pHndrI,9379
|
|
130
131
|
netbox_dns/validators/__init__.py,sha256=Mr8TvmcJTa8Pubj8TzbFBKfbHhEmGcr5JdQvczEJ39A,72
|
|
131
132
|
netbox_dns/validators/dns_name.py,sha256=4JojiP6pb1Z1m_PmDv4g65Ckhg5rQkVqm8JAwHW28nA,3432
|
|
132
133
|
netbox_dns/validators/dns_value.py,sha256=y2Zga4hmywqDrTBXcMC-sWaFbw4eoY8pySq7cWnMP8Y,2822
|
|
@@ -140,8 +141,8 @@ netbox_dns/views/registration_contact.py,sha256=Yg4gTldQQPfAFgjD7vultw3OmcovWZti
|
|
|
140
141
|
netbox_dns/views/view.py,sha256=-qdpEVrAI_fquZa-_jW2FvNXmCt3yRHIrkfgKKi01hc,2899
|
|
141
142
|
netbox_dns/views/zone.py,sha256=Na286tp_XcnT-4FIgXsvh1wPByir0RtBil0B2JhfuZE,5495
|
|
142
143
|
netbox_dns/views/zone_template.py,sha256=UaPEReBFoJP1k7MC8jS-iT3KQtJqSFu67jjCRiTCH4c,2118
|
|
143
|
-
netbox_plugin_dns-1.1.
|
|
144
|
-
netbox_plugin_dns-1.1.
|
|
145
|
-
netbox_plugin_dns-1.1.
|
|
146
|
-
netbox_plugin_dns-1.1.
|
|
147
|
-
netbox_plugin_dns-1.1.
|
|
144
|
+
netbox_plugin_dns-1.1.2.dist-info/LICENSE,sha256=I3tDu11bZfhFm3EkV4zOD5TmWgLjnUNLEFwrdjniZYs,1112
|
|
145
|
+
netbox_plugin_dns-1.1.2.dist-info/METADATA,sha256=cSzLVUftq3LnCskiVNmYcpuHYqsNUrpzUNp0lIOQ50k,7129
|
|
146
|
+
netbox_plugin_dns-1.1.2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
147
|
+
netbox_plugin_dns-1.1.2.dist-info/top_level.txt,sha256=sA1Rwl1mRKvMC6XHe2ylZ1GF-Q1NGd08XedK9Y4xZc4,11
|
|
148
|
+
netbox_plugin_dns-1.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|