netbox-plugin-dns 1.1.0b6__py3-none-any.whl → 1.1.1__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.

Files changed (79) hide show
  1. netbox_dns/__init__.py +1 -1
  2. netbox_dns/api/nested_serializers.py +17 -16
  3. netbox_dns/api/serializers.py +1 -1
  4. netbox_dns/api/serializers_/record.py +1 -0
  5. netbox_dns/api/serializers_/{contact.py → registration_contact.py} +5 -5
  6. netbox_dns/api/serializers_/zone.py +5 -5
  7. netbox_dns/api/serializers_/zone_template.py +5 -5
  8. netbox_dns/api/urls.py +2 -2
  9. netbox_dns/api/views.py +7 -35
  10. netbox_dns/filtersets/__init__.py +1 -1
  11. netbox_dns/filtersets/nameserver.py +0 -0
  12. netbox_dns/filtersets/record.py +0 -0
  13. netbox_dns/filtersets/record_template.py +0 -0
  14. netbox_dns/filtersets/{contact.py → registration_contact.py} +4 -4
  15. netbox_dns/filtersets/zone.py +15 -15
  16. netbox_dns/filtersets/zone_template.py +15 -15
  17. netbox_dns/forms/__init__.py +1 -1
  18. netbox_dns/forms/nameserver.py +0 -0
  19. netbox_dns/forms/record.py +0 -0
  20. netbox_dns/forms/record_template.py +0 -0
  21. netbox_dns/forms/{contact.py → registration_contact.py} +16 -16
  22. netbox_dns/forms/zone.py +13 -13
  23. netbox_dns/forms/zone_template.py +13 -13
  24. netbox_dns/graphql/__init__.py +2 -2
  25. netbox_dns/graphql/filters.py +5 -5
  26. netbox_dns/graphql/schema.py +24 -44
  27. netbox_dns/graphql/types.py +38 -12
  28. netbox_dns/management/commands/rebuild_dnssync.py +18 -0
  29. netbox_dns/migrations/0007_alter_ordering_options.py +25 -0
  30. netbox_dns/migrations/{0007_view_prefixes.py → 0008_view_prefixes.py} +1 -1
  31. netbox_dns/migrations/0009_rename_contact_registrationcontact.py +36 -0
  32. netbox_dns/models/__init__.py +1 -1
  33. netbox_dns/models/nameserver.py +8 -3
  34. netbox_dns/models/record.py +42 -20
  35. netbox_dns/models/record_template.py +4 -1
  36. netbox_dns/models/registrar.py +7 -1
  37. netbox_dns/models/{contact.py → registration_contact.py} +15 -9
  38. netbox_dns/models/view.py +9 -2
  39. netbox_dns/models/zone.py +48 -30
  40. netbox_dns/models/zone_template.py +12 -9
  41. netbox_dns/navigation.py +7 -7
  42. netbox_dns/signals/ipam_dnssync.py +6 -2
  43. netbox_dns/tables/__init__.py +1 -1
  44. netbox_dns/tables/nameserver.py +1 -7
  45. netbox_dns/tables/record.py +10 -37
  46. netbox_dns/tables/record_template.py +0 -17
  47. netbox_dns/tables/registrar.py +0 -2
  48. netbox_dns/tables/{contact.py → registration_contact.py} +5 -6
  49. netbox_dns/tables/view.py +1 -8
  50. netbox_dns/tables/zone.py +0 -15
  51. netbox_dns/tables/zone_template.py +2 -16
  52. netbox_dns/templates/netbox_dns/{contact.html → registrationcontact.html} +1 -1
  53. netbox_dns/urls/__init__.py +2 -2
  54. netbox_dns/urls/nameserver.py +14 -38
  55. netbox_dns/urls/record.py +7 -19
  56. netbox_dns/urls/record_template.py +18 -27
  57. netbox_dns/urls/registrar.py +11 -35
  58. netbox_dns/urls/registration_contact.py +60 -0
  59. netbox_dns/urls/view.py +8 -22
  60. netbox_dns/urls/zone.py +8 -46
  61. netbox_dns/urls/zone_template.py +16 -26
  62. netbox_dns/utilities/ipam_dnssync.py +26 -24
  63. netbox_dns/validators/dns_name.py +9 -0
  64. netbox_dns/views/__init__.py +1 -1
  65. netbox_dns/views/nameserver.py +7 -3
  66. netbox_dns/views/record.py +12 -7
  67. netbox_dns/views/record_template.py +1 -1
  68. netbox_dns/views/registrar.py +0 -1
  69. netbox_dns/views/registration_contact.py +94 -0
  70. netbox_dns/views/view.py +6 -1
  71. netbox_dns/views/zone.py +7 -6
  72. netbox_dns/views/zone_template.py +2 -2
  73. {netbox_plugin_dns-1.1.0b6.dist-info → netbox_plugin_dns-1.1.1.dist-info}/METADATA +14 -14
  74. {netbox_plugin_dns-1.1.0b6.dist-info → netbox_plugin_dns-1.1.1.dist-info}/RECORD +78 -74
  75. {netbox_plugin_dns-1.1.0b6.dist-info → netbox_plugin_dns-1.1.1.dist-info}/WHEEL +2 -1
  76. netbox_plugin_dns-1.1.1.dist-info/top_level.txt +1 -0
  77. netbox_dns/urls/contact.py +0 -51
  78. netbox_dns/views/contact.py +0 -95
  79. {netbox_plugin_dns-1.1.0b6.dist-info → netbox_plugin_dns-1.1.1.dist-info}/LICENSE +0 -0
netbox_dns/urls/zone.py CHANGED
@@ -1,63 +1,25 @@
1
- from django.urls import path
1
+ from django.urls import include, path
2
2
 
3
- from netbox.views.generic import ObjectChangeLogView, ObjectJournalView
3
+ from utilities.urls import get_model_urls
4
4
 
5
- from netbox_dns.models import Zone
6
5
  from netbox_dns.views import (
7
- ZoneListView,
8
6
  ZoneView,
9
- ZoneDeleteView,
7
+ ZoneListView,
10
8
  ZoneEditView,
9
+ ZoneDeleteView,
11
10
  ZoneBulkImportView,
12
11
  ZoneBulkEditView,
13
12
  ZoneBulkDeleteView,
14
- ZoneRecordListView,
15
- ZoneManagedRecordListView,
16
- ZoneRegistrationView,
17
- ZoneRFC2317ChildZoneListView,
18
- ZoneChildZoneListView,
19
13
  )
20
14
 
21
15
  zone_urlpatterns = [
16
+ path("zones/<int:pk>/", ZoneView.as_view(), name="zone"),
22
17
  path("zones/", ZoneListView.as_view(), name="zone_list"),
23
18
  path("zones/add/", ZoneEditView.as_view(), name="zone_add"),
19
+ path("zones/<int:pk>/edit/", ZoneEditView.as_view(), name="zone_edit"),
20
+ path("zones/<int:pk>/delete/", ZoneDeleteView.as_view(), name="zone_delete"),
24
21
  path("zones/import/", ZoneBulkImportView.as_view(), name="zone_import"),
25
22
  path("zones/edit/", ZoneBulkEditView.as_view(), name="zone_bulk_edit"),
26
23
  path("zones/delete/", ZoneBulkDeleteView.as_view(), name="zone_bulk_delete"),
27
- path("zones/<int:pk>/", ZoneView.as_view(), name="zone"),
28
- path("zones/<int:pk>/delete/", ZoneDeleteView.as_view(), name="zone_delete"),
29
- path("zones/<int:pk>/edit/", ZoneEditView.as_view(), name="zone_edit"),
30
- path("zones/<int:pk>/records/", ZoneRecordListView.as_view(), name="zone_records"),
31
- path(
32
- "zones/<int:pk>/managedrecords/",
33
- ZoneManagedRecordListView.as_view(),
34
- name="zone_managed_records",
35
- ),
36
- path(
37
- "zones/<int:pk>/rfc2317childzones/",
38
- ZoneRFC2317ChildZoneListView.as_view(),
39
- name="zone_rfc2317_child_zones",
40
- ),
41
- path(
42
- "zones/<int:pk>/childzones/",
43
- ZoneChildZoneListView.as_view(),
44
- name="zone_child_zones",
45
- ),
46
- path(
47
- "zones/<int:pk>/registration/",
48
- ZoneRegistrationView.as_view(),
49
- name="zone_registration",
50
- ),
51
- path(
52
- "zones/<int:pk>/journal/",
53
- ObjectJournalView.as_view(),
54
- name="zone_journal",
55
- kwargs={"model": Zone},
56
- ),
57
- path(
58
- "zones/<int:pk>/changelog/",
59
- ObjectChangeLogView.as_view(),
60
- name="zone_changelog",
61
- kwargs={"model": Zone},
62
- ),
24
+ path("zones/<int:pk>/", include(get_model_urls("netbox_dns", "zone"))),
63
25
  ]
@@ -1,21 +1,31 @@
1
- from django.urls import path
1
+ from django.urls import include, path
2
2
 
3
- from netbox.views.generic import ObjectChangeLogView, ObjectJournalView
3
+ from utilities.urls import get_model_urls
4
4
 
5
- from netbox_dns.models import ZoneTemplate
6
5
  from netbox_dns.views import (
7
- ZoneTemplateListView,
8
6
  ZoneTemplateView,
9
- ZoneTemplateDeleteView,
7
+ ZoneTemplateListView,
10
8
  ZoneTemplateEditView,
9
+ ZoneTemplateDeleteView,
11
10
  ZoneTemplateBulkImportView,
12
11
  ZoneTemplateBulkEditView,
13
12
  ZoneTemplateBulkDeleteView,
14
13
  )
15
14
 
16
15
  zonetemplate_urlpatterns = [
16
+ path("zonetemplates/<int:pk>/", ZoneTemplateView.as_view(), name="zonetemplate"),
17
17
  path("zonetemplates/", ZoneTemplateListView.as_view(), name="zonetemplate_list"),
18
18
  path("zonetemplates/add/", ZoneTemplateEditView.as_view(), name="zonetemplate_add"),
19
+ path(
20
+ "zonetemplates/<int:pk>/edit/",
21
+ ZoneTemplateEditView.as_view(),
22
+ name="zonetemplate_edit",
23
+ ),
24
+ path(
25
+ "zonetemplates/<int:pk>/delete/",
26
+ ZoneTemplateDeleteView.as_view(),
27
+ name="zonetemplate_delete",
28
+ ),
19
29
  path(
20
30
  "zonetemplates/import/",
21
31
  ZoneTemplateBulkImportView.as_view(),
@@ -31,27 +41,7 @@ zonetemplate_urlpatterns = [
31
41
  ZoneTemplateBulkDeleteView.as_view(),
32
42
  name="zonetemplate_bulk_delete",
33
43
  ),
34
- path("zonetemplates/<int:pk>/", ZoneTemplateView.as_view(), name="zonetemplate"),
35
- path(
36
- "zonetemplates/<int:pk>/delete/",
37
- ZoneTemplateDeleteView.as_view(),
38
- name="zonetemplate_delete",
39
- ),
40
- path(
41
- "zonetemplates/<int:pk>/edit/",
42
- ZoneTemplateEditView.as_view(),
43
- name="zonetemplate_edit",
44
- ),
45
- path(
46
- "zonetemplates/<int:pk>/journal/",
47
- ObjectJournalView.as_view(),
48
- name="zonetemplate_journal",
49
- kwargs={"model": ZoneTemplate},
50
- ),
51
44
  path(
52
- "zonetemplates/<int:pk>/changelog/",
53
- ObjectChangeLogView.as_view(),
54
- name="zonetemplate_changelog",
55
- kwargs={"model": ZoneTemplate},
45
+ "zonetemplates/<int:pk>/", include(get_model_urls("netbox_dns", "zonetemplate"))
56
46
  ),
57
47
  ]
@@ -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)
@@ -74,7 +88,7 @@ def get_zones(ip_address, view=None, old_zone=None):
74
88
  fqdn = dns_name.from_text(ip_address.dns_name)
75
89
  zone_name_candidates = [
76
90
  fqdn.split(i)[1].to_text().rstrip(".")
77
- for i in range(min_labels + 1, len(fqdn.labels))
91
+ for i in range(min_labels + 1, len(fqdn.labels) + 1)
78
92
  ]
79
93
 
80
94
  zones = _zone.Zone.objects.filter(
@@ -108,11 +122,7 @@ def check_dns_records(ip_address, zone=None, view=None):
108
122
 
109
123
  if ip_address.pk is not None:
110
124
  for record in ip_address.netbox_dns_records.filter(zone__in=zones):
111
- if (
112
- record.fqdn != ip_address.dns_name
113
- or record.value != ip_address.address.ip
114
- or record.status != _get_record_status(ip_address)
115
- ):
125
+ if not _match_data(ip_address, record):
116
126
  record.update_from_ip_address(ip_address)
117
127
 
118
128
  if record is not None:
@@ -121,9 +131,7 @@ def check_dns_records(ip_address, zone=None, view=None):
121
131
  zones = _zone.Zone.objects.filter(
122
132
  pk__in=[zone.pk for zone in zones]
123
133
  ).exclude(
124
- pk__in=set(
125
- ip_address.netbox_dns_records.all().values_list("zone", flat=True)
126
- )
134
+ pk__in=set(ip_address.netbox_dns_records.values_list("zone", flat=True))
127
135
  )
128
136
 
129
137
  for zone in zones:
@@ -159,22 +167,14 @@ def update_dns_records(ip_address):
159
167
 
160
168
  if ip_address.pk is not None:
161
169
  for record in ip_address.netbox_dns_records.all():
162
- 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
+ ):
163
173
  record.delete()
164
174
  continue
165
175
 
166
- cf_disable_ptr = ip_address.custom_field_data.get(
167
- "ipaddress_dns_record_disable_ptr"
168
- )
169
-
170
- if (
171
- record.fqdn.rstrip(".") != ip_address.dns_name.rstrip(".")
172
- or record.value != str(ip_address.address.ip)
173
- or record.status != _get_record_status(ip_address)
174
- or record.ttl
175
- != ip_address.custom_field_data.get("ipaddress_dns_record_ttl")
176
- or (cf_disable_ptr is not None and record.disable_ptr != cf_disable_ptr)
177
- ):
176
+ record.update_fqdn()
177
+ if not _match_data(ip_address, record):
178
178
  record.update_from_ip_address(ip_address)
179
179
 
180
180
  if record is not None:
@@ -271,9 +271,11 @@ def get_ip_addresses_by_zone(zone):
271
271
  are the IPAddress objects in prefixes assigned to the same view, if the
272
272
  'dns_name' attribute of the IPAddress object ends in the zone's name.
273
273
  """
274
- 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
+ )
275
277
 
276
- return queryset.filter(dns_name__regex=rf"\.{re.escape(zone.name)}\.?$")
278
+ return queryset
277
279
 
278
280
 
279
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
  ):
@@ -2,7 +2,7 @@ from .view import *
2
2
  from .zone import *
3
3
  from .nameserver import *
4
4
  from .record import *
5
- from .contact import *
5
+ from .registration_contact import *
6
6
  from .registrar import *
7
7
  from .zone_template import *
8
8
  from .record_template import *
@@ -2,6 +2,7 @@ from dns import name as dns_name
2
2
 
3
3
  from netbox.views import generic
4
4
  from utilities.views import ViewTab, register_model_view
5
+ from tenancy.views import ObjectContactsView
5
6
 
6
7
  from netbox_dns.filtersets import NameServerFilterSet, ZoneFilterSet
7
8
  from netbox_dns.forms import (
@@ -15,15 +16,13 @@ from netbox_dns.tables import NameServerTable, ZoneTable
15
16
 
16
17
 
17
18
  __all__ = (
18
- "NameServerListView",
19
19
  "NameServerView",
20
+ "NameServerListView",
20
21
  "NameServerEditView",
21
22
  "NameServerDeleteView",
22
23
  "NameServerBulkEditView",
23
24
  "NameServerBulkImportView",
24
25
  "NameServerBulkDeleteView",
25
- "NameServerZoneListView",
26
- "NameServerSOAZoneListView",
27
26
  )
28
27
 
29
28
 
@@ -77,6 +76,11 @@ class NameServerBulkDeleteView(generic.BulkDeleteView):
77
76
  table = NameServerTable
78
77
 
79
78
 
79
+ @register_model_view(NameServer, "contacts")
80
+ class NameServerContactsView(ObjectContactsView):
81
+ queryset = NameServer.objects.all()
82
+
83
+
80
84
  @register_model_view(NameServer, "zones")
81
85
  class NameServerZoneListView(generic.ObjectChildrenView):
82
86
  queryset = NameServer.objects.all().prefetch_related("zones")
@@ -1,10 +1,8 @@
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
4
+ from utilities.views import register_model_view
5
+ from tenancy.views import ObjectContactsView
8
6
 
9
7
  from netbox_dns.filtersets import RecordFilterSet
10
8
  from netbox_dns.forms import (
@@ -20,14 +18,14 @@ from netbox_dns.utilities import value_to_unicode
20
18
 
21
19
 
22
20
  __all__ = (
23
- "RecordListView",
24
- "ManagedRecordListView",
25
21
  "RecordView",
22
+ "RecordListView",
26
23
  "RecordEditView",
27
24
  "RecordDeleteView",
28
25
  "RecordBulkImportView",
29
26
  "RecordBulkEditView",
30
27
  "RecordBulkDeleteView",
28
+ "ManagedRecordListView",
31
29
  )
32
30
 
33
31
 
@@ -41,7 +39,9 @@ class RecordListView(generic.ObjectListView):
41
39
 
42
40
 
43
41
  class ManagedRecordListView(generic.ObjectListView):
44
- queryset = Record.objects.prefetch_related("ipam_ip_address", "address_record")
42
+ queryset = Record.objects.filter(managed=True).prefetch_related(
43
+ "ipam_ip_address", "address_record"
44
+ )
45
45
  filterset = RecordFilterSet
46
46
  filterset_form = RecordFilterForm
47
47
  table = ManagedRecordTable
@@ -157,3 +157,8 @@ class RecordBulkEditView(generic.BulkEditView):
157
157
  class RecordBulkDeleteView(generic.BulkDeleteView):
158
158
  queryset = Record.objects.filter(managed=False)
159
159
  table = RecordTable
160
+
161
+
162
+ @register_model_view(Record, "contacts")
163
+ class RecordContactsView(ObjectContactsView):
164
+ queryset = Record.objects.all()
@@ -15,8 +15,8 @@ from netbox_dns.utilities import value_to_unicode
15
15
 
16
16
 
17
17
  __all__ = (
18
- "RecordTemplateListView",
19
18
  "RecordTemplateView",
19
+ "RecordTemplateListView",
20
20
  "RecordTemplateEditView",
21
21
  "RecordTemplateDeleteView",
22
22
  "RecordTemplateBulkImportView",
@@ -21,7 +21,6 @@ __all__ = (
21
21
  "RegistrarBulkImportView",
22
22
  "RegistrarBulkEditView",
23
23
  "RegistrarBulkDeleteView",
24
- "RegistrarZoneListView",
25
24
  )
26
25
 
27
26
 
@@ -0,0 +1,94 @@
1
+ from django.db.models import Q
2
+
3
+ from netbox.views import generic
4
+
5
+ from utilities.views import ViewTab, register_model_view
6
+
7
+ from netbox_dns.models import RegistrationContact, Zone
8
+ from netbox_dns.filtersets import RegistrationContactFilterSet, ZoneFilterSet
9
+ from netbox_dns.forms import (
10
+ RegistrationContactForm,
11
+ RegistrationContactFilterForm,
12
+ RegistrationContactImportForm,
13
+ RegistrationContactBulkEditForm,
14
+ )
15
+ from netbox_dns.tables import RegistrationContactTable, ZoneTable
16
+
17
+
18
+ __all__ = (
19
+ "RegistrationContactView",
20
+ "RegistrationContactEditView",
21
+ "RegistrationContactListView",
22
+ "RegistrationContactDeleteView",
23
+ "RegistrationContactBulkImportView",
24
+ "RegistrationContactBulkEditView",
25
+ "RegistrationContactBulkDeleteView",
26
+ )
27
+
28
+
29
+ class RegistrationContactView(generic.ObjectView):
30
+ queryset = RegistrationContact.objects.all()
31
+
32
+
33
+ class RegistrationContactListView(generic.ObjectListView):
34
+ queryset = RegistrationContact.objects.all()
35
+ table = RegistrationContactTable
36
+ filterset = RegistrationContactFilterSet
37
+ filterset_form = RegistrationContactFilterForm
38
+
39
+
40
+ class RegistrationContactEditView(generic.ObjectEditView):
41
+ queryset = RegistrationContact.objects.all()
42
+ form = RegistrationContactForm
43
+ default_return_url = "plugins:netbox_dns:registrationcontact_list"
44
+
45
+
46
+ class RegistrationContactDeleteView(generic.ObjectDeleteView):
47
+ queryset = RegistrationContact.objects.all()
48
+ default_return_url = "plugins:netbox_dns:registrationcontact_list"
49
+
50
+
51
+ class RegistrationContactBulkImportView(generic.BulkImportView):
52
+ queryset = RegistrationContact.objects.all()
53
+ model_form = RegistrationContactImportForm
54
+ table = RegistrationContactTable
55
+ default_return_url = "plugins:netbox_dns:registrationcontact_list"
56
+
57
+
58
+ class RegistrationContactBulkEditView(generic.BulkEditView):
59
+ queryset = RegistrationContact.objects.all()
60
+ filterset = RegistrationContactFilterSet
61
+ table = RegistrationContactTable
62
+ form = RegistrationContactBulkEditForm
63
+
64
+
65
+ class RegistrationContactBulkDeleteView(generic.BulkDeleteView):
66
+ queryset = RegistrationContact.objects.all()
67
+ table = RegistrationContactTable
68
+
69
+
70
+ @register_model_view(RegistrationContact, "zones")
71
+ class RegistrationContactZoneListView(generic.ObjectChildrenView):
72
+ queryset = RegistrationContact.objects.all().prefetch_related(
73
+ "zone_set", "admin_c_zones", "tech_c_zones", "billing_c_zones"
74
+ )
75
+ child_model = Zone
76
+ table = ZoneTable
77
+ filterset = ZoneFilterSet
78
+ template_name = "netbox_dns/zone/child.html"
79
+ hide_if_empty = True
80
+
81
+ tab = ViewTab(
82
+ label="Zones",
83
+ permission="netbox_dns.view_zone",
84
+ badge=lambda obj: len(obj.zones),
85
+ hide_if_empty=True,
86
+ )
87
+
88
+ def get_children(self, request, parent):
89
+ return Zone.objects.filter(
90
+ Q(registrant=parent)
91
+ | Q(admin_c=parent)
92
+ | Q(tech_c=parent)
93
+ | Q(billing_c=parent)
94
+ )
netbox_dns/views/view.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from utilities.views import ViewTab, register_model_view
2
2
 
3
3
  from netbox.views import generic
4
+ from tenancy.views import ObjectContactsView
4
5
  from ipam.models import Prefix
5
6
 
6
7
  from netbox_dns.models import View, Zone
@@ -24,7 +25,6 @@ __all__ = (
24
25
  "ViewBulkImportView",
25
26
  "ViewBulkEditView",
26
27
  "ViewBulkDeleteView",
27
- "ViewZoneListView",
28
28
  "ViewPrefixEditView",
29
29
  )
30
30
 
@@ -104,3 +104,8 @@ class ViewZoneListView(generic.ObjectChildrenView):
104
104
 
105
105
  def get_children(self, request, parent):
106
106
  return parent.zone_set
107
+
108
+
109
+ @register_model_view(View, "contacts")
110
+ class ViewContactsView(ObjectContactsView):
111
+ queryset = View.objects.all()
netbox_dns/views/zone.py CHANGED
@@ -2,6 +2,7 @@ from dns import name as dns_name
2
2
 
3
3
  from netbox.views import generic
4
4
  from utilities.views import ViewTab, register_model_view
5
+ from tenancy.views import ObjectContactsView
5
6
 
6
7
  from netbox_dns.filtersets import ZoneFilterSet, RecordFilterSet
7
8
  from netbox_dns.forms import (
@@ -19,18 +20,13 @@ from netbox_dns.tables import (
19
20
 
20
21
 
21
22
  __all__ = (
22
- "ZoneListView",
23
23
  "ZoneView",
24
+ "ZoneListView",
24
25
  "ZoneEditView",
25
26
  "ZoneDeleteView",
26
27
  "ZoneBulkImportView",
27
28
  "ZoneBulkEditView",
28
29
  "ZoneBulkDeleteView",
29
- "ZoneRegistrationView",
30
- "ZoneRecordListView",
31
- "ZoneManagedRecordListView",
32
- "ZoneRFC2317ChildZoneListView",
33
- "ZoneChildZoneListView",
34
30
  )
35
31
 
36
32
 
@@ -201,3 +197,8 @@ class ZoneChildZoneListView(generic.ObjectChildrenView):
201
197
 
202
198
  def get_children(self, request, parent):
203
199
  return parent.child_zones
200
+
201
+
202
+ @register_model_view(Zone, "contacts")
203
+ class ZoneContactsView(ObjectContactsView):
204
+ queryset = Zone.objects.all()
@@ -1,5 +1,6 @@
1
1
  from netbox.views import generic
2
2
 
3
+ from netbox_dns.models import ZoneTemplate
3
4
  from netbox_dns.filtersets import ZoneTemplateFilterSet
4
5
  from netbox_dns.forms import (
5
6
  ZoneTemplateImportForm,
@@ -7,13 +8,12 @@ from netbox_dns.forms import (
7
8
  ZoneTemplateFilterForm,
8
9
  ZoneTemplateBulkEditForm,
9
10
  )
10
- from netbox_dns.models import ZoneTemplate
11
11
  from netbox_dns.tables import ZoneTemplateTable, RecordTemplateDisplayTable
12
12
 
13
13
 
14
14
  __all__ = (
15
- "ZoneTemplateListView",
16
15
  "ZoneTemplateView",
16
+ "ZoneTemplateListView",
17
17
  "ZoneTemplateEditView",
18
18
  "ZoneTemplateDeleteView",
19
19
  "ZoneTemplateBulkImportView",
@@ -1,22 +1,18 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-plugin-dns
3
- Version: 1.1.0b6
3
+ Version: 1.1.1
4
4
  Summary: NetBox DNS is a NetBox plugin for managing DNS data.
5
- Home-page: https://github.com/peteeckel/netbox-plugin-dns
6
- License: MIT
5
+ Author-email: Peter Eckel <pete@netbox-dns.org>
6
+ Project-URL: Homepage, https://github.com/peteeckel/netbox-plugin-dns
7
+ Project-URL: Documentation, https://github.com/peteeckel/netbox-plugin-dns/blob/main/docs/using_netbox_dns.md
8
+ Project-URL: Repository, https://github.com/peteeckel/netbox-plugin-dns
9
+ Project-URL: Issues, https://github.com/peteeckel/netbox-plugin-dns/issues
7
10
  Keywords: netbox,netbox-plugin,dns
8
- Author: Peter Eckel
9
- Author-email: pete@netbox-dns.org
10
- Requires-Python: >=3.10,<4.0
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
- Classifier: License :: OSI Approved :: MIT License
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.10
15
- Classifier: Programming Language :: Python :: 3.11
16
- Classifier: Programming Language :: Python :: 3.12
17
- Requires-Dist: dnspython (>=2.6.1,<3.0.0)
18
- Project-URL: Repository, https://github.com/peteeckel/netbox-plugin-dns
12
+ Requires-Python: >=3.10
19
13
  Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: dnspython
20
16
 
21
17
  # NetBox DNS
22
18
  The NetBox DNS plugin enables NetBox to manage operational DNS data such as name servers, zones, records and views, as well as registration data for domains. It can automate tasks like creating PTR records, generating zone serial numbers, NS and SOA records, as well as validate names and values values for resource records to ensure zone data is consistent, up-to-date and compliant with to the relevant RFCs.
@@ -34,6 +30,11 @@ The NetBox DNS plugin enables NetBox to manage operational DNS data such as name
34
30
  <a href="https://pepy.tech/project/netbox-plugin-dns"><img alt="Downloads/Month" src="https://static.pepy.tech/badge/netbox-plugin-dns/week"></a>
35
31
  </div>
36
32
 
33
+ > [!WARNING]
34
+ > **As a result of some issues with NetBox Branching still under investigation, NetBox DNS is currently not compatible with the new NetBox Branching plugin.**
35
+ > This affects multiple aspects of the branching functionality, and currently (netboxlabs-branching-plugin version 0.4.0) there is no workaround. Do not try to use NetBox Branching together with NetBox DNS until these issues are resolved.
36
+ > This warning will be updated as soon as the situation is resolved.
37
+
37
38
  ## Objectives
38
39
  NetBox DNS is designed to be the 'DNS Source of Truth' analogous to NetBox being the 'Network Source of Truth'.
39
40
 
@@ -111,4 +112,3 @@ For further information, please refer to the full documentation: [Using NetBox D
111
112
  ## License
112
113
 
113
114
  MIT
114
-