netbox-plugin-dns 0.22.6__tar.gz → 0.22.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of netbox-plugin-dns might be problematic. Click here for more details.

Files changed (117) hide show
  1. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/PKG-INFO +1 -1
  2. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/__init__.py +2 -1
  3. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/api/serializers.py +1 -0
  4. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/filters/record.py +31 -5
  5. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/filters/zone.py +1 -1
  6. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/forms/record.py +11 -4
  7. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/forms/registrar.py +9 -0
  8. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/forms/zone.py +4 -3
  9. netbox_plugin_dns-0.22.8/netbox_dns/migrations/0029_record_fqdn.py +30 -0
  10. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/models/record.py +67 -63
  11. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/models/zone.py +9 -0
  12. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/views/record.py +2 -2
  13. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/pyproject.toml +1 -1
  14. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/LICENSE +0 -0
  15. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/README.md +0 -0
  16. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/api/nested_serializers.py +0 -0
  17. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/api/urls.py +0 -0
  18. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/api/views.py +0 -0
  19. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/apps.py +0 -0
  20. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/fields/__init__.py +0 -0
  21. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/fields/address.py +0 -0
  22. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/fields/network.py +0 -0
  23. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/fields/rfc2317.py +0 -0
  24. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/filters/__init__.py +0 -0
  25. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/filters/contact.py +0 -0
  26. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/filters/nameserver.py +0 -0
  27. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/filters/registrar.py +0 -0
  28. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/filters/view.py +0 -0
  29. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/forms/__init__.py +0 -0
  30. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/forms/contact.py +0 -0
  31. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/forms/nameserver.py +0 -0
  32. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/forms/view.py +0 -0
  33. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/graphql/__init__.py +0 -0
  34. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/graphql/contact.py +0 -0
  35. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/graphql/nameserver.py +0 -0
  36. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/graphql/record.py +0 -0
  37. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/graphql/registrar.py +0 -0
  38. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/graphql/schema.py +0 -0
  39. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/graphql/view.py +0 -0
  40. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/graphql/zone.py +0 -0
  41. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/management/commands/cleanup_database.py +0 -0
  42. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/management/commands/cleanup_rrset_ttl.py +0 -0
  43. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/management/commands/setup_coupling.py +0 -0
  44. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/management/commands/update_soa.py +0 -0
  45. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0001_initial.py +0 -0
  46. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
  47. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0002_zone_default_ttl.py +0 -0
  48. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0003_soa_managed_records.py +0 -0
  49. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0004_create_ptr_for_a_aaaa_records.py +0 -0
  50. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0005_update_ns_records.py +0 -0
  51. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0006_zone_soa_serial_auto.py +0 -0
  52. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0007_alter_zone_soa_serial_auto.py +0 -0
  53. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0008_zone_status_names.py +0 -0
  54. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0009_netbox32.py +0 -0
  55. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0010_update_soa_records.py +0 -0
  56. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0011_add_view_model.py +0 -0
  57. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0012_adjust_zone_and_record.py +0 -0
  58. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0013_add_nameserver_zone_record_description.py +0 -0
  59. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0014_add_view_description.py +0 -0
  60. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0015_add_record_status.py +0 -0
  61. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0016_cleanup_ptr_records.py +0 -0
  62. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0017_alter_record_ttl.py +0 -0
  63. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0018_zone_arpa_network.py +0 -0
  64. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0019_update_ns_ttl.py +0 -0
  65. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
  66. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
  67. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0022_search.py +0 -0
  68. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
  69. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0024_tenancy.py +0 -0
  70. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
  71. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0026_domain_registration.py +0 -0
  72. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
  73. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
  74. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/migrations/__init__.py +0 -0
  75. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/models/__init__.py +0 -0
  76. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/models/contact.py +0 -0
  77. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/models/nameserver.py +0 -0
  78. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/models/registrar.py +0 -0
  79. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/models/view.py +0 -0
  80. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/navigation.py +0 -0
  81. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/signals/__init__.py +0 -0
  82. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/signals/ipam_coupling.py +0 -0
  83. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/tables/__init__.py +0 -0
  84. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/tables/contact.py +0 -0
  85. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/tables/nameserver.py +0 -0
  86. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/tables/record.py +4 -4
  87. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/tables/registrar.py +0 -0
  88. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/tables/view.py +0 -0
  89. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/tables/zone.py +0 -0
  90. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/template_content.py +0 -0
  91. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/contact.html +0 -0
  92. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/nameserver.html +0 -0
  93. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
  94. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
  95. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/record.html +0 -0
  96. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/registrar.html +0 -0
  97. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/related_dns_objects.html +0 -0
  98. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/view.html +0 -0
  99. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
  100. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
  101. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
  102. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
  103. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
  104. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
  105. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/templates/netbox_dns/zone.html +0 -0
  106. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/urls.py +0 -0
  107. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/utilities/__init__.py +0 -0
  108. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/utilities/ipam_coupling.py +0 -0
  109. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/validators/__init__.py +0 -0
  110. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/validators/dns_name.py +0 -0
  111. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/validators/rfc2317.py +0 -0
  112. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/views/__init__.py +0 -0
  113. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/views/contact.py +0 -0
  114. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/views/nameserver.py +0 -0
  115. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/views/registrar.py +0 -0
  116. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/views/view.py +0 -0
  117. {netbox_plugin_dns-0.22.6 → netbox_plugin_dns-0.22.8}/netbox_dns/views/zone.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-plugin-dns
3
- Version: 0.22.6
3
+ Version: 0.22.8
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
@@ -10,7 +10,7 @@ except ImportError:
10
10
  # NetBox 3.5.8
11
11
  from extras.plugins.utils import get_plugin_config
12
12
 
13
- __version__ = "0.22.6"
13
+ __version__ = "0.22.8"
14
14
 
15
15
 
16
16
  class DNSConfig(PluginConfig):
@@ -18,6 +18,7 @@ class DNSConfig(PluginConfig):
18
18
  verbose_name = "NetBox DNS"
19
19
  description = "NetBox plugin for DNS data"
20
20
  min_version = "3.5.0"
21
+ max_version = "3.99.0"
21
22
  version = __version__
22
23
  author = "Peter Eckel"
23
24
  author_email = "pete@netbox-dns.org"
@@ -241,6 +241,7 @@ class RecordSerializer(NetBoxModelSerializer):
241
241
  "display",
242
242
  "type",
243
243
  "name",
244
+ "fqdn",
244
245
  "value",
245
246
  "status",
246
247
  "ttl",
@@ -3,17 +3,22 @@ from django.db.models import Q
3
3
 
4
4
  from netbox.filtersets import NetBoxModelFilterSet
5
5
  from tenancy.filtersets import TenancyFilterSet
6
+ from utilities.filters import MultiValueCharFilter
6
7
 
7
- from netbox_dns.models import View, Zone, Record, RecordTypeChoices
8
+ from netbox_dns.models import View, Zone, Record, RecordTypeChoices, RecordStatusChoices
8
9
 
9
10
 
10
11
  class RecordFilter(TenancyFilterSet, NetBoxModelFilterSet):
11
- """Filter capabilities for Record instances."""
12
-
12
+ fqdn = MultiValueCharFilter(
13
+ method="filter_fqdn",
14
+ )
13
15
  type = django_filters.MultipleChoiceFilter(
14
16
  choices=RecordTypeChoices,
15
17
  null_value=None,
16
18
  )
19
+ status = django_filters.MultipleChoiceFilter(
20
+ choices=RecordStatusChoices,
21
+ )
17
22
  zone_id = django_filters.ModelMultipleChoiceFilter(
18
23
  queryset=Zone.objects.all(),
19
24
  label="Parent Zone ID",
@@ -39,10 +44,31 @@ class RecordFilter(TenancyFilterSet, NetBoxModelFilterSet):
39
44
 
40
45
  class Meta:
41
46
  model = Record
42
- fields = ("id", "type", "name", "value", "status", "zone", "managed", "tenant")
47
+ fields = (
48
+ "id",
49
+ "type",
50
+ "name",
51
+ "fqdn",
52
+ "value",
53
+ "status",
54
+ "zone",
55
+ "managed",
56
+ "tenant",
57
+ )
58
+
59
+ def filter_fqdn(self, queryset, name, value):
60
+ if not value:
61
+ return queryset
62
+
63
+ fqdns = []
64
+ for fqdn in value:
65
+ if not fqdn.endswith("."):
66
+ fqdn = fqdn + "."
67
+ fqdns.append(fqdn)
68
+
69
+ return queryset.filter(fqdn__in=fqdns)
43
70
 
44
71
  def search(self, queryset, name, value):
45
- """Perform the filtered search."""
46
72
  if not value.strip():
47
73
  return queryset
48
74
  qs_filter = (
@@ -8,7 +8,7 @@ from netbox_dns.models import View, Zone, ZoneStatusChoices, Registrar, Contact
8
8
 
9
9
 
10
10
  class ZoneFilter(TenancyFilterSet, NetBoxModelFilterSet):
11
- status = django_filters.ChoiceFilter(
11
+ status = django_filters.MultipleChoiceFilter(
12
12
  choices=ZoneStatusChoices,
13
13
  )
14
14
  view_id = django_filters.ModelMultipleChoiceFilter(
@@ -79,24 +79,31 @@ class RecordFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
79
79
  model = Record
80
80
  fieldsets = (
81
81
  (None, ("q", "filter_id", "tag")),
82
- ("Attributes", ("view_id", "zone_id", "name", "type", "value", "status")),
82
+ (
83
+ "Attributes",
84
+ ("view_id", "zone_id", "name", "fqdn", "type", "value", "status"),
85
+ ),
83
86
  ("Tenant", ("tenant_group_id", "tenant_id")),
84
87
  )
85
88
 
86
89
  type = forms.MultipleChoiceField(
87
- choices=add_blank_choice(RecordTypeChoices),
90
+ choices=RecordTypeChoices,
88
91
  required=False,
89
92
  )
90
93
  name = forms.CharField(
91
94
  required=False,
92
95
  label="Name",
93
96
  )
97
+ fqdn = forms.CharField(
98
+ required=False,
99
+ label="FQDN",
100
+ )
94
101
  value = forms.CharField(
95
102
  required=False,
96
103
  label="Value",
97
104
  )
98
- status = forms.ChoiceField(
99
- choices=add_blank_choice(RecordStatusChoices),
105
+ status = forms.MultipleChoiceField(
106
+ choices=RecordStatusChoices,
100
107
  required=False,
101
108
  )
102
109
  zone_id = DynamicModelMultipleChoiceField(
@@ -83,6 +83,13 @@ class RegistrarImportForm(NetBoxModelImportForm):
83
83
  class RegistrarBulkEditForm(NetBoxModelBulkEditForm):
84
84
  model = Registrar
85
85
 
86
+ iana_id = forms.IntegerField(
87
+ required=False,
88
+ label="IANA ID",
89
+ )
90
+ address = forms.CharField(
91
+ required=False,
92
+ )
86
93
  referral_url = forms.CharField(
87
94
  required=False,
88
95
  label="Referral URL",
@@ -104,6 +111,7 @@ class RegistrarBulkEditForm(NetBoxModelBulkEditForm):
104
111
  (
105
112
  None,
106
113
  (
114
+ "iana_id",
107
115
  "address",
108
116
  "referral_url",
109
117
  "whois_server",
@@ -114,6 +122,7 @@ class RegistrarBulkEditForm(NetBoxModelBulkEditForm):
114
122
  )
115
123
 
116
124
  nullable_fields = (
125
+ "iana_id",
117
126
  "address",
118
127
  "referral_url",
119
128
  "whois_server",
@@ -258,8 +258,8 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
258
258
  required=False,
259
259
  label="View",
260
260
  )
261
- status = forms.ChoiceField(
262
- choices=add_blank_choice(ZoneStatusChoices),
261
+ status = forms.MultipleChoiceField(
262
+ choices=ZoneStatusChoices,
263
263
  required=False,
264
264
  )
265
265
  name = forms.CharField(
@@ -595,8 +595,9 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
595
595
  help_text="IPv4 network prefix with a mask length of at least 25 bits",
596
596
  validators=[validate_ipv4, validate_prefix, validate_rfc2317],
597
597
  )
598
- rfc2317_parent_managed = forms.BooleanField(
598
+ rfc2317_parent_managed = forms.NullBooleanField(
599
599
  required=False,
600
+ widget=BulkEditNullBooleanSelect(),
600
601
  label="RFC2317 Parent Managed",
601
602
  help_text="IPv4 reverse zone for deletgating the RFC2317 PTR records is managed in NetBox DNS",
602
603
  )
@@ -0,0 +1,30 @@
1
+ from dns import name as dns_name
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ def update_record_fqdn(apps, schema_editor):
7
+ Record = apps.get_model("netbox_dns", "Record")
8
+
9
+ for record in Record.objects.filter(fqdn__isnull=True):
10
+ zone = dns_name.from_text(record.zone.name, origin=dns_name.root)
11
+ fqdn = dns_name.from_text(record.name, origin=zone)
12
+
13
+ record.fqdn = fqdn.to_text()
14
+
15
+ record.save()
16
+
17
+
18
+ class Migration(migrations.Migration):
19
+ dependencies = [
20
+ ("netbox_dns", "0028_rfc2317_fields"),
21
+ ]
22
+
23
+ operations = [
24
+ migrations.AddField(
25
+ model_name="record",
26
+ name="fqdn",
27
+ field=models.CharField(default=None, max_length=255, null=True, blank=True),
28
+ ),
29
+ migrations.RunPython(update_record_fqdn),
30
+ ]
@@ -114,17 +114,23 @@ class Record(NetBoxModel):
114
114
  Q(Q(type=RecordTypeChoices.A) | Q(type=RecordTypeChoices.AAAA)),
115
115
  )
116
116
 
117
+ name = models.CharField(
118
+ max_length=255,
119
+ )
117
120
  zone = models.ForeignKey(
118
121
  "Zone",
119
122
  on_delete=models.CASCADE,
120
123
  )
124
+ fqdn = models.CharField(
125
+ max_length=255,
126
+ null=True,
127
+ blank=True,
128
+ default=None,
129
+ )
121
130
  type = models.CharField(
122
131
  choices=RecordTypeChoices,
123
132
  max_length=10,
124
133
  )
125
- name = models.CharField(
126
- max_length=255,
127
- )
128
134
  value = models.CharField(
129
135
  max_length=65535,
130
136
  )
@@ -209,14 +215,7 @@ class Record(NetBoxModel):
209
215
 
210
216
  def __str__(self):
211
217
  try:
212
- name = (
213
- dns_name.from_text(
214
- str(self.name),
215
- origin=dns_name.from_text(self.zone.name, origin=None),
216
- )
217
- .relativize(dns_name.root)
218
- .to_unicode()
219
- )
218
+ name = dns_name.from_text(self.fqdn).relativize(dns_name.root).to_unicode()
220
219
  except dns_name.IDNAException:
221
220
  name = self.name
222
221
  except dns_name.LabelTooLong as exc:
@@ -234,13 +233,6 @@ class Record(NetBoxModel):
234
233
  def get_absolute_url(self):
235
234
  return reverse("plugins:netbox_dns:record", kwargs={"pk": self.id})
236
235
 
237
- @property
238
- def fqdn(self):
239
- zone = dns_name.from_text(self.zone.name)
240
- name = dns_name.from_text(self.name, origin=zone)
241
-
242
- return name.to_text()
243
-
244
236
  @property
245
237
  def value_fqdn(self):
246
238
  if self.type != RecordTypeChoices.CNAME:
@@ -393,6 +385,22 @@ class Record(NetBoxModel):
393
385
 
394
386
  self.ptr_record = ptr_record
395
387
 
388
+ def remove_from_rfc2317_cname_record(self, save_zone_serial=True):
389
+ if self.rfc2317_cname_record.pk:
390
+ rfc2317_ptr_records = self.rfc2317_cname_record.rfc2317_ptr_records.exclude(
391
+ pk=self.pk
392
+ )
393
+
394
+ if rfc2317_ptr_records:
395
+ self.rfc2317_cname_record.ttl = rfc2317_ptr_records.aggregate(
396
+ Min("ttl")
397
+ ).get("ttl__min")
398
+ self.rfc2317_cname_record.save(
399
+ update_fields=["ttl"], save_zone_serial=save_zone_serial
400
+ )
401
+ else:
402
+ self.rfc2317_cname_record.delete()
403
+
396
404
  def update_rfc2317_cname_record(self, save_zone_serial=True):
397
405
  if self.zone.rfc2317_parent_managed:
398
406
  cname_name = dns_name.from_text(
@@ -400,48 +408,56 @@ class Record(NetBoxModel):
400
408
  ).relativize(dns_name.from_text(self.zone.rfc2317_parent_zone.name))
401
409
 
402
410
  if self.rfc2317_cname_record is not None:
403
- self.rfc2317_cname_record.name = cname_name
404
- self.rfc2317_cname_record.zone = self.zone.rfc2317_parent_zone
405
- self.rfc2317_cname_record.value = self.fqdn
406
- self.rfc2317_cname_record.ttl = min_ttl(
407
- self.rfc2317_cname_record.rfc2317_ptr_records.exclude(pk=self.pk)
411
+ if self.rfc2317_cname_record.name == cname_name.to_text():
412
+ self.rfc2317_cname_record.zone = self.zone.rfc2317_parent_zone
413
+ self.rfc2317_cname_record.value = self.fqdn
414
+ self.rfc2317_cname_record.ttl = min_ttl(
415
+ self.rfc2317_cname_record.rfc2317_ptr_records.exclude(
416
+ pk=self.pk
417
+ )
418
+ .aggregate(Min("ttl"))
419
+ .get("ttl__min"),
420
+ self.ttl,
421
+ )
422
+ self.rfc2317_cname_record.save(save_zone_serial=save_zone_serial)
423
+
424
+ return
425
+ else:
426
+ self.remove_from_rfc2317_cname_record(
427
+ save_zone_serial=save_zone_serial
428
+ )
429
+
430
+ rfc2317_cname_record = Record.objects.filter(
431
+ name=cname_name,
432
+ type=RecordTypeChoices.CNAME,
433
+ zone=self.zone.rfc2317_parent_zone,
434
+ managed=True,
435
+ value=self.fqdn,
436
+ ).first()
437
+
438
+ if rfc2317_cname_record is not None:
439
+ rfc2317_cname_record.ttl = min_ttl(
440
+ rfc2317_cname_record.rfc2317_ptr_records.exclude(pk=self.pk)
408
441
  .aggregate(Min("ttl"))
409
442
  .get("ttl__min"),
410
443
  self.ttl,
411
444
  )
412
- self.rfc2317_cname_record.save(save_zone_serial=save_zone_serial)
445
+ rfc2317_cname_record.save(
446
+ update_fields=["ttl"], save_zone_serial=save_zone_serial
447
+ )
448
+
413
449
  else:
414
- rfc2317_cname_record = Record.objects.filter(
450
+ rfc2317_cname_record = Record(
415
451
  name=cname_name,
416
452
  type=RecordTypeChoices.CNAME,
417
453
  zone=self.zone.rfc2317_parent_zone,
418
454
  managed=True,
419
455
  value=self.fqdn,
420
- ).first()
421
-
422
- if rfc2317_cname_record is not None:
423
- rfc2317_cname_record.ttl = min_ttl(
424
- rfc2317_cname_record.rfc2317_ptr_records.exclude(pk=self.pk)
425
- .aggregate(Min("ttl"))
426
- .get("ttl__min"),
427
- self.ttl,
428
- )
429
- rfc2317_cname_record.save(
430
- update_fields=["ttl"], save_zone_serial=save_zone_serial
431
- )
432
-
433
- else:
434
- rfc2317_cname_record = Record(
435
- name=cname_name,
436
- type=RecordTypeChoices.CNAME,
437
- zone=self.zone.rfc2317_parent_zone,
438
- managed=True,
439
- value=self.fqdn,
440
- ttl=self.ttl,
441
- )
442
- rfc2317_cname_record.save(save_zone_serial=save_zone_serial)
456
+ ttl=self.ttl,
457
+ )
458
+ rfc2317_cname_record.save(save_zone_serial=save_zone_serial)
443
459
 
444
- self.rfc2317_cname_record = rfc2317_cname_record
460
+ self.rfc2317_cname_record = rfc2317_cname_record
445
461
 
446
462
  else:
447
463
  if self.rfc2317_cname_record is not None:
@@ -458,6 +474,7 @@ class Record(NetBoxModel):
458
474
  name.to_unicode()
459
475
 
460
476
  self.name = name.relativize(zone).to_text()
477
+ self.fqdn = fqdn.to_text()
461
478
 
462
479
  except dns.exception.DNSException as exc:
463
480
  raise ValidationError(
@@ -725,20 +742,7 @@ class Record(NetBoxModel):
725
742
 
726
743
  def delete(self, *args, save_zone_serial=True, **kwargs):
727
744
  if self.rfc2317_cname_record:
728
- if self.rfc2317_cname_record.pk:
729
- if self.rfc2317_cname_record.rfc2317_ptr_records.count() == 1:
730
- self.rfc2317_cname_record.delete()
731
- else:
732
- self.rfc2317_cname_record.ttl = (
733
- self.rfc2317_cname_record.rfc2317_ptr_records.exclude(
734
- pk=self.pk
735
- )
736
- .aggregate(Min("ttl"))
737
- .get("ttl__min")
738
- )
739
- self.rfc2317_cname_record.save(
740
- update_fields=["ttl"], save_zone_serial=save_zone_serial
741
- )
745
+ self.remove_from_rfc2317_cname_record(save_zone_serial=save_zone_serial)
742
746
 
743
747
  if self.ptr_record:
744
748
  self.ptr_record.delete()
@@ -738,6 +738,15 @@ class Zone(NetBoxModel):
738
738
  ip.dns_name = f'{ip.custom_field_data["ipaddress_dns_record_name"]}.{self.name}'
739
739
  ip.save(update_fields=["dns_name"])
740
740
 
741
+ if name_changed:
742
+ for _record in self.record_set.all():
743
+ _record.save(
744
+ update_fields=["fqdn"],
745
+ save_zone_serial=False,
746
+ update_rrset_ttl=False,
747
+ update_rfc2317_cname=False,
748
+ )
749
+
741
750
  self.save_soa_serial()
742
751
  self.update_soa_record()
743
752
 
@@ -44,7 +44,7 @@ class RecordView(generic.ObjectView):
44
44
  value_fqdn = dns_name.from_text(instance.value_fqdn)
45
45
  value_zone_names = [
46
46
  value_fqdn.split(length)[1].to_text().rstrip(".")
47
- for length in range(2, len(value_fqdn))
47
+ for length in range(2, len(value_fqdn) + 1)
48
48
  ]
49
49
 
50
50
  value_zone = (
@@ -80,7 +80,7 @@ class RecordView(generic.ObjectView):
80
80
  fqdn = dns_name.from_text(instance.fqdn)
81
81
  parent_zone_names = [
82
82
  fqdn.split(length)[1].to_text().rstrip(".")
83
- for length in range(1, len(fqdn))
83
+ for length in range(1, len(fqdn) + 1)
84
84
  ]
85
85
 
86
86
  parent_zones = Zone.objects.filter(
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "netbox-plugin-dns"
3
- version = "0.22.6"
3
+ version = "0.22.8"
4
4
  description = "NetBox DNS is a NetBox plugin for managing DNS data."
5
5
  authors = ["Peter Eckel <pete@netbox-dns.org>"]
6
6
  homepage = "https://github.com/peteeckel/netbox-plugin-dns"
@@ -61,8 +61,8 @@ class RecordTable(RecordBaseTable):
61
61
  model = Record
62
62
  fields = (
63
63
  "pk",
64
- "zone",
65
64
  "name",
65
+ "zone",
66
66
  "ttl",
67
67
  "type",
68
68
  "value",
@@ -77,8 +77,8 @@ class RecordTable(RecordBaseTable):
77
77
  "tenant_group",
78
78
  )
79
79
  default_columns = (
80
- "zone",
81
80
  "name",
81
+ "zone",
82
82
  "ttl",
83
83
  "type",
84
84
  "value",
@@ -101,8 +101,8 @@ class ManagedRecordTable(RecordBaseTable):
101
101
  class Meta(NetBoxTable.Meta):
102
102
  model = Record
103
103
  fields = (
104
- "zone",
105
104
  "name",
105
+ "zone",
106
106
  "ttl",
107
107
  "type",
108
108
  "value",
@@ -112,8 +112,8 @@ class ManagedRecordTable(RecordBaseTable):
112
112
  "active",
113
113
  )
114
114
  default_columns = (
115
- "zone",
116
115
  "name",
116
+ "zone",
117
117
  "ttl",
118
118
  "type",
119
119
  "value",