netbox-plugin-dns 1.1.1__tar.gz → 1.1.2__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 (154) hide show
  1. {netbox_plugin_dns-1.1.1/netbox_plugin_dns.egg-info → netbox_plugin_dns-1.1.2}/PKG-INFO +1 -1
  2. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/__init__.py +3 -2
  3. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/view.py +1 -0
  4. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/forms/view.py +29 -10
  5. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/graphql/schema.py +0 -10
  6. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/graphql/types.py +1 -0
  7. netbox_plugin_dns-1.1.2/netbox_dns/migrations/0010_view_ip_address_filter.py +18 -0
  8. netbox_plugin_dns-1.1.2/netbox_dns/mixins/object_modification.py +53 -0
  9. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/models/record.py +32 -10
  10. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/models/view.py +40 -0
  11. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/models/zone.py +12 -7
  12. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/signals/ipam_dnssync.py +4 -4
  13. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/view.py +1 -1
  14. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/view.html +16 -0
  15. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/utilities/ipam_dnssync.py +57 -25
  16. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2/netbox_plugin_dns.egg-info}/PKG-INFO +1 -1
  17. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_plugin_dns.egg-info/SOURCES.txt +1 -0
  18. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/pyproject.toml +1 -1
  19. netbox_plugin_dns-1.1.1/netbox_dns/mixins/object_modification.py +0 -31
  20. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/LICENSE +0 -0
  21. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/README.md +0 -0
  22. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/nested_serializers.py +0 -0
  23. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers.py +0 -0
  24. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/__init__.py +0 -0
  25. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/nameserver.py +0 -0
  26. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/prefix.py +0 -0
  27. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/record.py +0 -0
  28. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/record_template.py +0 -0
  29. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/registrar.py +0 -0
  30. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/registration_contact.py +0 -0
  31. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/zone.py +0 -0
  32. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/serializers_/zone_template.py +0 -0
  33. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/urls.py +0 -0
  34. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/api/views.py +0 -0
  35. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/apps.py +0 -0
  36. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/choices/__init__.py +0 -0
  37. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/choices/record.py +0 -0
  38. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/choices/zone.py +0 -0
  39. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/fields/__init__.py +0 -0
  40. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/fields/address.py +0 -0
  41. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/fields/ipam.py +0 -0
  42. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/fields/network.py +0 -0
  43. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/fields/rfc2317.py +0 -0
  44. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/filtersets/__init__.py +0 -0
  45. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/filtersets/nameserver.py +0 -0
  46. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/filtersets/record.py +0 -0
  47. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/filtersets/record_template.py +0 -0
  48. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/filtersets/registrar.py +0 -0
  49. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/filtersets/registration_contact.py +0 -0
  50. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/filtersets/view.py +0 -0
  51. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/filtersets/zone.py +0 -0
  52. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/filtersets/zone_template.py +0 -0
  53. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/forms/__init__.py +0 -0
  54. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/forms/nameserver.py +0 -0
  55. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/forms/record.py +0 -0
  56. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/forms/record_template.py +0 -0
  57. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/forms/registrar.py +0 -0
  58. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/forms/registration_contact.py +0 -0
  59. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/forms/zone.py +0 -0
  60. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/forms/zone_template.py +0 -0
  61. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/graphql/__init__.py +0 -0
  62. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/graphql/filters.py +0 -0
  63. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/management/commands/cleanup_database.py +0 -0
  64. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/management/commands/cleanup_rrset_ttl.py +0 -0
  65. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/management/commands/rebuild_dnssync.py +0 -0
  66. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/management/commands/setup_dnssync.py +0 -0
  67. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/management/commands/update_soa.py +0 -0
  68. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
  69. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +0 -0
  70. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0002_contact_description_registrar_description.py +0 -0
  71. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0003_default_view.py +0 -0
  72. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0004_create_and_assign_default_view.py +0 -0
  73. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0005_alter_zone_view_not_null.py +0 -0
  74. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0006_templating.py +0 -0
  75. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0007_alter_ordering_options.py +0 -0
  76. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0008_view_prefixes.py +0 -0
  77. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0009_rename_contact_registrationcontact.py +0 -0
  78. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
  79. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
  80. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0022_search.py +0 -0
  81. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
  82. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0024_tenancy.py +0 -0
  83. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
  84. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0026_domain_registration.py +0 -0
  85. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
  86. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
  87. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/0029_record_fqdn.py +0 -0
  88. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/migrations/__init__.py +0 -0
  89. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/mixins/__init__.py +0 -0
  90. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/models/__init__.py +0 -0
  91. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/models/nameserver.py +0 -0
  92. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/models/record_template.py +0 -0
  93. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/models/registrar.py +0 -0
  94. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/models/registration_contact.py +0 -0
  95. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/models/zone_template.py +0 -0
  96. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/navigation.py +0 -0
  97. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/signals/__init__.py +0 -0
  98. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/__init__.py +0 -0
  99. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/ipam_dnssync.py +0 -0
  100. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/nameserver.py +0 -0
  101. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/record.py +0 -0
  102. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/record_template.py +0 -0
  103. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/registrar.py +0 -0
  104. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/registration_contact.py +0 -0
  105. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/zone.py +0 -0
  106. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/tables/zone_template.py +0 -0
  107. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/template_content.py +0 -0
  108. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/nameserver.html +0 -0
  109. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
  110. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
  111. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/record.html +0 -0
  112. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/recordtemplate.html +0 -0
  113. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/registrar.html +0 -0
  114. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/registrationcontact.html +0 -0
  115. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/view/button.html +0 -0
  116. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/view/prefix.html +0 -0
  117. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/view/related.html +0 -0
  118. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
  119. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
  120. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/zone/child_zone.html +0 -0
  121. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
  122. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
  123. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
  124. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
  125. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/zone.html +0 -0
  126. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/templates/netbox_dns/zonetemplate.html +0 -0
  127. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/urls/__init__.py +0 -0
  128. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/urls/nameserver.py +0 -0
  129. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/urls/record.py +0 -0
  130. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/urls/record_template.py +0 -0
  131. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/urls/registrar.py +0 -0
  132. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/urls/registration_contact.py +0 -0
  133. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/urls/view.py +0 -0
  134. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/urls/zone.py +0 -0
  135. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/urls/zone_template.py +0 -0
  136. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/utilities/__init__.py +0 -0
  137. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/utilities/conversions.py +0 -0
  138. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/validators/__init__.py +0 -0
  139. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/validators/dns_name.py +0 -0
  140. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/validators/dns_value.py +0 -0
  141. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/validators/rfc2317.py +0 -0
  142. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/views/__init__.py +0 -0
  143. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/views/nameserver.py +0 -0
  144. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/views/record.py +0 -0
  145. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/views/record_template.py +0 -0
  146. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/views/registrar.py +0 -0
  147. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/views/registration_contact.py +0 -0
  148. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/views/view.py +0 -0
  149. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/views/zone.py +0 -0
  150. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_dns/views/zone_template.py +0 -0
  151. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_plugin_dns.egg-info/dependency_links.txt +0 -0
  152. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_plugin_dns.egg-info/requires.txt +0 -0
  153. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/netbox_plugin_dns.egg-info/top_level.txt +0 -0
  154. {netbox_plugin_dns-1.1.1 → netbox_plugin_dns-1.1.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-plugin-dns
3
- Version: 1.1.1
3
+ Version: 1.1.2
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
@@ -5,7 +5,7 @@ from ipam.choices import IPAddressStatusChoices
5
5
 
6
6
  from netbox_dns.choices import RecordTypeChoices
7
7
 
8
- __version__ = "1.1.1"
8
+ __version__ = "1.1.2"
9
9
 
10
10
 
11
11
  class DNSConfig(PluginConfig):
@@ -37,8 +37,9 @@ class DNSConfig(PluginConfig):
37
37
  "tolerate_underscores_in_labels": False,
38
38
  "tolerate_underscores_in_hostnames": False, # Deprecated, will be removed in 1.2.0
39
39
  "tolerate_leading_underscore_types": [
40
- RecordTypeChoices.TXT,
41
40
  RecordTypeChoices.SRV,
41
+ RecordTypeChoices.TLSA,
42
+ RecordTypeChoices.TXT,
42
43
  ],
43
44
  "tolerate_non_rfc1035_types": [],
44
45
  "enable_root_zones": False,
@@ -65,5 +65,6 @@ class ViewSerializer(NetBoxModelSerializer):
65
65
  "custom_fields",
66
66
  "tenant",
67
67
  "prefixes",
68
+ "ip_address_filter",
68
69
  )
69
70
  brief_fields = ("id", "url", "display", "name", "default_view", "description")
@@ -1,6 +1,6 @@
1
1
  from django import forms
2
2
  from django.conf import settings
3
- from django.core.exceptions import ValidationError
3
+ from django.core.exceptions import ValidationError, FieldError
4
4
  from django.db.models import Q, Count
5
5
 
6
6
  from netbox.forms import (
@@ -18,9 +18,10 @@ from utilities.forms.fields import (
18
18
  )
19
19
  from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES
20
20
  from utilities.forms.rendering import FieldSet
21
+ from utilities.forms.fields import JSONField
21
22
  from tenancy.models import Tenant
22
23
  from tenancy.forms import TenancyForm, TenancyFilterForm
23
- from ipam.models import Prefix
24
+ from ipam.models import Prefix, IPAddress
24
25
  from netbox.context import current_request
25
26
 
26
27
  from netbox_dns.models import View
@@ -29,6 +30,7 @@ from netbox_dns.utilities import (
29
30
  check_dns_records,
30
31
  get_ip_addresses_by_prefix,
31
32
  get_views_by_prefix,
33
+ get_query_from_filter,
32
34
  )
33
35
 
34
36
 
@@ -45,7 +47,7 @@ class ViewPrefixUpdateMixin:
45
47
  def clean(self, *args, **kwargs):
46
48
  super().clean(*args, **kwargs)
47
49
 
48
- if self.instance.pk is None or "prefixes" not in self.changed_data:
50
+ if self.instance._state.adding or "prefixes" not in self.changed_data:
49
51
  return
50
52
 
51
53
  prefixes = self.cleaned_data.get("prefixes")
@@ -97,6 +99,7 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
97
99
 
98
100
  if settings.PLUGINS_CONFIG["netbox_dns"].get("dnssync_disabled"):
99
101
  del self.fields["prefixes"]
102
+ del self.fields["ip_address_filter"]
100
103
 
101
104
  if request := current_request.get():
102
105
  if not request.user.has_perm("ipam.view_prefix"):
@@ -107,12 +110,6 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
107
110
  "placeholder"
108
111
  ] = "You do not have permission to modify assigned prefixes"
109
112
 
110
- def clean_prefixes(self):
111
- if hasattr(self, "_saved_prefixes"):
112
- return self._saved_prefixes
113
-
114
- return self.cleaned_data["prefixes"]
115
-
116
113
  prefixes = PrefixDynamicModelMultipleChoiceField(
117
114
  queryset=Prefix.objects.all(),
118
115
  required=False,
@@ -121,10 +118,15 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
121
118
  "depth": None,
122
119
  },
123
120
  )
121
+ ip_address_filter = JSONField(
122
+ label="IP Address Filter",
123
+ required=False,
124
+ help_text="Specify criteria for address record creation in JSON form",
125
+ )
124
126
 
125
127
  fieldsets = (
126
128
  FieldSet("name", "default_view", "description", "tags", name="View"),
127
- FieldSet("prefixes"),
129
+ FieldSet("prefixes", "ip_address_filter"),
128
130
  FieldSet("tenant_group", "tenant", name="Tenancy"),
129
131
  )
130
132
 
@@ -137,8 +139,25 @@ class ViewForm(ViewPrefixUpdateMixin, TenancyForm, NetBoxModelForm):
137
139
  "tags",
138
140
  "tenant",
139
141
  "prefixes",
142
+ "ip_address_filter",
140
143
  )
141
144
 
145
+ def clean_prefixes(self):
146
+ if hasattr(self, "_saved_prefixes"):
147
+ return self._saved_prefixes
148
+
149
+ return self.cleaned_data["prefixes"]
150
+
151
+ def clean_ip_address_filter(self):
152
+ ip_address_filter = self.cleaned_data.get("ip_address_filter")
153
+
154
+ try:
155
+ IPAddress.objects.filter(get_query_from_filter(ip_address_filter)).exists()
156
+ except (FieldError, ValueError) as exc:
157
+ self.add_error("ip_address_filter", f"Invalid filter for IPAddress: {exc}")
158
+
159
+ return ip_address_filter
160
+
142
161
 
143
162
  class ViewFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
144
163
  def __init__(self, *args, **kwargs):
@@ -3,16 +3,6 @@ from typing import List
3
3
  import strawberry
4
4
  import strawberry_django
5
5
 
6
- from netbox_dns.models import (
7
- NameServer,
8
- View,
9
- Zone,
10
- Record,
11
- RegistrationContact,
12
- Registrar,
13
- ZoneTemplate,
14
- RecordTemplate,
15
- )
16
6
  from .types import (
17
7
  NetBoxDNSNameServerType,
18
8
  NetBoxDNSViewType,
@@ -43,6 +43,7 @@ class NetBoxDNSViewType(NetBoxObjectType):
43
43
  description: str
44
44
  tenant: Annotated["TenantType", strawberry.lazy("tenancy.graphql.types")] | None
45
45
  prefixes: List[Annotated["PrefixType", strawberry.lazy("ipam.graphql.types")]]
46
+ ip_address_filter: str | None
46
47
 
47
48
 
48
49
  @strawberry_django.type(Zone, fields="__all__", filters=NetBoxDNSZoneFilter)
@@ -0,0 +1,18 @@
1
+ # Generated by Django 5.0.9 on 2024-09-18 13:12
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("netbox_dns", "0009_rename_contact_registrationcontact"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name="view",
15
+ name="ip_address_filter",
16
+ field=models.JSONField(blank=True, null=True),
17
+ ),
18
+ ]
@@ -0,0 +1,53 @@
1
+ from netbox.models import NetBoxModel
2
+
3
+
4
+ __all__ = ("ObjectModificationMixin",)
5
+
6
+
7
+ class ObjectModificationMixin:
8
+ def __init__(self, *args, **kwargs):
9
+ super().__init__(*args, **kwargs)
10
+
11
+ if not hasattr(self.__class__, "check_fields"):
12
+ self.__class__.check_fields = (
13
+ {field.name for field in self._meta.fields}
14
+ - {field.name for field in NetBoxModel._meta.fields}
15
+ - {"id"}
16
+ )
17
+
18
+ self.__class__.check_fields.add("custom_field_data")
19
+
20
+ self._save_field_values()
21
+
22
+ def _save_field_values(self):
23
+ for field in self.check_fields:
24
+ if f"{field}_id" in self.__dict__:
25
+ setattr(self, f"_saved_{field}_id", self.__dict__.get(f"{field}_id"))
26
+ else:
27
+ setattr(self, f"_saved_{field}", self.__dict__.get(field))
28
+
29
+ def save(self, *args, **kwargs):
30
+ super().save(*args, **kwargs)
31
+
32
+ self._save_field_values()
33
+
34
+ @property
35
+ def changed_fields(self):
36
+ if self._state.adding:
37
+ return None
38
+
39
+ _changed_fields = set()
40
+ for field in self.check_fields:
41
+ if f"_saved_{field}_id" in self.__dict__:
42
+ if self.__dict__.get(f"_saved_{field}_id") != self.__dict__.get(
43
+ f"{field}_id"
44
+ ):
45
+ _changed_fields.add(field)
46
+ else:
47
+ if self.__dict__.get(f"_saved_{field}") != self.__dict__.get(field):
48
+ _changed_fields.add(field)
49
+
50
+ return _changed_fields
51
+
52
+ def get_saved_value(self, field):
53
+ return self.__dict__.get(f"_saved_{field}")
@@ -10,13 +10,14 @@ from django.urls import reverse
10
10
  from django.conf import settings
11
11
 
12
12
  from netbox.models import NetBoxModel
13
+ from ipam.models import IPAddress
13
14
  from netbox.models.features import ContactsMixin
14
15
  from netbox.search import SearchIndex, register_search
15
16
  from netbox.plugins.utils import get_plugin_config
16
17
  from utilities.querysets import RestrictedQuerySet
17
18
 
18
19
  from netbox_dns.fields import AddressField
19
- from netbox_dns.utilities import arpa_to_prefix, name_to_unicode
20
+ from netbox_dns.utilities import arpa_to_prefix, name_to_unicode, get_query_from_filter
20
21
  from netbox_dns.validators import validate_generic_name, validate_record_value
21
22
  from netbox_dns.mixins import ObjectModificationMixin
22
23
  from netbox_dns.choices import RecordTypeChoices, RecordStatusChoices
@@ -41,6 +42,20 @@ def record_data_from_ip_address(ip_address, zone):
41
42
  cf_data = ip_address.custom_field_data
42
43
 
43
44
  if cf_data.get("ipaddress_dns_disabled"):
45
+ # +
46
+ # DNS record creation disabled for this address
47
+ # -
48
+ return None
49
+
50
+ if (
51
+ zone.view.ip_address_filter is not None
52
+ and not IPAddress.objects.filter(
53
+ Q(pk=ip_address.pk), get_query_from_filter(zone.view.ip_address_filter)
54
+ ).exists()
55
+ ):
56
+ # +
57
+ # IP address does not match the filter
58
+ # -
44
59
  return None
45
60
 
46
61
  data = {
@@ -473,22 +488,29 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
473
488
  self.rfc2317_cname_record = None
474
489
 
475
490
  def update_from_ip_address(self, ip_address, zone=None):
491
+ """
492
+ Update an address record according to data from an IPAddress object.
493
+
494
+ Returns a tuple of two booleans: (update, delete).
495
+
496
+ update: The record was updated and needs to be cleaned and/or saved
497
+ delete: The record is no longer needed and needs to be deleted
498
+ """
476
499
  if zone is None:
477
500
  zone = self.zone
478
501
 
479
502
  data = record_data_from_ip_address(ip_address, zone)
480
503
 
481
504
  if data is None:
482
- self.delete()
483
- return
505
+ return False, True
484
506
 
485
507
  if all((getattr(self, attr) == data[attr] for attr in data.keys())):
486
- return
508
+ return False, False
487
509
 
488
510
  for attr, value in data.items():
489
511
  setattr(self, attr, value)
490
512
 
491
- return self
513
+ return True, False
492
514
 
493
515
  @classmethod
494
516
  def create_from_ip_address(cls, ip_address, zone):
@@ -585,7 +607,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
585
607
  status__in=Record.ACTIVE_STATUS_LIST,
586
608
  )
587
609
 
588
- if self.pk is not None:
610
+ if not self._state.adding:
589
611
  records = records.exclude(pk=self.pk)
590
612
 
591
613
  if records.exists():
@@ -624,7 +646,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
624
646
  record.save(update_fields=["status"])
625
647
 
626
648
  def check_unique_rrset_ttl(self):
627
- if self.pk is not None:
649
+ if not self._state.adding:
628
650
  return
629
651
 
630
652
  if not get_plugin_config("netbox_dns", "enforce_unique_rrset_ttl", False):
@@ -663,7 +685,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
663
685
  ) from None
664
686
 
665
687
  def update_rrset_ttl(self, ttl=None):
666
- if self.pk is None:
688
+ if self._state.adding:
667
689
  return
668
690
 
669
691
  if not get_plugin_config("netbox_dns", "enforce_unique_rrset_ttl", False):
@@ -699,7 +721,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
699
721
  self.validate_name(new_zone=new_zone)
700
722
  self.validate_value()
701
723
  self.check_unique_record(new_zone=new_zone)
702
- if self.pk is None:
724
+ if self._state.adding:
703
725
  self.check_unique_rrset_ttl()
704
726
 
705
727
  if not self.is_active:
@@ -787,7 +809,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
787
809
  ):
788
810
  self.full_clean()
789
811
 
790
- if self.pk is not None and update_rrset_ttl:
812
+ if not self._state.adding and update_rrset_ttl:
791
813
  self.update_rrset_ttl()
792
814
 
793
815
  if self.is_ptr_record:
@@ -9,6 +9,13 @@ from netbox.context import current_request
9
9
  from utilities.exceptions import AbortRequest
10
10
 
11
11
  from netbox_dns.mixins import ObjectModificationMixin
12
+ from netbox_dns.utilities import (
13
+ get_ip_addresses_by_view,
14
+ check_dns_records,
15
+ update_dns_records,
16
+ delete_dns_records,
17
+ get_query_from_filter,
18
+ )
12
19
 
13
20
 
14
21
  __all__ = (
@@ -34,6 +41,11 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
34
41
  related_name="netbox_dns_views",
35
42
  blank=True,
36
43
  )
44
+ ip_address_filter = models.JSONField(
45
+ verbose_name="IP Address Filter",
46
+ blank=True,
47
+ null=True,
48
+ )
37
49
  tenant = models.ForeignKey(
38
50
  to="tenancy.Tenant",
39
51
  on_delete=models.PROTECT,
@@ -87,6 +99,21 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
87
99
  }
88
100
  )
89
101
 
102
+ if "ip_address_filter" in changed_fields and self.get_saved_value(
103
+ "ip_address_filter"
104
+ ):
105
+ try:
106
+ for ip_address in get_ip_addresses_by_view(self).filter(
107
+ get_query_from_filter(self.ip_address_filter)
108
+ ):
109
+ check_dns_records(ip_address, view=self)
110
+ except ValidationError as exc:
111
+ raise ValidationError(
112
+ {
113
+ "ip_address_filter": exc.messages,
114
+ }
115
+ )
116
+
90
117
  super().clean(*args, **kwargs)
91
118
 
92
119
  def save(self, *args, **kwargs):
@@ -106,6 +133,19 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
106
133
  view.default_view = False
107
134
  view.save()
108
135
 
136
+ if changed_fields is not None and "ip_address_filter" in changed_fields:
137
+ ip_addresses = get_ip_addresses_by_view(self)
138
+
139
+ for ip_address in ip_addresses.exclude(
140
+ get_query_from_filter(self.ip_address_filter)
141
+ ):
142
+ delete_dns_records(ip_address, view=self)
143
+
144
+ for ip_address in ip_addresses.filter(
145
+ get_query_from_filter(self.ip_address_filter)
146
+ ):
147
+ update_dns_records(ip_address, view=self)
148
+
109
149
 
110
150
  @register_search
111
151
  class ViewIndex(SearchIndex):
@@ -649,14 +649,16 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
649
649
  }
650
650
  )
651
651
 
652
- if self.pk is not None:
653
- old_zone = Zone.objects.get(pk=self.pk)
652
+ if not self._state.adding:
653
+ old_soa_serial = self.get_saved_value("soa_serial")
654
+ old_soa_serial_auto = self.get_saved_value("soa_serial_auto")
655
+
654
656
  if not self.soa_serial_auto:
655
- self.check_soa_serial_increment(old_zone.soa_serial, self.soa_serial)
656
- elif not old_zone.soa_serial_auto:
657
+ self.check_soa_serial_increment(old_soa_serial, self.soa_serial)
658
+ elif not old_soa_serial_auto:
657
659
  try:
658
660
  self.check_soa_serial_increment(
659
- old_zone.soa_serial, self.get_auto_serial()
661
+ old_soa_serial, self.get_auto_serial()
660
662
  )
661
663
  except ValidationError:
662
664
  raise ValidationError(
@@ -665,10 +667,13 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
665
667
  }
666
668
  )
667
669
 
670
+ old_name = self.get_saved_value("name")
671
+ old_view_id = self.get_saved_value("view_id")
672
+
668
673
  if (
669
674
  not self.ip_addresses_checked
670
- and old_zone.name != self.name
671
- or old_zone.view != self.view
675
+ and old_name != self.name
676
+ or old_view_id != self.view_id
672
677
  ):
673
678
  ip_addresses = IPAddress.objects.filter(
674
679
  netbox_dns_records__in=self.record_set.filter(
@@ -52,7 +52,7 @@ def ipam_dnssync_ipaddress_post_clean(instance, **kwargs):
52
52
  dns_name=instance.dns_name,
53
53
  status__in=IPADDRESS_ACTIVE_STATUS,
54
54
  )
55
- if instance.pk is not None:
55
+ if not instance._state.adding:
56
56
  duplicate_addresses = duplicate_addresses.exclude(pk=instance.pk)
57
57
 
58
58
  if ENFORCE_UNIQUE_RECORDS and instance.status in IPADDRESS_ACTIVE_STATUS:
@@ -74,7 +74,7 @@ def ipam_dnssync_ipaddress_post_clean(instance, **kwargs):
74
74
  if (request := current_request.get()) is not None:
75
75
  cf_data = instance.custom_field_data
76
76
  if (
77
- instance.pk is not None
77
+ not instance._state.adding
78
78
  and any(
79
79
  (
80
80
  cf_data.get(cf, cf_default)
@@ -86,7 +86,7 @@ def ipam_dnssync_ipaddress_post_clean(instance, **kwargs):
86
86
  )
87
87
  and not check_record_permission()
88
88
  ) or (
89
- instance.pk is None
89
+ instance._state.adding
90
90
  and any(
91
91
  (
92
92
  cf_data.get(cf, cf_default) != cf_default
@@ -129,7 +129,7 @@ def ipam_dnssync_prefix_pre_save(instance, **kwargs):
129
129
  """
130
130
  request = current_request.get()
131
131
 
132
- if instance.pk is None or not instance.netbox_dns_views.exists():
132
+ if instance._state.adding or not instance.netbox_dns_views.exists():
133
133
  return
134
134
 
135
135
  saved_prefix = Prefix.objects.prefetch_related("netbox_dns_views").get(
@@ -23,7 +23,7 @@ class ViewTable(TenancyColumnsMixin, NetBoxTable):
23
23
 
24
24
  class Meta(NetBoxTable.Meta):
25
25
  model = View
26
- fields = ("description",)
26
+ fields = ("description", "ip_address_filter")
27
27
  default_columns = ("name", "default_view")
28
28
 
29
29
 
@@ -42,6 +42,7 @@
42
42
  </h5>
43
43
  <div class="card-body">
44
44
  <table class="table table-hover attr-table">
45
+ {% if object.prefixes.exists %}
45
46
  {% for prefix in object.prefixes.all %}
46
47
  <tr>
47
48
  <td>
@@ -56,9 +57,24 @@
56
57
  {% endif %}
57
58
  </tr>
58
59
  {% endfor %}
60
+ {% else %}
61
+ <span class="text-muted">No prefixes assigned</span>
62
+ {% endif %}
59
63
  </table>
60
64
  </div>
61
65
  </div>
66
+ <div class="card">
67
+ <h5 class="card-header">
68
+ IP Address Filters
69
+ </h5>
70
+ <div class="card-body">
71
+ {% if object.ip_address_filter %}
72
+ <pre>{{ object.ip_address_filter|json }}</pre>
73
+ {% else %}
74
+ <span class="text-muted">No filters defined</span>
75
+ {% endif %}
76
+ </div>
77
+ </div>
62
78
  {% endif %}
63
79
  </div>
64
80
  </div>