netbox-plugin-dns 1.0.7__tar.gz → 1.1.0b1__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 (151) hide show
  1. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/PKG-INFO +2 -2
  2. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/__init__.py +21 -5
  3. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/nested_serializers.py +16 -17
  4. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/serializers.py +1 -0
  5. netbox_plugin_dns-1.1.0b1/netbox_dns/api/serializers_/prefix.py +18 -0
  6. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/serializers_/record.py +0 -1
  7. netbox_plugin_dns-1.1.0b1/netbox_dns/api/serializers_/view.py +69 -0
  8. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/urls.py +3 -0
  9. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/views.py +36 -0
  10. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/fields/__init__.py +1 -0
  11. netbox_plugin_dns-1.1.0b1/netbox_dns/fields/ipam.py +18 -0
  12. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/filtersets/record.py +1 -1
  13. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/filtersets/view.py +16 -0
  14. netbox_plugin_dns-1.1.0b1/netbox_dns/forms/view.py +202 -0
  15. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/forms/zone.py +0 -8
  16. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/graphql/schema.py +40 -16
  17. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/graphql/types.py +1 -0
  18. netbox_plugin_dns-1.1.0b1/netbox_dns/management/commands/setup_autodns.py +120 -0
  19. netbox_plugin_dns-1.1.0b1/netbox_dns/migrations/0007_view_prefixes.py +18 -0
  20. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/models/__init__.py +0 -2
  21. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/models/contact.py +3 -9
  22. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/models/nameserver.py +3 -8
  23. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/models/record.py +71 -17
  24. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/models/record_template.py +1 -4
  25. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/models/registrar.py +1 -7
  26. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/models/view.py +7 -9
  27. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/models/zone.py +28 -29
  28. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/models/zone_template.py +5 -8
  29. netbox_plugin_dns-1.1.0b1/netbox_dns/signals/ipam_autodns.py +138 -0
  30. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/tables/contact.py +1 -0
  31. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/tables/nameserver.py +7 -1
  32. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/tables/record.py +30 -10
  33. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/tables/record_template.py +17 -0
  34. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/tables/registrar.py +2 -0
  35. netbox_plugin_dns-1.1.0b1/netbox_dns/tables/view.py +53 -0
  36. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/tables/zone.py +15 -0
  37. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/tables/zone_template.py +16 -2
  38. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/template_content.py +28 -39
  39. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/record.html +6 -6
  40. netbox_plugin_dns-1.1.0b1/netbox_dns/templates/netbox_dns/view/related.html +17 -0
  41. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/view.html +29 -0
  42. netbox_plugin_dns-1.1.0b1/netbox_dns/urls/contact.py +51 -0
  43. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/urls/nameserver.py +38 -14
  44. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/urls/record.py +19 -7
  45. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/urls/record_template.py +27 -18
  46. netbox_plugin_dns-1.1.0b1/netbox_dns/urls/registrar.py +63 -0
  47. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/urls/view.py +22 -8
  48. netbox_plugin_dns-1.1.0b1/netbox_dns/urls/zone.py +63 -0
  49. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/urls/zone_template.py +26 -16
  50. netbox_plugin_dns-1.1.0b1/netbox_dns/utilities/__init__.py +2 -0
  51. netbox_plugin_dns-1.0.7/netbox_dns/utilities/__init__.py → netbox_plugin_dns-1.1.0b1/netbox_dns/utilities/conversions.py +9 -0
  52. netbox_plugin_dns-1.1.0b1/netbox_dns/utilities/ipam_autodns.py +205 -0
  53. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/validators/dns_name.py +0 -9
  54. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/views/contact.py +1 -0
  55. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/views/nameserver.py +3 -7
  56. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/views/record.py +2 -9
  57. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/views/registrar.py +1 -0
  58. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/views/view.py +1 -6
  59. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/views/zone.py +6 -7
  60. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/pyproject.toml +2 -2
  61. netbox_plugin_dns-1.0.7/netbox_dns/api/serializers_/view.py +0 -37
  62. netbox_plugin_dns-1.0.7/netbox_dns/forms/view.py +0 -90
  63. netbox_plugin_dns-1.0.7/netbox_dns/management/commands/setup_coupling.py +0 -109
  64. netbox_plugin_dns-1.0.7/netbox_dns/migrations/0007_alter_ordering_options.py +0 -25
  65. netbox_plugin_dns-1.0.7/netbox_dns/signals/ipam_coupling.py +0 -168
  66. netbox_plugin_dns-1.0.7/netbox_dns/tables/view.py +0 -24
  67. netbox_plugin_dns-1.0.7/netbox_dns/templates/netbox_dns/related_dns_objects.html +0 -21
  68. netbox_plugin_dns-1.0.7/netbox_dns/urls/contact.py +0 -29
  69. netbox_plugin_dns-1.0.7/netbox_dns/urls/registrar.py +0 -39
  70. netbox_plugin_dns-1.0.7/netbox_dns/urls/zone.py +0 -25
  71. netbox_plugin_dns-1.0.7/netbox_dns/utilities/ipam_coupling.py +0 -112
  72. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/LICENSE +0 -0
  73. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/README.md +0 -0
  74. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/serializers_/__init__.py +0 -0
  75. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/serializers_/contact.py +0 -0
  76. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/serializers_/nameserver.py +0 -0
  77. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/serializers_/record_template.py +0 -0
  78. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/serializers_/registrar.py +0 -0
  79. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/serializers_/zone.py +0 -0
  80. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/api/serializers_/zone_template.py +0 -0
  81. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/apps.py +0 -0
  82. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/choices/__init__.py +0 -0
  83. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/choices/record.py +0 -0
  84. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/choices/zone.py +0 -0
  85. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/fields/address.py +0 -0
  86. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/fields/network.py +0 -0
  87. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/fields/rfc2317.py +0 -0
  88. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/filtersets/__init__.py +0 -0
  89. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/filtersets/contact.py +0 -0
  90. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/filtersets/nameserver.py +0 -0
  91. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/filtersets/record_template.py +0 -0
  92. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/filtersets/registrar.py +0 -0
  93. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/filtersets/zone.py +0 -0
  94. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/filtersets/zone_template.py +0 -0
  95. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/forms/__init__.py +0 -0
  96. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/forms/contact.py +0 -0
  97. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/forms/nameserver.py +0 -0
  98. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/forms/record.py +0 -0
  99. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/forms/record_template.py +0 -0
  100. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/forms/registrar.py +0 -0
  101. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/forms/zone_template.py +0 -0
  102. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/graphql/__init__.py +0 -0
  103. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/graphql/filters.py +0 -0
  104. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/management/commands/cleanup_database.py +0 -0
  105. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/management/commands/cleanup_rrset_ttl.py +0 -0
  106. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/management/commands/update_soa.py +0 -0
  107. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
  108. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +0 -0
  109. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0002_contact_description_registrar_description.py +0 -0
  110. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0003_default_view.py +0 -0
  111. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0004_create_and_assign_default_view.py +0 -0
  112. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0005_alter_zone_view_not_null.py +0 -0
  113. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0006_templating.py +0 -0
  114. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
  115. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
  116. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0022_search.py +0 -0
  117. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
  118. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0024_tenancy.py +0 -0
  119. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
  120. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0026_domain_registration.py +0 -0
  121. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
  122. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
  123. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/0029_record_fqdn.py +0 -0
  124. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/migrations/__init__.py +0 -0
  125. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/mixins/__init__.py +0 -0
  126. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/mixins/object_modification.py +0 -0
  127. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/navigation.py +0 -0
  128. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/signals/__init__.py +0 -0
  129. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/tables/__init__.py +0 -0
  130. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/contact.html +0 -0
  131. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/nameserver.html +0 -0
  132. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
  133. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
  134. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/recordtemplate.html +0 -0
  135. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/registrar.html +0 -0
  136. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
  137. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
  138. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/zone/child_zone.html +0 -0
  139. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
  140. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
  141. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
  142. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
  143. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/zone.html +0 -0
  144. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/templates/netbox_dns/zonetemplate.html +0 -0
  145. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/urls/__init__.py +0 -0
  146. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/validators/__init__.py +0 -0
  147. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/validators/dns_value.py +0 -0
  148. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/validators/rfc2317.py +0 -0
  149. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/views/__init__.py +0 -0
  150. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/views/record_template.py +1 -1
  151. {netbox_plugin_dns-1.0.7 → netbox_plugin_dns-1.1.0b1}/netbox_dns/views/zone_template.py +2 -2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-plugin-dns
3
- Version: 1.0.7
3
+ Version: 1.1.0b1
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
@@ -8,7 +8,7 @@ Keywords: netbox,netbox-plugin,dns
8
8
  Author: Peter Eckel
9
9
  Author-email: pete@netbox-dns.org
10
10
  Requires-Python: >=3.10,<4.0
11
- Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Development Status :: 4 - Beta
12
12
  Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Programming Language :: Python :: 3.10
@@ -1,13 +1,18 @@
1
+ from django.conf import settings
2
+
1
3
  from netbox.plugins import PluginConfig
4
+ from ipam.choices import IPAddressStatusChoices
5
+
6
+ from netbox_dns.choices import RecordTypeChoices
2
7
 
3
- __version__ = "1.0.7"
8
+ __version__ = "1.1.0-beta1"
4
9
 
5
10
 
6
11
  class DNSConfig(PluginConfig):
7
12
  name = "netbox_dns"
8
13
  verbose_name = "NetBox DNS"
9
14
  description = "NetBox plugin for DNS data"
10
- min_version = "4.0.0"
15
+ min_version = "4.1.0-beta1"
11
16
  version = __version__
12
17
  author = "Peter Eckel"
13
18
  author_email = "pete@netbox-dns.org"
@@ -20,13 +25,18 @@ class DNSConfig(PluginConfig):
20
25
  "zone_soa_retry": 7200,
21
26
  "zone_soa_expire": 2419200,
22
27
  "zone_soa_minimum": 3600,
23
- "feature_ipam_coupling": False,
28
+ "autodns_disabled": False,
29
+ "autodns_ipaddress_active_status": [
30
+ IPAddressStatusChoices.STATUS_ACTIVE,
31
+ IPAddressStatusChoices.STATUS_DHCP,
32
+ IPAddressStatusChoices.STATUS_SLAAC,
33
+ ],
24
34
  "tolerate_characters_in_zone_labels": "",
25
35
  "tolerate_underscores_in_labels": False,
26
36
  "tolerate_underscores_in_hostnames": False, # Deprecated, will be removed in 1.2.0
27
37
  "tolerate_leading_underscore_types": [
28
- "TXT",
29
- "SRV",
38
+ RecordTypeChoices.TXT,
39
+ RecordTypeChoices.SRV,
30
40
  ],
31
41
  "tolerate_non_rfc1035_types": [],
32
42
  "enable_root_zones": False,
@@ -37,6 +47,12 @@ class DNSConfig(PluginConfig):
37
47
  }
38
48
  base_url = "netbox-dns"
39
49
 
50
+ def ready(self):
51
+ super().ready()
52
+
53
+ if not settings.PLUGINS_CONFIG["netbox_dns"].get("autodns_disabled"):
54
+ from netbox_dns.signals import ipam_autodns
55
+
40
56
 
41
57
  #
42
58
  # Initialize plugin config
@@ -59,22 +59,6 @@ class NestedZoneSerializer(WritableNestedSerializer):
59
59
  ]
60
60
 
61
61
 
62
- class NestedZoneTemplateSerializer(WritableNestedSerializer):
63
- url = serializers.HyperlinkedIdentityField(
64
- view_name="plugins-api:netbox_dns-api:zonetemplate-detail"
65
- )
66
-
67
- class Meta:
68
- model = ZoneTemplate
69
- fields = (
70
- "id",
71
- "url",
72
- "name",
73
- "display",
74
- "description",
75
- )
76
-
77
-
78
62
  class NestedRecordSerializer(WritableNestedSerializer):
79
63
  url = serializers.HyperlinkedIdentityField(
80
64
  view_name="plugins-api:netbox_dns-api:record-detail"
@@ -102,7 +86,6 @@ class NestedRecordSerializer(WritableNestedSerializer):
102
86
  "status",
103
87
  "ttl",
104
88
  "zone",
105
- "managed",
106
89
  "active",
107
90
  ]
108
91
 
@@ -126,3 +109,19 @@ class NestedRecordTemplateSerializer(WritableNestedSerializer):
126
109
  "ttl",
127
110
  "description",
128
111
  )
112
+
113
+
114
+ class NestedZoneTemplateSerializer(WritableNestedSerializer):
115
+ url = serializers.HyperlinkedIdentityField(
116
+ view_name="plugins-api:netbox_dns-api:zonetemplate-detail"
117
+ )
118
+
119
+ class Meta:
120
+ model = ZoneTemplate
121
+ fields = (
122
+ "id",
123
+ "url",
124
+ "name",
125
+ "display",
126
+ "description",
127
+ )
@@ -6,5 +6,6 @@ from .serializers_.view import *
6
6
  from .serializers_.zone import *
7
7
  from .serializers_.zone_template import *
8
8
  from .serializers_.record_template import *
9
+ from .serializers_.prefix import *
9
10
 
10
11
  from .nested_serializers import *
@@ -0,0 +1,18 @@
1
+ from rest_framework.serializers import HyperlinkedIdentityField
2
+
3
+ from ipam.api.serializers import PrefixSerializer as IPAMPrefixSerializer
4
+
5
+
6
+ __all__ = ("PrefixSerializer",)
7
+
8
+
9
+ class PrefixSerializer(IPAMPrefixSerializer):
10
+ url = HyperlinkedIdentityField(view_name="plugins-api:netbox_dns-api:prefix-detail")
11
+
12
+ def to_representation(self, instance):
13
+ representation = super().to_representation(instance)
14
+
15
+ if instance.vrf is not None:
16
+ representation["display"] += f" [{instance.vrf.name}]"
17
+
18
+ return representation
@@ -87,6 +87,5 @@ class RecordSerializer(NetBoxModelSerializer):
87
87
  "status",
88
88
  "ttl",
89
89
  "description",
90
- "managed",
91
90
  "active",
92
91
  )
@@ -0,0 +1,69 @@
1
+ from rest_framework import serializers
2
+
3
+ from netbox.api.serializers import NetBoxModelSerializer
4
+ from tenancy.api.serializers import TenantSerializer
5
+ from ipam.api.serializers import PrefixSerializer
6
+
7
+ from netbox_dns.models import View
8
+
9
+
10
+ __all__ = ("ViewSerializer",)
11
+
12
+
13
+ class ViewSerializer(NetBoxModelSerializer):
14
+ url = serializers.HyperlinkedIdentityField(
15
+ view_name="plugins-api:netbox_dns-api:view-detail"
16
+ )
17
+ default_view = serializers.BooleanField(
18
+ read_only=True,
19
+ )
20
+ prefixes = PrefixSerializer(
21
+ many=True,
22
+ nested=True,
23
+ read_only=False,
24
+ required=False,
25
+ help_text="IPAM Prefixes assigned to the View",
26
+ )
27
+ tenant = TenantSerializer(
28
+ nested=True,
29
+ required=False,
30
+ allow_null=True,
31
+ )
32
+
33
+ def create(self, validated_data):
34
+ prefixes = validated_data.pop("prefixes", None)
35
+
36
+ view = super().create(validated_data)
37
+
38
+ if prefixes is not None:
39
+ view.prefixes.set(prefixes)
40
+
41
+ return view
42
+
43
+ def update(self, instance, validated_data):
44
+ prefixes = validated_data.pop("prefixes", None)
45
+
46
+ view = super().update(instance, validated_data)
47
+
48
+ if prefixes is not None:
49
+ view.prefixes.set(prefixes)
50
+
51
+ return view
52
+
53
+ class Meta:
54
+ model = View
55
+ fields = (
56
+ "id",
57
+ "url",
58
+ "display",
59
+ "name",
60
+ "default_view",
61
+ "tags",
62
+ "description",
63
+ "created",
64
+ "last_updated",
65
+ "custom_fields",
66
+ "tenant",
67
+ "prefixes",
68
+ )
69
+ brief_fields = ("id", "url", "display", "name", "default_view", "description")
@@ -10,6 +10,7 @@ from netbox_dns.api.views import (
10
10
  ContactViewSet,
11
11
  ZoneTemplateViewSet,
12
12
  RecordTemplateViewSet,
13
+ PrefixViewSet,
13
14
  )
14
15
 
15
16
  router = NetBoxRouter()
@@ -24,4 +25,6 @@ router.register("contacts", ContactViewSet)
24
25
  router.register("zonetemplates", ZoneTemplateViewSet)
25
26
  router.register("recordtemplates", RecordTemplateViewSet)
26
27
 
28
+ router.register("prefixes", PrefixViewSet)
29
+
27
30
  urlpatterns = router.urls
@@ -1,6 +1,10 @@
1
1
  from rest_framework import serializers
2
+ from rest_framework.decorators import action
3
+ from rest_framework.response import Response
2
4
  from rest_framework.routers import APIRootView
3
5
 
6
+ from ipam.models import Prefix
7
+
4
8
  from netbox.api.viewsets import NetBoxModelViewSet
5
9
 
6
10
  from netbox_dns.api.serializers import (
@@ -12,6 +16,7 @@ from netbox_dns.api.serializers import (
12
16
  ContactSerializer,
13
17
  ZoneTemplateSerializer,
14
18
  RecordTemplateSerializer,
19
+ PrefixSerializer,
15
20
  )
16
21
  from netbox_dns.filtersets import (
17
22
  ViewFilterSet,
@@ -45,6 +50,12 @@ class ViewViewSet(NetBoxModelViewSet):
45
50
  serializer_class = ViewSerializer
46
51
  filterset_class = ViewFilterSet
47
52
 
53
+ @action(detail=True, methods=["get"])
54
+ def views(self, request, pk=None):
55
+ views = View.objects.filter(zone=pk)
56
+ serializer = ViewSerializer(views, many=True, context={"request": request})
57
+ return Response(serializer.data)
58
+
48
59
 
49
60
  class ZoneViewSet(NetBoxModelViewSet):
50
61
  queryset = Zone.objects.prefetch_related(
@@ -58,12 +69,32 @@ class ZoneViewSet(NetBoxModelViewSet):
58
69
  serializer_class = ZoneSerializer
59
70
  filterset_class = ZoneFilterSet
60
71
 
72
+ @action(detail=True, methods=["get"])
73
+ def records(self, request, pk=None):
74
+ records = Record.objects.filter(zone=pk)
75
+ serializer = RecordSerializer(records, many=True, context={"request": request})
76
+ return Response(serializer.data)
77
+
78
+ @action(detail=True, methods=["get"])
79
+ def nameservers(self, request, pk=None):
80
+ nameservers = NameServer.objects.filter(zones__id=pk)
81
+ serializer = NameServerSerializer(
82
+ nameservers, many=True, context={"request": request}
83
+ )
84
+ return Response(serializer.data)
85
+
61
86
 
62
87
  class NameServerViewSet(NetBoxModelViewSet):
63
88
  queryset = NameServer.objects.prefetch_related("zones", "tenant")
64
89
  serializer_class = NameServerSerializer
65
90
  filterset_class = NameServerFilterSet
66
91
 
92
+ @action(detail=True, methods=["get"])
93
+ def zones(self, request, pk=None):
94
+ zones = Zone.objects.filter(nameservers__id=pk)
95
+ serializer = ZoneSerializer(zones, many=True, context={"request": request})
96
+ return Response(serializer.data)
97
+
67
98
 
68
99
  class RecordViewSet(NetBoxModelViewSet):
69
100
  queryset = Record.objects.all().prefetch_related("zone", "zone__view", "tenant")
@@ -124,3 +155,8 @@ class RecordTemplateViewSet(NetBoxModelViewSet):
124
155
  queryset = RecordTemplate.objects.all()
125
156
  serializer_class = RecordTemplateSerializer
126
157
  filterset_class = RecordTemplateFilterSet
158
+
159
+
160
+ class PrefixViewSet(NetBoxModelViewSet):
161
+ queryset = Prefix.objects.all()
162
+ serializer_class = PrefixSerializer
@@ -1,3 +1,4 @@
1
1
  from .network import *
2
2
  from .address import *
3
3
  from .rfc2317 import *
4
+ from .ipam import *
@@ -0,0 +1,18 @@
1
+ from utilities.forms.fields import DynamicModelMultipleChoiceField
2
+ from utilities.forms.widgets import APISelectMultiple
3
+
4
+
5
+ __all__ = ("PrefixDynamicModelMultipleChoiceField",)
6
+
7
+
8
+ class PrefixDynamicModelMultipleChoiceField(DynamicModelMultipleChoiceField):
9
+ def __init__(self, *args, **kwargs):
10
+ super().__init__(*args, **kwargs)
11
+
12
+ widget = APISelectMultiple(api_url="/api/plugins/netbox-dns/prefixes")
13
+
14
+ def label_from_instance(self, obj):
15
+ if obj.vrf:
16
+ return f"{str(obj.prefix)} [{obj.vrf.name}]"
17
+
18
+ return str(obj.prefix)
@@ -121,7 +121,7 @@ class RecordFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
121
121
  if not value.strip():
122
122
  return queryset
123
123
  qs_filter = (
124
- Q(fqdn__icontains=value)
124
+ Q(name__icontains=value)
125
125
  | Q(value__icontains=value)
126
126
  | Q(zone__name__icontains=value)
127
127
  )
@@ -1,7 +1,10 @@
1
+ import django_filters
2
+
1
3
  from django.db.models import Q
2
4
 
3
5
  from netbox.filtersets import NetBoxModelFilterSet
4
6
  from tenancy.filtersets import TenancyFilterSet
7
+ from ipam.models import Prefix
5
8
 
6
9
  from netbox_dns.models import View
7
10
 
@@ -10,6 +13,19 @@ __all__ = ("ViewFilterSet",)
10
13
 
11
14
 
12
15
  class ViewFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
16
+ prefix_id = django_filters.ModelMultipleChoiceFilter(
17
+ queryset=Prefix.objects.all(),
18
+ field_name="prefixes",
19
+ to_field_name="id",
20
+ label="Prefixes ID",
21
+ )
22
+ prefix = django_filters.ModelMultipleChoiceFilter(
23
+ queryset=Prefix.objects.all(),
24
+ field_name="prefixes__prefix",
25
+ to_field_name="prefix",
26
+ label="Prefix",
27
+ )
28
+
13
29
  class Meta:
14
30
  model = View
15
31
  fields = ("id", "name", "default_view", "description")
@@ -0,0 +1,202 @@
1
+ from django import forms
2
+ from django.conf import settings
3
+ from django.core.exceptions import ValidationError
4
+ from django.db.models import Q, Count
5
+
6
+ from netbox.forms import (
7
+ NetBoxModelBulkEditForm,
8
+ NetBoxModelFilterSetForm,
9
+ NetBoxModelImportForm,
10
+ NetBoxModelForm,
11
+ )
12
+ from utilities.forms.fields import (
13
+ TagFilterField,
14
+ CSVModelChoiceField,
15
+ CSVModelMultipleChoiceField,
16
+ DynamicModelChoiceField,
17
+ DynamicModelMultipleChoiceField,
18
+ )
19
+ from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES
20
+ from utilities.forms.rendering import FieldSet
21
+ from tenancy.models import Tenant
22
+ from tenancy.forms import TenancyForm, TenancyFilterForm
23
+ from ipam.models import Prefix
24
+
25
+ from netbox_dns.models import View
26
+ from netbox_dns.fields import PrefixDynamicModelMultipleChoiceField
27
+ from netbox_dns.utilities import (
28
+ get_ip_addresses_by_prefix,
29
+ update_dns_records,
30
+ get_views_by_prefix,
31
+ )
32
+
33
+
34
+ __all__ = (
35
+ "ViewForm",
36
+ "ViewFilterForm",
37
+ "ViewImportForm",
38
+ "ViewBulkEditForm",
39
+ )
40
+
41
+
42
+ class ViewPrefixUpdateMixin:
43
+ def clean(self, *args, **kwargs):
44
+ super().clean(*args, **kwargs)
45
+
46
+ if self.instance.pk is None or "prefixes" not in self.changed_data:
47
+ return
48
+
49
+ prefixes = self.cleaned_data.get("prefixes")
50
+ old_prefixes = View.objects.get(pk=self.instance.pk).prefixes.all()
51
+
52
+ for prefix in prefixes.difference(old_prefixes):
53
+ for ip_address in get_ip_addresses_by_prefix(prefix, check_view=False):
54
+ try:
55
+ update_dns_records(ip_address, commit=False, view=self.instance)
56
+ except ValidationError as exc:
57
+ self.add_error("prefixes", exc.messages)
58
+
59
+ # +
60
+ # Determine the prefixes that, when removed from the view, have no direct view
61
+ # assignment left. These prefixes will potentially inherit from a different view,
62
+ # which means that they have to be validated against different zones.
63
+ # -
64
+ check_prefixes = set(
65
+ old_prefixes.annotate(view_count=Count("netbox_dns_views")).filter(
66
+ Q(view_count=1, netbox_dns_views=self.instance)
67
+ | Q(netbox_dns_views__isnull=True)
68
+ )
69
+ ) - set(prefixes)
70
+
71
+ for check_prefix in check_prefixes:
72
+ # +
73
+ # Check whether the prefix will get a new view by inheritance from its
74
+ # parent. If that's the case, the IP addresses need to be checked.
75
+ # -
76
+ if (parent := check_prefix.get_parents().last()) is None:
77
+ return
78
+
79
+ for view in get_views_by_prefix(parent):
80
+ if view == self.instance:
81
+ continue
82
+
83
+ for ip_address in get_ip_addresses_by_prefix(
84
+ check_prefix, check_view=False
85
+ ):
86
+ try:
87
+ update_dns_records(ip_address, commit=False, view=view)
88
+ except ValidationError as exc:
89
+ self.add_error("prefixes", exc.messages)
90
+
91
+
92
+ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
93
+ def __init__(self, *args, **kwargs):
94
+ super().__init__(*args, **kwargs)
95
+
96
+ if settings.PLUGINS_CONFIG["netbox_dns"].get("autodns_disabled"):
97
+ del self.fields["prefixes"]
98
+
99
+ prefixes = PrefixDynamicModelMultipleChoiceField(
100
+ queryset=Prefix.objects.all(),
101
+ required=False,
102
+ label="IPAM Prefixes",
103
+ context={
104
+ "depth": None,
105
+ },
106
+ )
107
+
108
+ fieldsets = (
109
+ FieldSet("name", "default_view", "description", "tags", name="View"),
110
+ FieldSet("prefixes"),
111
+ FieldSet("tenant_group", "tenant", name="Tenancy"),
112
+ )
113
+
114
+ class Meta:
115
+ model = View
116
+ fields = (
117
+ "name",
118
+ "default_view",
119
+ "description",
120
+ "tags",
121
+ "tenant",
122
+ "prefixes",
123
+ )
124
+
125
+
126
+ class ViewFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
127
+ def __init__(self, *args, **kwargs):
128
+ super().__init__(*args, **kwargs)
129
+
130
+ if settings.PLUGINS_CONFIG["netbox_dns"].get("autodns_disabled"):
131
+ del self.fields["prefix_id"]
132
+
133
+ model = View
134
+ fieldsets = (
135
+ FieldSet("q", "filter_id", "tag"),
136
+ FieldSet("name", "default_view", "description", name="Attributes"),
137
+ FieldSet("prefix_id"),
138
+ FieldSet("tenant_group_id", "tenant_id", name="Tenancy"),
139
+ )
140
+
141
+ name = forms.CharField(
142
+ required=False,
143
+ )
144
+ default_view = forms.NullBooleanField(
145
+ required=False,
146
+ widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
147
+ )
148
+ description = forms.CharField(
149
+ required=False,
150
+ )
151
+ prefix_id = PrefixDynamicModelMultipleChoiceField(
152
+ queryset=Prefix.objects.all(),
153
+ required=False,
154
+ label="Prefix",
155
+ context={
156
+ "depth": None,
157
+ },
158
+ )
159
+ tag = TagFilterField(View)
160
+
161
+
162
+ class ViewImportForm(ViewPrefixUpdateMixin, NetBoxModelImportForm):
163
+ def __init__(self, *args, **kwargs):
164
+ super().__init__(*args, **kwargs)
165
+
166
+ if settings.PLUGINS_CONFIG["netbox_dns"].get("autodns_disabled"):
167
+ del self.fields["prefixes"]
168
+
169
+ prefixes = CSVModelMultipleChoiceField(
170
+ queryset=Prefix.objects.all(),
171
+ to_field_name="id",
172
+ required=False,
173
+ help_text="Prefix IDs assigned to the view",
174
+ )
175
+ tenant = CSVModelChoiceField(
176
+ queryset=Tenant.objects.all(),
177
+ to_field_name="name",
178
+ required=False,
179
+ help_text="Assigned tenant",
180
+ )
181
+
182
+ class Meta:
183
+ model = View
184
+ fields = ("name", "description", "prefixes", "tenant", "tags")
185
+
186
+
187
+ class ViewBulkEditForm(NetBoxModelBulkEditForm):
188
+ model = View
189
+
190
+ description = forms.CharField(max_length=200, required=False)
191
+ tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False)
192
+
193
+ fieldsets = (
194
+ FieldSet(
195
+ "name",
196
+ "description",
197
+ name="Attributes",
198
+ ),
199
+ FieldSet("tenant", name="Tenancy"),
200
+ )
201
+
202
+ nullable_fields = ("description", "tenant")
@@ -81,14 +81,6 @@ class ZoneTemplateUpdateMixin:
81
81
  else:
82
82
  zone_data = self.cleaned_data.copy()
83
83
 
84
- custom_fields = dict()
85
- for key, value in zone_data.copy().items():
86
- if key.startswith("cf_"):
87
- custom_fields[key[3:]] = value
88
- zone_data.pop(key)
89
- if custom_fields:
90
- zone_data["custom_field_data"] = custom_fields
91
-
92
84
  zone_data.pop("template", None)
93
85
  zone_data.pop("tenant_group", None)
94
86
  zone_data.pop("_init_time", None)