netbox-plugin-dns 1.1.3__tar.gz → 1.1.4__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 (156) hide show
  1. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/PKG-INFO +2 -2
  2. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/README.md +1 -1
  3. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/__init__.py +9 -2
  4. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/choices/zone.py +2 -0
  5. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/fields/address.py +3 -21
  6. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/filtersets/record.py +4 -0
  7. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/forms/record.py +18 -6
  8. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/forms/zone.py +7 -1
  9. netbox_plugin_dns-1.1.4/netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
  10. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/models/record.py +11 -10
  11. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/models/record_template.py +1 -1
  12. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/models/zone.py +18 -7
  13. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/signals/ipam_dnssync.py +1 -1
  14. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/validators/dns_value.py +47 -6
  15. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_plugin_dns.egg-info/PKG-INFO +2 -2
  16. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/pyproject.toml +1 -1
  17. netbox_plugin_dns-1.1.3/netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
  18. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/LICENSE +0 -0
  19. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/nested_serializers.py +0 -0
  20. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers.py +0 -0
  21. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/__init__.py +0 -0
  22. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/nameserver.py +0 -0
  23. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/prefix.py +0 -0
  24. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/record.py +0 -0
  25. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/record_template.py +0 -0
  26. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/registrar.py +0 -0
  27. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/registration_contact.py +0 -0
  28. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/view.py +0 -0
  29. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/zone.py +0 -0
  30. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/serializers_/zone_template.py +0 -0
  31. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/urls.py +0 -0
  32. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/api/views.py +0 -0
  33. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/apps.py +0 -0
  34. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/choices/__init__.py +0 -0
  35. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/choices/record.py +0 -0
  36. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/fields/__init__.py +0 -0
  37. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/fields/ipam.py +0 -0
  38. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/fields/network.py +0 -0
  39. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/fields/rfc2317.py +0 -0
  40. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/filtersets/__init__.py +0 -0
  41. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/filtersets/nameserver.py +0 -0
  42. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/filtersets/record_template.py +0 -0
  43. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/filtersets/registrar.py +0 -0
  44. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/filtersets/registration_contact.py +0 -0
  45. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/filtersets/view.py +0 -0
  46. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/filtersets/zone.py +0 -0
  47. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/filtersets/zone_template.py +0 -0
  48. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/forms/__init__.py +0 -0
  49. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/forms/nameserver.py +0 -0
  50. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/forms/record_template.py +0 -0
  51. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/forms/registrar.py +0 -0
  52. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/forms/registration_contact.py +0 -0
  53. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/forms/view.py +0 -0
  54. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/forms/zone_template.py +0 -0
  55. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/graphql/__init__.py +0 -0
  56. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/graphql/filters.py +0 -0
  57. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/graphql/schema.py +0 -0
  58. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/graphql/types.py +0 -0
  59. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
  60. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/management/commands/cleanup_database.py +0 -0
  61. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/management/commands/cleanup_rrset_ttl.py +0 -0
  62. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/management/commands/rebuild_dnssync.py +0 -0
  63. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/management/commands/setup_dnssync.py +0 -0
  64. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/management/commands/update_soa.py +0 -0
  65. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
  66. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +0 -0
  67. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0002_contact_description_registrar_description.py +0 -0
  68. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0003_default_view.py +0 -0
  69. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0004_create_and_assign_default_view.py +0 -0
  70. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0005_alter_zone_view_not_null.py +0 -0
  71. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0006_templating.py +0 -0
  72. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0007_alter_ordering_options.py +0 -0
  73. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0008_view_prefixes.py +0 -0
  74. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0009_rename_contact_registrationcontact.py +0 -0
  75. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0010_view_ip_address_filter.py +0 -0
  76. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
  77. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
  78. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0022_search.py +0 -0
  79. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
  80. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0024_tenancy.py +0 -0
  81. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
  82. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0026_domain_registration.py +0 -0
  83. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
  84. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
  85. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/0029_record_fqdn.py +0 -0
  86. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/migrations/__init__.py +0 -0
  87. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/mixins/__init__.py +0 -0
  88. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/mixins/object_modification.py +0 -0
  89. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/models/__init__.py +0 -0
  90. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/models/nameserver.py +0 -0
  91. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/models/registrar.py +0 -0
  92. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/models/registration_contact.py +0 -0
  93. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/models/view.py +0 -0
  94. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/models/zone_template.py +0 -0
  95. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/navigation.py +0 -0
  96. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/signals/__init__.py +0 -0
  97. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/__init__.py +0 -0
  98. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/ipam_dnssync.py +0 -0
  99. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/nameserver.py +0 -0
  100. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/record.py +0 -0
  101. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/record_template.py +0 -0
  102. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/registrar.py +0 -0
  103. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/registration_contact.py +0 -0
  104. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/view.py +0 -0
  105. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/zone.py +0 -0
  106. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/tables/zone_template.py +0 -0
  107. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/template_content.py +0 -0
  108. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/nameserver.html +0 -0
  109. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
  110. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
  111. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/record.html +0 -0
  112. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/recordtemplate.html +0 -0
  113. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/registrar.html +0 -0
  114. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/registrationcontact.html +0 -0
  115. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/view/button.html +0 -0
  116. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/view/prefix.html +0 -0
  117. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/view/related.html +0 -0
  118. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/view.html +0 -0
  119. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
  120. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
  121. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/zone/child_zone.html +0 -0
  122. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
  123. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
  124. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
  125. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
  126. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/zone.html +0 -0
  127. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/templates/netbox_dns/zonetemplate.html +0 -0
  128. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/urls/__init__.py +0 -0
  129. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/urls/nameserver.py +0 -0
  130. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/urls/record.py +0 -0
  131. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/urls/record_template.py +0 -0
  132. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/urls/registrar.py +0 -0
  133. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/urls/registration_contact.py +0 -0
  134. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/urls/view.py +0 -0
  135. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/urls/zone.py +0 -0
  136. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/urls/zone_template.py +0 -0
  137. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/utilities/__init__.py +0 -0
  138. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/utilities/conversions.py +0 -0
  139. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/utilities/ipam_dnssync.py +0 -0
  140. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/validators/__init__.py +0 -0
  141. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/validators/dns_name.py +0 -0
  142. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/validators/rfc2317.py +0 -0
  143. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/views/__init__.py +0 -0
  144. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/views/nameserver.py +0 -0
  145. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/views/record.py +0 -0
  146. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/views/record_template.py +0 -0
  147. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/views/registrar.py +0 -0
  148. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/views/registration_contact.py +0 -0
  149. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/views/view.py +0 -0
  150. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/views/zone.py +0 -0
  151. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_dns/views/zone_template.py +0 -0
  152. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_plugin_dns.egg-info/SOURCES.txt +0 -0
  153. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_plugin_dns.egg-info/dependency_links.txt +0 -0
  154. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_plugin_dns.egg-info/requires.txt +0 -0
  155. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/netbox_plugin_dns.egg-info/top_level.txt +0 -0
  156. {netbox_plugin_dns-1.1.3 → netbox_plugin_dns-1.1.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-plugin-dns
3
- Version: 1.1.3
3
+ Version: 1.1.4
4
4
  Summary: NetBox DNS is a NetBox plugin for managing DNS data.
5
5
  Author-email: Peter Eckel <pete@netbox-dns.org>
6
6
  Project-URL: Homepage, https://github.com/peteeckel/netbox-plugin-dns
@@ -32,7 +32,7 @@ The NetBox DNS plugin enables NetBox to manage operational DNS data such as name
32
32
 
33
33
  > [!WARNING]
34
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.
35
+ > This affects multiple aspects of the branching functionality, and currently there is no workaround. Do not try to use NetBox Branching together with NetBox DNS until these issues are resolved.
36
36
  > This warning will be updated as soon as the situation is resolved.
37
37
 
38
38
  ## Objectives
@@ -16,7 +16,7 @@ The NetBox DNS plugin enables NetBox to manage operational DNS data such as name
16
16
 
17
17
  > [!WARNING]
18
18
  > **As a result of some issues with NetBox Branching still under investigation, NetBox DNS is currently not compatible with the new NetBox Branching plugin.**
19
- > 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.
19
+ > This affects multiple aspects of the branching functionality, and currently there is no workaround. Do not try to use NetBox Branching together with NetBox DNS until these issues are resolved.
20
20
  > This warning will be updated as soon as the situation is resolved.
21
21
 
22
22
  ## Objectives
@@ -4,9 +4,9 @@ from django.utils.translation import gettext_lazy as _
4
4
  from netbox.plugins import PluginConfig
5
5
  from ipam.choices import IPAddressStatusChoices
6
6
 
7
- from netbox_dns.choices import RecordTypeChoices
7
+ from netbox_dns.choices import RecordTypeChoices, RecordStatusChoices, ZoneStatusChoices
8
8
 
9
- __version__ = "1.1.3"
9
+ __version__ = "1.1.4"
10
10
 
11
11
 
12
12
  class DNSConfig(PluginConfig):
@@ -26,6 +26,13 @@ class DNSConfig(PluginConfig):
26
26
  "zone_soa_retry": 7200,
27
27
  "zone_soa_expire": 2419200,
28
28
  "zone_soa_minimum": 3600,
29
+ "zone_active_status": [
30
+ ZoneStatusChoices.STATUS_ACTIVE,
31
+ ZoneStatusChoices.STATUS_DYNAMIC,
32
+ ],
33
+ "record_active_status": [
34
+ RecordStatusChoices.STATUS_ACTIVE,
35
+ ],
29
36
  "dnssync_disabled": False,
30
37
  "dnssync_ipaddress_active_status": [
31
38
  IPAddressStatusChoices.STATUS_ACTIVE,
@@ -13,10 +13,12 @@ class ZoneStatusChoices(ChoiceSet):
13
13
  STATUS_RESERVED = "reserved"
14
14
  STATUS_DEPRECATED = "deprecated"
15
15
  STATUS_PARKED = "parked"
16
+ STATUS_DYNAMIC = "dynamic"
16
17
 
17
18
  CHOICES = [
18
19
  (STATUS_ACTIVE, _("Active"), "blue"),
19
20
  (STATUS_RESERVED, _("Reserved"), "cyan"),
20
21
  (STATUS_DEPRECATED, _("Deprecated"), "red"),
21
22
  (STATUS_PARKED, _("Parked"), "gray"),
23
+ (STATUS_DYNAMIC, _("Dynamic"), "orange"),
22
24
  ]
@@ -1,31 +1,13 @@
1
- from django import forms
2
1
  from django.db import models
3
2
  from django.core.exceptions import ValidationError
4
3
  from django.utils.translation import gettext_lazy as _
5
4
 
6
5
  from netaddr import AddrFormatError, IPAddress
7
6
 
7
+ from ipam.formfields import IPAddressFormField
8
8
 
9
- __all__ = (
10
- "AddressFormField",
11
- "AddressField",
12
- )
13
9
 
14
-
15
- class AddressFormField(forms.Field):
16
- def to_python(self, value):
17
- if not value:
18
- return None
19
-
20
- if isinstance(value, IPAddress):
21
- return value
22
-
23
- try:
24
- ip_address = IPAddress(value)
25
- except AddrFormatError as exc:
26
- raise ValidationError(exc)
27
-
28
- return ip_address
10
+ __all__ = ("AddressField",)
29
11
 
30
12
 
31
13
  class AddressField(models.Field):
@@ -58,7 +40,7 @@ class AddressField(models.Field):
58
40
  return str(self.to_python(value))
59
41
 
60
42
  def form_class(self):
61
- return AddressFormField
43
+ return IPAddressFormField
62
44
 
63
45
  def formfield(self, **kwargs):
64
46
  defaults = {"form_class": self.form_class()}
@@ -76,6 +76,9 @@ class RecordFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
76
76
  method="filter_ip_address",
77
77
  label=_("IP Address"),
78
78
  )
79
+ active = django_filters.BooleanFilter(
80
+ label=_("Record is active"),
81
+ )
79
82
 
80
83
  managed = django_filters.BooleanFilter()
81
84
 
@@ -89,6 +92,7 @@ class RecordFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
89
92
  "ttl",
90
93
  "value",
91
94
  "disable_ptr",
95
+ "active",
92
96
  "managed",
93
97
  )
94
98
 
@@ -38,12 +38,6 @@ class RecordForm(TenancyForm, NetBoxModelForm):
38
38
  def __init__(self, *args, **kwargs):
39
39
  super().__init__(*args, **kwargs)
40
40
 
41
- initial_zone_id = self.initial.get("zone")
42
- if initial_zone_id is not None:
43
- self.initial["view"] = Zone.objects.get(pk=initial_zone_id).view
44
- else:
45
- self.initial["view"] = View.get_default_view()
46
-
47
41
  initial_name = self.initial.get("name")
48
42
  if initial_name:
49
43
  self.initial["name"] = name_to_unicode(initial_name)
@@ -51,6 +45,9 @@ class RecordForm(TenancyForm, NetBoxModelForm):
51
45
  view = DynamicModelChoiceField(
52
46
  queryset=View.objects.all(),
53
47
  required=False,
48
+ initial_params={
49
+ "zone": "$zone",
50
+ },
54
51
  label=_p("DNS", "View"),
55
52
  )
56
53
  zone = DynamicModelChoiceField(
@@ -111,6 +108,7 @@ class RecordFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
111
108
  fieldsets = (
112
109
  FieldSet("q", "filter_id", "tag"),
113
110
  FieldSet(
111
+ "view_id",
114
112
  "zone_id",
115
113
  "name",
116
114
  "fqdn",
@@ -118,6 +116,7 @@ class RecordFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
118
116
  "value",
119
117
  "disable_ptr",
120
118
  "status",
119
+ "active",
121
120
  "description",
122
121
  name=_("Attributes"),
123
122
  ),
@@ -151,10 +150,23 @@ class RecordFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
151
150
  required=False,
152
151
  label=_("Status"),
153
152
  )
153
+ view_id = DynamicModelMultipleChoiceField(
154
+ queryset=View.objects.all(),
155
+ required=False,
156
+ label=_("View"),
157
+ )
154
158
  zone_id = DynamicModelMultipleChoiceField(
155
159
  queryset=Zone.objects.all(),
156
160
  required=False,
157
161
  label=_("Zone"),
162
+ query_params={
163
+ "view_id": "$view_id",
164
+ },
165
+ )
166
+ active = forms.NullBooleanField(
167
+ required=False,
168
+ widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
169
+ label=_("Active"),
158
170
  )
159
171
  description = forms.CharField(
160
172
  required=False,
@@ -354,6 +354,7 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
354
354
  "status",
355
355
  "name",
356
356
  "nameserver_id",
357
+ "active",
357
358
  "description",
358
359
  name=_("Attributes"),
359
360
  ),
@@ -400,6 +401,11 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
400
401
  required=False,
401
402
  label=_("Nameservers"),
402
403
  )
404
+ active = forms.NullBooleanField(
405
+ required=False,
406
+ widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
407
+ label=_("Active"),
408
+ )
403
409
  description = forms.CharField(
404
410
  required=False,
405
411
  label=_("Description"),
@@ -781,7 +787,7 @@ class ZoneBulkEditForm(NetBoxModelBulkEditForm):
781
787
  tenant_group = DynamicModelChoiceField(
782
788
  queryset=TenantGroup.objects.all(),
783
789
  required=False,
784
- label=_("Tenant"),
790
+ label=_("Tenant Group"),
785
791
  )
786
792
  tenant = DynamicModelChoiceField(
787
793
  queryset=Tenant.objects.all(),
@@ -34,6 +34,9 @@ __all__ = (
34
34
  "RecordIndex",
35
35
  )
36
36
 
37
+ ZONE_ACTIVE_STATUS_LIST = get_plugin_config("netbox_dns", "zone_active_status")
38
+ RECORD_ACTIVE_STATUS_LIST = get_plugin_config("netbox_dns", "record_active_status")
39
+
37
40
 
38
41
  def min_ttl(*ttl_list):
39
42
  return min((ttl for ttl in ttl_list if ttl is not None), default=None)
@@ -102,14 +105,14 @@ class RecordManager(models.Manager.from_queryset(RestrictedQuerySet)):
102
105
  .annotate(
103
106
  active=ExpressionWrapper(
104
107
  Q(
105
- Q(zone__status__in=zone.Zone.ACTIVE_STATUS_LIST)
108
+ Q(zone__status__in=ZONE_ACTIVE_STATUS_LIST)
106
109
  & Q(
107
110
  Q(address_record__isnull=True)
108
111
  | Q(
109
- address_record__zone__status__in=zone.Zone.ACTIVE_STATUS_LIST
112
+ address_record__zone__status__in=ZONE_ACTIVE_STATUS_LIST
110
113
  )
111
114
  )
112
- & Q(status__in=Record.ACTIVE_STATUS_LIST)
115
+ & Q(status__in=RECORD_ACTIVE_STATUS_LIST)
113
116
  ),
114
117
  output_field=BooleanField(),
115
118
  )
@@ -118,8 +121,6 @@ class RecordManager(models.Manager.from_queryset(RestrictedQuerySet)):
118
121
 
119
122
 
120
123
  class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
121
- ACTIVE_STATUS_LIST = (RecordStatusChoices.STATUS_ACTIVE,)
122
-
123
124
  unique_ptr_qs = Q(
124
125
  Q(disable_ptr=False),
125
126
  Q(Q(type=RecordTypeChoices.A) | Q(type=RecordTypeChoices.AAAA)),
@@ -295,8 +296,8 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
295
296
  @property
296
297
  def is_active(self):
297
298
  return (
298
- self.status in Record.ACTIVE_STATUS_LIST
299
- and self.zone.status in zone.Zone.ACTIVE_STATUS_LIST
299
+ self.status in RECORD_ACTIVE_STATUS_LIST
300
+ and self.zone.status in ZONE_ACTIVE_STATUS_LIST
300
301
  )
301
302
 
302
303
  @property
@@ -597,7 +598,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
597
598
 
598
599
  def validate_value(self):
599
600
  try:
600
- validate_record_value(self.type, self.value)
601
+ validate_record_value(self)
601
602
  except ValidationError as exc:
602
603
  raise ValidationError({"value": exc})
603
604
 
@@ -616,7 +617,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
616
617
  name=self.name,
617
618
  type=self.type,
618
619
  value=self.value,
619
- status__in=Record.ACTIVE_STATUS_LIST,
620
+ status__in=RECORD_ACTIVE_STATUS_LIST,
620
621
  )
621
622
 
622
623
  if not self._state.adding:
@@ -653,7 +654,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
653
654
  name=self.name,
654
655
  type=self.type,
655
656
  value=self.value,
656
- status__in=Record.ACTIVE_STATUS_LIST,
657
+ status__in=RECORD_ACTIVE_STATUS_LIST,
657
658
  ipam_ip_address__isnull=True,
658
659
  )
659
660
 
@@ -137,7 +137,7 @@ class RecordTemplate(NetBoxModel):
137
137
 
138
138
  def validate_value(self):
139
139
  try:
140
- validate_record_value(self.type, self.value)
140
+ validate_record_value(self)
141
141
  except ValidationError as exc:
142
142
  raise ValidationError({"value": exc}) from None
143
143
 
@@ -53,6 +53,9 @@ __all__ = (
53
53
  "ZoneIndex",
54
54
  )
55
55
 
56
+ ZONE_ACTIVE_STATUS_LIST = get_plugin_config("netbox_dns", "zone_active_status")
57
+ RECORD_ACTIVE_STATUS_LIST = get_plugin_config("netbox_dns", "record_active_status")
58
+
56
59
 
57
60
  class ZoneManager(models.Manager.from_queryset(RestrictedQuerySet)):
58
61
  """
@@ -65,15 +68,13 @@ class ZoneManager(models.Manager.from_queryset(RestrictedQuerySet)):
65
68
  .get_queryset()
66
69
  .annotate(
67
70
  active=ExpressionWrapper(
68
- Q(status__in=Zone.ACTIVE_STATUS_LIST), output_field=BooleanField()
71
+ Q(status__in=ZONE_ACTIVE_STATUS_LIST), output_field=BooleanField()
69
72
  )
70
73
  )
71
74
  )
72
75
 
73
76
 
74
77
  class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
75
- ACTIVE_STATUS_LIST = (ZoneStatusChoices.STATUS_ACTIVE,)
76
-
77
78
  def __init__(self, *args, **kwargs):
78
79
  kwargs.pop("template", None)
79
80
 
@@ -299,11 +300,21 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
299
300
 
300
301
  @staticmethod
301
302
  def get_defaults():
303
+ default_fields = (
304
+ "zone_default_ttl",
305
+ "zone_soa_ttl",
306
+ "zone_soa_serial",
307
+ "zone_soa_refresh",
308
+ "zone_soa_retry",
309
+ "zone_soa_expire",
310
+ "zone_soa_minimum",
311
+ "zone_soa_rname",
312
+ )
313
+
302
314
  return {
303
315
  field[5:]: value
304
316
  for field, value in settings.PLUGINS_CONFIG.get("netbox_dns").items()
305
- if field.startswith("zone_")
306
- and field not in ("zone_soa_mname", "zone_nameservers")
317
+ if field in default_fields
307
318
  }
308
319
 
309
320
  @property
@@ -337,7 +348,7 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
337
348
 
338
349
  @property
339
350
  def is_active(self):
340
- return self.status in Zone.ACTIVE_STATUS_LIST
351
+ return self.status in ZONE_ACTIVE_STATUS_LIST
341
352
 
342
353
  @property
343
354
  def is_reverse_zone(self):
@@ -474,7 +485,7 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
474
485
  relative_name = name.relativize(parent).to_text()
475
486
  address_records = Record.objects.filter(
476
487
  Q(zone=ns_zone),
477
- Q(status__in=Record.ACTIVE_STATUS_LIST),
488
+ Q(status__in=RECORD_ACTIVE_STATUS_LIST),
478
489
  Q(Q(name=f"{_nameserver.name}.") | Q(name=relative_name)),
479
490
  Q(Q(type=RecordTypeChoices.A) | Q(type=RecordTypeChoices.AAAA)),
480
491
  )
@@ -63,7 +63,7 @@ def ipam_dnssync_ipaddress_post_clean(instance, **kwargs):
63
63
  {
64
64
  "dns_name": _(
65
65
  "Unique DNS records are enforced and there is already "
66
- "an active IP address {address} with DNS name {name}. Plesase choose "
66
+ "an active IP address {address} with DNS name {name}. Please choose "
67
67
  "a different name or disable record creation for this IP address."
68
68
  ).format(address=instance.address, name=instance.dns_name)
69
69
  }
@@ -1,5 +1,8 @@
1
- import dns
1
+ import re
2
+ import textwrap
3
+
2
4
  from dns import rdata, name as dns_name
5
+ from dns.exception import SyntaxError
3
6
 
4
7
  from django.core.exceptions import ValidationError
5
8
  from django.utils.translation import gettext as _
@@ -11,11 +14,12 @@ from netbox_dns.validators import (
11
14
  validate_generic_name,
12
15
  )
13
16
 
17
+ MAX_TXT_LENGTH = 255
14
18
 
15
19
  __all__ = ("validate_record_value",)
16
20
 
17
21
 
18
- def validate_record_value(record_type, value):
22
+ def validate_record_value(record):
19
23
  def _validate_idn(name):
20
24
  try:
21
25
  name.to_unicode()
@@ -26,16 +30,53 @@ def validate_record_value(record_type, value):
26
30
  )
27
31
  )
28
32
 
33
+ def _split_text_value(value):
34
+ # +
35
+ # Text values longer than 255 characters need to be broken up for TXT and
36
+ # SPF records.
37
+ # First, in case they had been split into separate strings, reassemble the
38
+ # original (long) value, then split it into chunks of a maximum length of
39
+ # 255 (preferably at word boundaries), and then build a sequence of partial
40
+ # strings enclosed in double quotes and separated by space.
41
+ #
42
+ # See https://datatracker.ietf.org/doc/html/rfc4408#section-3.1.3 for details.
43
+ # -
44
+ raw_value = "".join(re.findall(r'"([^"]+)"', value))
45
+ if not raw_value:
46
+ raw_value = value
47
+
48
+ return " ".join(
49
+ f'"{part}"'
50
+ for part in textwrap.wrap(raw_value, MAX_TXT_LENGTH, drop_whitespace=False)
51
+ )
52
+
53
+ if record.type in (RecordTypeChoices.TXT, RecordTypeChoices.SPF):
54
+ if not (record.value.isascii() and record.value.isprintable()):
55
+ raise ValidationError(
56
+ _(
57
+ "Record value {value} for a type {type} record is not a printable ASCII string."
58
+ ).format(value=record.value, type=record.type)
59
+ )
60
+
61
+ if len(record.value) <= MAX_TXT_LENGTH:
62
+ return
63
+
64
+ try:
65
+ rr = rdata.from_text(RecordClassChoices.IN, record.type, record.value)
66
+ except SyntaxError as exc:
67
+ if str(exc) == "string too long":
68
+ record.value = _split_text_value(record.value)
69
+
29
70
  try:
30
- rr = rdata.from_text(RecordClassChoices.IN, record_type, value)
31
- except dns.exception.SyntaxError as exc:
71
+ rr = rdata.from_text(RecordClassChoices.IN, record.type, record.value)
72
+ except SyntaxError as exc:
32
73
  raise ValidationError(
33
74
  _(
34
75
  "Record value {value} is not a valid value for a {type} record: {error}."
35
- ).format(value=value, type=record_type, error=exc)
76
+ ).format(value=record.value, type=record.type, error=exc)
36
77
  )
37
78
 
38
- match record_type:
79
+ match record.type:
39
80
  case RecordTypeChoices.CNAME:
40
81
  _validate_idn(rr.target)
41
82
  validate_domain_name(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-plugin-dns
3
- Version: 1.1.3
3
+ Version: 1.1.4
4
4
  Summary: NetBox DNS is a NetBox plugin for managing DNS data.
5
5
  Author-email: Peter Eckel <pete@netbox-dns.org>
6
6
  Project-URL: Homepage, https://github.com/peteeckel/netbox-plugin-dns
@@ -32,7 +32,7 @@ The NetBox DNS plugin enables NetBox to manage operational DNS data such as name
32
32
 
33
33
  > [!WARNING]
34
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.
35
+ > This affects multiple aspects of the branching functionality, and currently there is no workaround. Do not try to use NetBox Branching together with NetBox DNS until these issues are resolved.
36
36
  > This warning will be updated as soon as the situation is resolved.
37
37
 
38
38
  ## Objectives
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "netbox-plugin-dns"
3
- version = "1.1.3"
3
+ version = "1.1.4"
4
4
  description = "NetBox DNS is a NetBox plugin for managing DNS data."
5
5
  authors = [
6
6
  {name="Peter Eckel", email="pete@netbox-dns.org"},