netbox-plugin-dns 0.21.4__py3-none-any.whl → 1.4.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. netbox_dns/__init__.py +106 -41
  2. netbox_dns/api/field_serializers.py +25 -0
  3. netbox_dns/api/nested_serializers.py +95 -52
  4. netbox_dns/api/serializers.py +14 -296
  5. netbox_dns/api/serializers_/__init__.py +0 -0
  6. netbox_dns/api/serializers_/dnssec_key_template.py +69 -0
  7. netbox_dns/api/serializers_/dnssec_policy.py +165 -0
  8. netbox_dns/api/serializers_/nameserver.py +56 -0
  9. netbox_dns/api/serializers_/prefix.py +18 -0
  10. netbox_dns/api/serializers_/record.py +105 -0
  11. netbox_dns/api/serializers_/record_template.py +71 -0
  12. netbox_dns/api/serializers_/registrar.py +45 -0
  13. netbox_dns/api/serializers_/registration_contact.py +50 -0
  14. netbox_dns/api/serializers_/view.py +81 -0
  15. netbox_dns/api/serializers_/zone.py +247 -0
  16. netbox_dns/api/serializers_/zone_template.py +157 -0
  17. netbox_dns/api/urls.py +13 -2
  18. netbox_dns/api/views.py +96 -58
  19. netbox_dns/choices/__init__.py +4 -0
  20. netbox_dns/choices/dnssec_key_template.py +67 -0
  21. netbox_dns/choices/dnssec_policy.py +40 -0
  22. netbox_dns/choices/record.py +104 -0
  23. netbox_dns/choices/utilities.py +4 -0
  24. netbox_dns/choices/zone.py +119 -0
  25. netbox_dns/fields/__init__.py +4 -0
  26. netbox_dns/fields/address.py +22 -16
  27. netbox_dns/fields/choice_array.py +33 -0
  28. netbox_dns/fields/ipam.py +15 -0
  29. netbox_dns/fields/network.py +42 -18
  30. netbox_dns/fields/rfc2317.py +97 -0
  31. netbox_dns/fields/timeperiod.py +33 -0
  32. netbox_dns/filters.py +7 -0
  33. netbox_dns/filtersets/__init__.py +12 -0
  34. netbox_dns/filtersets/dnssec_key_template.py +57 -0
  35. netbox_dns/filtersets/dnssec_policy.py +101 -0
  36. netbox_dns/filtersets/nameserver.py +46 -0
  37. netbox_dns/filtersets/record.py +135 -0
  38. netbox_dns/filtersets/record_template.py +59 -0
  39. netbox_dns/{filters → filtersets}/registrar.py +8 -1
  40. netbox_dns/{filters/contact.py → filtersets/registration_contact.py} +9 -3
  41. netbox_dns/filtersets/view.py +45 -0
  42. netbox_dns/filtersets/zone.py +254 -0
  43. netbox_dns/filtersets/zone_template.py +165 -0
  44. netbox_dns/forms/__init__.py +5 -1
  45. netbox_dns/forms/dnssec_key_template.py +250 -0
  46. netbox_dns/forms/dnssec_policy.py +654 -0
  47. netbox_dns/forms/nameserver.py +121 -27
  48. netbox_dns/forms/record.py +215 -104
  49. netbox_dns/forms/record_template.py +285 -0
  50. netbox_dns/forms/registrar.py +108 -31
  51. netbox_dns/forms/registration_contact.py +282 -0
  52. netbox_dns/forms/view.py +331 -20
  53. netbox_dns/forms/zone.py +769 -373
  54. netbox_dns/forms/zone_template.py +463 -0
  55. netbox_dns/graphql/__init__.py +25 -22
  56. netbox_dns/graphql/enums.py +41 -0
  57. netbox_dns/graphql/filter_lookups.py +13 -0
  58. netbox_dns/graphql/filters/__init__.py +12 -0
  59. netbox_dns/graphql/filters/dnssec_key_template.py +63 -0
  60. netbox_dns/graphql/filters/dnssec_policy.py +124 -0
  61. netbox_dns/graphql/filters/nameserver.py +32 -0
  62. netbox_dns/graphql/filters/record.py +89 -0
  63. netbox_dns/graphql/filters/record_template.py +55 -0
  64. netbox_dns/graphql/filters/registrar.py +30 -0
  65. netbox_dns/graphql/filters/registration_contact.py +27 -0
  66. netbox_dns/graphql/filters/view.py +28 -0
  67. netbox_dns/graphql/filters/zone.py +147 -0
  68. netbox_dns/graphql/filters/zone_template.py +97 -0
  69. netbox_dns/graphql/schema.py +89 -7
  70. netbox_dns/graphql/types.py +355 -0
  71. netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
  72. netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
  73. netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
  74. netbox_dns/management/commands/cleanup_database.py +175 -156
  75. netbox_dns/management/commands/cleanup_rrset_ttl.py +64 -0
  76. netbox_dns/management/commands/rebuild_dnssync.py +23 -0
  77. netbox_dns/management/commands/setup_dnssync.py +140 -0
  78. netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -27
  79. netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +557 -0
  80. netbox_dns/migrations/{0013_add_nameserver_zone_record_description.py → 0002_contact_description_registrar_description.py} +4 -9
  81. netbox_dns/migrations/0003_default_view.py +15 -0
  82. netbox_dns/migrations/0004_create_and_assign_default_view.py +26 -0
  83. netbox_dns/migrations/0005_alter_zone_view_not_null.py +18 -0
  84. netbox_dns/migrations/0006_templating.py +172 -0
  85. netbox_dns/migrations/0007_alter_ordering_options.py +25 -0
  86. netbox_dns/migrations/0008_view_prefixes.py +18 -0
  87. netbox_dns/migrations/0009_rename_contact_registrationcontact.py +36 -0
  88. netbox_dns/migrations/0010_view_ip_address_filter.py +18 -0
  89. netbox_dns/migrations/0011_rename_related_fields.py +63 -0
  90. netbox_dns/migrations/0012_natural_ordering.py +88 -0
  91. netbox_dns/migrations/0013_zonetemplate_soa_mname_zonetemplate_soa_rname.py +30 -0
  92. netbox_dns/migrations/0014_alter_unique_constraints_lowercase.py +42 -0
  93. netbox_dns/migrations/0015_dnssec.py +168 -0
  94. netbox_dns/migrations/{0015_add_record_status.py → 0016_dnssec_policy_status.py} +5 -4
  95. netbox_dns/migrations/0017_dnssec_policy_zone_zone_template.py +41 -0
  96. netbox_dns/migrations/0018_zone_domain_status_zone_expiration_date.py +23 -0
  97. netbox_dns/migrations/0019_dnssecpolicy_parental_agents.py +25 -0
  98. netbox_dns/migrations/0020_netbox_3_4.py +1 -1
  99. netbox_dns/migrations/0020_remove_dnssecpolicy_parental_agents_and_more.py +29 -0
  100. netbox_dns/migrations/0021_alter_record_ptr_record.py +25 -0
  101. netbox_dns/migrations/0021_record_ip_address.py +1 -1
  102. netbox_dns/migrations/0022_alter_record_ipam_ip_address.py +26 -0
  103. netbox_dns/migrations/0023_disable_ptr_false.py +27 -0
  104. netbox_dns/migrations/0024_zonetemplate_parental_agents.py +25 -0
  105. netbox_dns/migrations/0025_remove_zone_inline_signing_and_more.py +22 -0
  106. netbox_dns/migrations/0026_alter_dnssecpolicy_nsec3_opt_out.py +18 -0
  107. netbox_dns/migrations/0026_domain_registration.py +1 -1
  108. netbox_dns/migrations/0027_zone_comments.py +18 -0
  109. netbox_dns/migrations/0028_alter_zone_default_ttl_alter_zone_soa_minimum_and_more.py +54 -0
  110. netbox_dns/migrations/0028_rfc2317_fields.py +44 -0
  111. netbox_dns/migrations/0029_alter_registrationcontact_street.py +18 -0
  112. netbox_dns/migrations/0029_record_fqdn.py +30 -0
  113. netbox_dns/mixins/__init__.py +1 -0
  114. netbox_dns/mixins/object_modification.py +57 -0
  115. netbox_dns/models/__init__.py +5 -1
  116. netbox_dns/models/dnssec_key_template.py +114 -0
  117. netbox_dns/models/dnssec_policy.py +203 -0
  118. netbox_dns/models/nameserver.py +61 -30
  119. netbox_dns/models/record.py +781 -234
  120. netbox_dns/models/record_template.py +198 -0
  121. netbox_dns/models/registrar.py +34 -15
  122. netbox_dns/models/{contact.py → registration_contact.py} +72 -43
  123. netbox_dns/models/view.py +129 -9
  124. netbox_dns/models/zone.py +806 -242
  125. netbox_dns/models/zone_template.py +209 -0
  126. netbox_dns/navigation.py +176 -76
  127. netbox_dns/signals/__init__.py +0 -0
  128. netbox_dns/signals/dnssec.py +32 -0
  129. netbox_dns/signals/ipam_dnssync.py +216 -0
  130. netbox_dns/tables/__init__.py +5 -1
  131. netbox_dns/tables/dnssec_key_template.py +49 -0
  132. netbox_dns/tables/dnssec_policy.py +140 -0
  133. netbox_dns/tables/ipam_dnssync.py +12 -0
  134. netbox_dns/tables/nameserver.py +14 -17
  135. netbox_dns/tables/record.py +117 -59
  136. netbox_dns/tables/record_template.py +91 -0
  137. netbox_dns/tables/registrar.py +20 -10
  138. netbox_dns/tables/{contact.py → registration_contact.py} +22 -11
  139. netbox_dns/tables/view.py +47 -3
  140. netbox_dns/tables/zone.py +62 -31
  141. netbox_dns/tables/zone_template.py +78 -0
  142. netbox_dns/template_content.py +124 -38
  143. netbox_dns/templates/netbox_dns/dnsseckeytemplate.html +70 -0
  144. netbox_dns/templates/netbox_dns/dnssecpolicy.html +163 -0
  145. netbox_dns/templates/netbox_dns/nameserver.html +31 -28
  146. netbox_dns/templates/netbox_dns/record/managed.html +2 -1
  147. netbox_dns/templates/netbox_dns/record/related.html +17 -6
  148. netbox_dns/templates/netbox_dns/record.html +140 -93
  149. netbox_dns/templates/netbox_dns/recordtemplate.html +96 -0
  150. netbox_dns/templates/netbox_dns/registrar.html +41 -34
  151. netbox_dns/templates/netbox_dns/registrationcontact.html +76 -0
  152. netbox_dns/templates/netbox_dns/view/button.html +10 -0
  153. netbox_dns/templates/netbox_dns/view/prefix.html +44 -0
  154. netbox_dns/templates/netbox_dns/view/related.html +33 -0
  155. netbox_dns/templates/netbox_dns/view.html +62 -18
  156. netbox_dns/templates/netbox_dns/zone/base.html +6 -3
  157. netbox_dns/templates/netbox_dns/zone/child.html +6 -5
  158. netbox_dns/templates/netbox_dns/zone/child_zone.html +18 -0
  159. netbox_dns/templates/netbox_dns/zone/delegation_record.html +18 -0
  160. netbox_dns/templates/netbox_dns/zone/managed_record.html +1 -1
  161. netbox_dns/templates/netbox_dns/zone/record.html +6 -5
  162. netbox_dns/templates/netbox_dns/zone/registration.html +43 -24
  163. netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +18 -0
  164. netbox_dns/templates/netbox_dns/zone.html +178 -119
  165. netbox_dns/templates/netbox_dns/zonetemplate/child.html +46 -0
  166. netbox_dns/templates/netbox_dns/zonetemplate.html +124 -0
  167. netbox_dns/templatetags/netbox_dns.py +10 -0
  168. netbox_dns/urls.py +50 -210
  169. netbox_dns/utilities/__init__.py +3 -0
  170. netbox_dns/{utilities.py → utilities/conversions.py} +55 -7
  171. netbox_dns/utilities/dns.py +11 -0
  172. netbox_dns/utilities/ipam_dnssync.py +370 -0
  173. netbox_dns/validators/__init__.py +4 -0
  174. netbox_dns/validators/dns_name.py +116 -0
  175. netbox_dns/validators/dns_value.py +147 -0
  176. netbox_dns/validators/dnssec.py +148 -0
  177. netbox_dns/validators/rfc2317.py +28 -0
  178. netbox_dns/views/__init__.py +5 -1
  179. netbox_dns/views/dnssec_key_template.py +78 -0
  180. netbox_dns/views/dnssec_policy.py +146 -0
  181. netbox_dns/views/nameserver.py +34 -15
  182. netbox_dns/views/record.py +156 -15
  183. netbox_dns/views/record_template.py +93 -0
  184. netbox_dns/views/registrar.py +32 -13
  185. netbox_dns/views/registration_contact.py +101 -0
  186. netbox_dns/views/view.py +58 -14
  187. netbox_dns/views/zone.py +130 -33
  188. netbox_dns/views/zone_template.py +82 -0
  189. netbox_plugin_dns-1.4.7.dist-info/METADATA +132 -0
  190. netbox_plugin_dns-1.4.7.dist-info/RECORD +201 -0
  191. {netbox_plugin_dns-0.21.4.dist-info → netbox_plugin_dns-1.4.7.dist-info}/WHEEL +2 -1
  192. {netbox_plugin_dns-0.21.4.dist-info → netbox_plugin_dns-1.4.7.dist-info/licenses}/LICENSE +2 -1
  193. netbox_plugin_dns-1.4.7.dist-info/top_level.txt +1 -0
  194. netbox_dns/filters/__init__.py +0 -6
  195. netbox_dns/filters/nameserver.py +0 -18
  196. netbox_dns/filters/record.py +0 -53
  197. netbox_dns/filters/view.py +0 -18
  198. netbox_dns/filters/zone.py +0 -112
  199. netbox_dns/forms/contact.py +0 -211
  200. netbox_dns/graphql/contact.py +0 -19
  201. netbox_dns/graphql/nameserver.py +0 -19
  202. netbox_dns/graphql/record.py +0 -19
  203. netbox_dns/graphql/registrar.py +0 -19
  204. netbox_dns/graphql/view.py +0 -19
  205. netbox_dns/graphql/zone.py +0 -19
  206. netbox_dns/management/commands/setup_coupling.py +0 -75
  207. netbox_dns/management/commands/update_soa.py +0 -22
  208. netbox_dns/middleware.py +0 -226
  209. netbox_dns/migrations/0001_initial.py +0 -115
  210. netbox_dns/migrations/0002_zone_default_ttl.py +0 -18
  211. netbox_dns/migrations/0003_soa_managed_records.py +0 -112
  212. netbox_dns/migrations/0004_create_ptr_for_a_aaaa_records.py +0 -80
  213. netbox_dns/migrations/0005_update_ns_records.py +0 -41
  214. netbox_dns/migrations/0006_zone_soa_serial_auto.py +0 -29
  215. netbox_dns/migrations/0007_alter_zone_soa_serial_auto.py +0 -17
  216. netbox_dns/migrations/0008_zone_status_names.py +0 -21
  217. netbox_dns/migrations/0009_netbox32.py +0 -71
  218. netbox_dns/migrations/0010_update_soa_records.py +0 -58
  219. netbox_dns/migrations/0011_add_view_model.py +0 -70
  220. netbox_dns/migrations/0012_adjust_zone_and_record.py +0 -17
  221. netbox_dns/migrations/0014_add_view_description.py +0 -16
  222. netbox_dns/migrations/0016_cleanup_ptr_records.py +0 -38
  223. netbox_dns/migrations/0017_alter_record_ttl.py +0 -17
  224. netbox_dns/migrations/0018_zone_arpa_network.py +0 -51
  225. netbox_dns/migrations/0019_update_ns_ttl.py +0 -19
  226. netbox_dns/templates/netbox_dns/contact.html +0 -71
  227. netbox_dns/templates/netbox_dns/related_dns_objects.html +0 -21
  228. netbox_dns/templatetags/view_helpers.py +0 -15
  229. netbox_dns/validators.py +0 -57
  230. netbox_dns/views/contact.py +0 -83
  231. netbox_plugin_dns-0.21.4.dist-info/METADATA +0 -101
  232. netbox_plugin_dns-0.21.4.dist-info/RECORD +0 -110
@@ -1,19 +0,0 @@
1
- from graphene import ObjectType
2
-
3
- from netbox.graphql.fields import ObjectField, ObjectListField
4
- from netbox.graphql.types import NetBoxObjectType
5
-
6
- from netbox_dns.models import NameServer
7
- from netbox_dns.filters import NameServerFilter
8
-
9
-
10
- class NameServerType(NetBoxObjectType):
11
- class Meta:
12
- model = NameServer
13
- fields = "__all__"
14
- filterset_class = NameServerFilter
15
-
16
-
17
- class NameServerQuery(ObjectType):
18
- nameserver = ObjectField(NameServerType)
19
- nameserver_list = ObjectListField(NameServerType)
@@ -1,19 +0,0 @@
1
- from graphene import ObjectType
2
-
3
- from netbox.graphql.fields import ObjectField, ObjectListField
4
- from netbox.graphql.types import NetBoxObjectType
5
-
6
- from netbox_dns.models import Record
7
- from netbox_dns.filters import RecordFilter
8
-
9
-
10
- class RecordType(NetBoxObjectType):
11
- class Meta:
12
- model = Record
13
- fields = "__all__"
14
- filterset_class = RecordFilter
15
-
16
-
17
- class RecordQuery(ObjectType):
18
- record = ObjectField(RecordType)
19
- record_list = ObjectListField(RecordType)
@@ -1,19 +0,0 @@
1
- from graphene import ObjectType
2
-
3
- from netbox.graphql.fields import ObjectField, ObjectListField
4
- from netbox.graphql.types import NetBoxObjectType
5
-
6
- from netbox_dns.models import Registrar
7
- from netbox_dns.filters import RegistrarFilter
8
-
9
-
10
- class RegistrarType(NetBoxObjectType):
11
- class Meta:
12
- model = Registrar
13
- fields = "__all__"
14
- filterset_class = RegistrarFilter
15
-
16
-
17
- class RegistrarQuery(ObjectType):
18
- registrar = ObjectField(RegistrarType)
19
- registrar_list = ObjectListField(RegistrarType)
@@ -1,19 +0,0 @@
1
- from graphene import ObjectType
2
-
3
- from netbox.graphql.fields import ObjectField, ObjectListField
4
- from netbox.graphql.types import NetBoxObjectType
5
-
6
- from netbox_dns.models import View
7
- from netbox_dns.filters import ViewFilter
8
-
9
-
10
- class ViewType(NetBoxObjectType):
11
- class Meta:
12
- model = View
13
- fields = "__all__"
14
- filterset_class = ViewFilter
15
-
16
-
17
- class ViewQuery(ObjectType):
18
- view = ObjectField(ViewType)
19
- view_list = ObjectListField(ViewType)
@@ -1,19 +0,0 @@
1
- from graphene import ObjectType
2
-
3
- from netbox.graphql.fields import ObjectField, ObjectListField
4
- from netbox.graphql.types import NetBoxObjectType
5
-
6
- from netbox_dns.models import Zone
7
- from netbox_dns.filters import ZoneFilter
8
-
9
-
10
- class ZoneType(NetBoxObjectType):
11
- class Meta:
12
- model = Zone
13
- fields = "__all__"
14
- filterset_class = ZoneFilter
15
-
16
-
17
- class ZoneQuery(ObjectType):
18
- zone = ObjectField(ZoneType)
19
- zone_list = ObjectListField(ZoneType)
@@ -1,75 +0,0 @@
1
- from django.core.management.base import BaseCommand, CommandError
2
-
3
- from django.contrib.contenttypes.models import ContentType
4
- from extras.models import CustomField
5
- from extras.choices import CustomFieldTypeChoices
6
- from ipam.models import IPAddress
7
- from netbox_dns.models import Record, Zone
8
-
9
-
10
- class Command(BaseCommand):
11
- help = "Setup IPAddress custom fields needed for IPAM-DNS coupling"
12
-
13
- def add_arguments(self, parser):
14
- parser.add_argument(
15
- "--remove", action="store_true", help="Remove custom fields"
16
- )
17
-
18
- def handle(self, *model_names, **options):
19
- ipaddress_object_type = ContentType.objects.get_for_model(IPAddress)
20
- zone_object_type = ContentType.objects.get_for_model(Zone)
21
- record_object_type = ContentType.objects.get_for_model(Record)
22
- customfields = ("ipaddress_dns_record_name", "ipaddress_dns_zone_id")
23
-
24
- if options["remove"]:
25
- for cf in customfields:
26
- try:
27
- CustomField.objects.get(
28
- name=cf, content_types=ipaddress_object_type
29
- ).delete()
30
- except:
31
- self.stderr.write(f"Custom field '{cf}' does not exist!")
32
- else:
33
- self.stdout.write(f"Custom field '{cf}' removed")
34
-
35
- else:
36
- msg = ""
37
- for cf in customfields:
38
- try:
39
- CustomField.objects.get(
40
- name=cf, content_types=ipaddress_object_type
41
- )
42
- except:
43
- pass
44
- else:
45
- msg += f"custom fields '{cf}' already exists, "
46
- if msg != "":
47
- raise CommandError(
48
- "\n".join(
49
- (
50
- "Can't setup IPAM-DNS coupling:",
51
- msg,
52
- "Remove them with NetBox command:",
53
- "python manage.py setup_coupling --remove",
54
- )
55
- )
56
- )
57
-
58
- cf_name = CustomField.objects.create(
59
- name="ipaddress_dns_record_name",
60
- label="Name",
61
- type=CustomFieldTypeChoices.TYPE_TEXT,
62
- required=False,
63
- group_name="DNS",
64
- )
65
- cf_name.content_types.set([ipaddress_object_type])
66
- cf_zone = CustomField.objects.create(
67
- name="ipaddress_dns_zone_id",
68
- label="Zone",
69
- type=CustomFieldTypeChoices.TYPE_OBJECT,
70
- object_type=zone_object_type,
71
- required=False,
72
- group_name="DNS",
73
- )
74
- cf_zone.content_types.set([ipaddress_object_type])
75
- self.stdout.write(f"Custom fields for IPAM-DNS coupling added")
@@ -1,22 +0,0 @@
1
- from django.core.management.base import BaseCommand
2
-
3
- from netbox_dns.models import Zone
4
-
5
-
6
- class Command(BaseCommand):
7
- help = "Create or update SOA records for all zones"
8
-
9
- def add_arguments(self, parser):
10
- parser.add_argument(
11
- "--verbose", action="store_true", help="Increase output verbosity"
12
- )
13
-
14
- def handle(self, *model_names, **options):
15
- zones = Zone.objects.all()
16
-
17
- for zone in zones:
18
- if options["verbose"]:
19
- self.stdout.write(f"Updating the SOA record for zone {zone.name}")
20
- zone.update_soa_record()
21
-
22
- self.stdout.write(f"All SOA records have been updated")
netbox_dns/middleware.py DELETED
@@ -1,226 +0,0 @@
1
- from django.db import transaction
2
- from django.db.models import signals
3
- from django.core.exceptions import MiddlewareNotUsed, PermissionDenied, ValidationError
4
-
5
- from ipam.models import IPAddress
6
- from ipam.choices import IPAddressStatusChoices
7
-
8
- try:
9
- # NetBox 3.5.0 - 3.5.7, 3.5.9+
10
- from extras.plugins import get_plugin_config
11
- except ImportError:
12
- # NetBox 3.5.8
13
- from extras.plugins.utils import get_plugin_config
14
- from netbox.signals import post_clean
15
- from utilities.permissions import resolve_permission
16
-
17
- from netbox_dns.models import Zone, Record, RecordTypeChoices, RecordStatusChoices
18
-
19
-
20
- def address_record_cf_data(ip_address):
21
- name = ip_address.custom_field_data.get("ipaddress_dns_record_name")
22
- zone_id = ip_address.custom_field_data.get("ipaddress_dns_zone_id")
23
-
24
- if name is None or zone_id is None:
25
- return None, None
26
-
27
- return name, zone_id
28
-
29
-
30
- def address_record_type(ip_address):
31
- return RecordTypeChoices.AAAA if ip_address.family == 6 else RecordTypeChoices.A
32
-
33
-
34
- def address_record_status(ip_address):
35
- return (
36
- RecordStatusChoices.STATUS_ACTIVE
37
- if ip_address.status == IPAddressStatusChoices.STATUS_ACTIVE
38
- else RecordStatusChoices.STATUS_INACTIVE
39
- )
40
-
41
-
42
- def new_address_record(ip_address):
43
- name, zone_id = address_record_cf_data(ip_address)
44
-
45
- if zone_id is None:
46
- return None
47
-
48
- return Record(
49
- name=name,
50
- zone_id=zone_id,
51
- status=address_record_status(ip_address),
52
- type=address_record_type(ip_address),
53
- value=str(ip_address.address.ip),
54
- ipam_ip_address_id=ip_address.id,
55
- managed=True,
56
- )
57
-
58
-
59
- def get_address_record(ip_address):
60
- return ip_address.netbox_dns_records.first()
61
-
62
-
63
- def update_address_record(record, ip_address):
64
- name, zone_id = address_record_cf_data(ip_address)
65
-
66
- record.name = name
67
- record.zone_id = zone_id
68
- record.status = address_record_status(ip_address)
69
- record.value = str(ip_address.address.ip)
70
-
71
-
72
- def check_address_record(user, record, permission):
73
- action = resolve_permission(permission)[1]
74
-
75
- if not user.has_perm(permission):
76
- raise PermissionDenied()
77
-
78
- with transaction.atomic():
79
- if action in {"add", "change"}:
80
- record.save()
81
-
82
- queryset = Record.objects.restrict(user=user, action=action)
83
- if not queryset.filter(pk=record.pk).exists():
84
- raise PermissionDenied()
85
-
86
- transaction.set_rollback(True)
87
-
88
-
89
- class Action:
90
- def __init__(self, request):
91
- self.request = request
92
-
93
- def post_clean(self, sender, **kwargs):
94
- ip_address = kwargs.get("instance")
95
- user = self.request.user
96
-
97
- try:
98
- if ip_address.id is None:
99
- #
100
- # Handle new IP addresses
101
- #
102
- record = new_address_record(ip_address)
103
- if record is not None:
104
- check_address_record(user, record, "netbox_dns.add_record")
105
- else:
106
- #
107
- # Handle updates to existing IP addresses
108
- #
109
- record = get_address_record(ip_address)
110
- if record is not None:
111
- #
112
- # Update or delete the existing address record
113
- #
114
- name, zone_id = address_record_cf_data(ip_address)
115
- if zone_id is not None:
116
- #
117
- # Update the address record
118
- #
119
- update_address_record(record, ip_address)
120
- check_address_record(user, record, "netbox_dns.change_record")
121
- else:
122
- #
123
- # Delete the address record
124
- #
125
- check_address_record(user, record, "netbox_dns.delete_record")
126
- else:
127
- #
128
- # Create a new address record
129
- #
130
- record = new_address_record(ip_address)
131
- if record is not None:
132
- check_address_record(user, record, "netbox_dns.add_record")
133
-
134
- except ValidationError as exc:
135
- value = exc.error_dict.pop("name", None)
136
- if value is not None:
137
- exc.error_dict["cf_ipaddress_dns_record_name"] = value
138
-
139
- value = exc.error_dict.pop("value", None)
140
- if value is not None:
141
- exc.error_dict["cf_ipaddress_dns_record_name"] = value
142
-
143
- raise ValidationError(exc)
144
-
145
- #
146
- # Update DNS related fields according to the contents of the IPAM-DNS
147
- # coupling custom fields.
148
- #
149
- def pre_save(self, sender, **kwargs):
150
- ip_address = kwargs.get("instance")
151
- name, zone_id = address_record_cf_data(ip_address)
152
-
153
- if zone_id is not None:
154
- ip_address.dns_name = f"{name}.{Zone.objects.get(pk=zone_id).name}"
155
- else:
156
- ip_address.dns_name = ""
157
- ip_address.custom_field_data["ipaddress_dns_record_name"] = None
158
- ip_address.custom_field_data["ipaddress_dns_zone_id"] = None
159
-
160
- #
161
- # Handle DNS record operation after IPAddress has been created or modified
162
- #
163
- def post_save(self, sender, **kwargs):
164
- ip_address = kwargs.get("instance")
165
- name, zone_id = address_record_cf_data(ip_address)
166
-
167
- if zone_id is None:
168
- #
169
- # Name/Zone CF data has been removed: Remove the DNS address record
170
- #
171
- for record in ip_address.netbox_dns_records.all():
172
- record.delete()
173
-
174
- else:
175
- #
176
- # Name/Zone CF data is present: Check for a DNS address record
177
- # and add or modify it as necessary
178
- #
179
- record = get_address_record(ip_address)
180
- if record is None:
181
- record = new_address_record(ip_address)
182
- else:
183
- update_address_record(record, ip_address)
184
-
185
- record.save()
186
-
187
- #
188
- # Delete DNS record before deleting IP address
189
- #
190
- def pre_delete(self, sender, **kwargs):
191
- ip_address = kwargs.get("instance")
192
-
193
- for record in ip_address.netbox_dns_records.all():
194
- user = self.request.user
195
- check_address_record(user, record, "netbox_dns.delete_record")
196
-
197
- record.delete()
198
-
199
-
200
- class IpamCouplingMiddleware:
201
- def __init__(self, get_response):
202
- if not get_plugin_config("netbox_dns", "feature_ipam_coupling"):
203
- raise MiddlewareNotUsed
204
-
205
- self.get_response = get_response
206
-
207
- def __call__(self, request):
208
- #
209
- # Connect signals to actions
210
- #
211
- action = Action(request)
212
- connections = [
213
- (post_clean, action.post_clean),
214
- (signals.pre_save, action.pre_save),
215
- (signals.post_save, action.post_save),
216
- (signals.pre_delete, action.pre_delete),
217
- ]
218
- for signal, receiver in connections:
219
- signal.connect(receiver, sender=IPAddress)
220
-
221
- response = self.get_response(request)
222
-
223
- for signal, receiver in connections:
224
- signal.disconnect(receiver)
225
-
226
- return response
@@ -1,115 +0,0 @@
1
- # Generated by Django 3.2.5 on 2021-08-13 14:44
2
-
3
- import django.core.serializers.json
4
- from django.db import migrations, models
5
- import django.db.models.deletion
6
- import taggit.managers
7
-
8
-
9
- class Migration(migrations.Migration):
10
- initial = True
11
-
12
- dependencies = [
13
- ("extras", "0059_exporttemplate_as_attachment"),
14
- ]
15
-
16
- operations = [
17
- migrations.CreateModel(
18
- name="NameServer",
19
- fields=[
20
- ("created", models.DateField(auto_now_add=True, null=True)),
21
- ("last_updated", models.DateTimeField(auto_now=True, null=True)),
22
- (
23
- "custom_field_data",
24
- models.JSONField(
25
- blank=True,
26
- default=dict,
27
- encoder=django.core.serializers.json.DjangoJSONEncoder,
28
- ),
29
- ),
30
- ("id", models.BigAutoField(primary_key=True, serialize=False)),
31
- ("name", models.CharField(max_length=255, unique=True)),
32
- (
33
- "tags",
34
- taggit.managers.TaggableManager(
35
- through="extras.TaggedItem", to="extras.Tag"
36
- ),
37
- ),
38
- ],
39
- options={
40
- "ordering": ("name", "id"),
41
- },
42
- ),
43
- migrations.CreateModel(
44
- name="Zone",
45
- fields=[
46
- ("created", models.DateField(auto_now_add=True, null=True)),
47
- ("last_updated", models.DateTimeField(auto_now=True, null=True)),
48
- (
49
- "custom_field_data",
50
- models.JSONField(
51
- blank=True,
52
- default=dict,
53
- encoder=django.core.serializers.json.DjangoJSONEncoder,
54
- ),
55
- ),
56
- ("id", models.BigAutoField(primary_key=True, serialize=False)),
57
- ("name", models.CharField(max_length=255, unique=True)),
58
- (
59
- "status",
60
- models.CharField(blank=True, default="active", max_length=50),
61
- ),
62
- (
63
- "nameservers",
64
- models.ManyToManyField(
65
- blank=True, related_name="zones", to="netbox_dns.NameServer"
66
- ),
67
- ),
68
- (
69
- "tags",
70
- taggit.managers.TaggableManager(
71
- blank=True, through="extras.TaggedItem", to="extras.Tag"
72
- ),
73
- ),
74
- ],
75
- options={
76
- "ordering": ("name", "id"),
77
- },
78
- ),
79
- migrations.CreateModel(
80
- name="Record",
81
- fields=[
82
- ("created", models.DateField(auto_now_add=True, null=True)),
83
- ("last_updated", models.DateTimeField(auto_now=True, null=True)),
84
- (
85
- "custom_field_data",
86
- models.JSONField(
87
- blank=True,
88
- default=dict,
89
- encoder=django.core.serializers.json.DjangoJSONEncoder,
90
- ),
91
- ),
92
- ("id", models.BigAutoField(primary_key=True, serialize=False)),
93
- ("type", models.CharField(max_length=10)),
94
- ("name", models.CharField(max_length=255)),
95
- ("value", models.CharField(max_length=1000)),
96
- ("ttl", models.PositiveIntegerField()),
97
- (
98
- "tags",
99
- taggit.managers.TaggableManager(
100
- through="extras.TaggedItem", to="extras.Tag"
101
- ),
102
- ),
103
- (
104
- "zone",
105
- models.ForeignKey(
106
- on_delete=django.db.models.deletion.CASCADE,
107
- to="netbox_dns.zone",
108
- ),
109
- ),
110
- ],
111
- options={
112
- "ordering": ("name", "id"),
113
- },
114
- ),
115
- ]
@@ -1,18 +0,0 @@
1
- # Generated by Django 3.2.8 on 2021-10-20 11:06
2
-
3
- from django.db import migrations, models
4
-
5
-
6
- class Migration(migrations.Migration):
7
- dependencies = [
8
- ("netbox_dns", "0001_initial"),
9
- ]
10
-
11
- operations = [
12
- migrations.AddField(
13
- model_name="zone",
14
- name="default_ttl",
15
- field=models.PositiveIntegerField(blank=True, default=86400),
16
- preserve_default=False,
17
- ),
18
- ]
@@ -1,112 +0,0 @@
1
- # Generated by Django 3.2.9 on 2021-11-04 20:48
2
-
3
- import django.core.validators
4
- from django.db import migrations, models
5
- import django.db.models.deletion
6
- import taggit.managers
7
-
8
-
9
- class Migration(migrations.Migration):
10
- dependencies = [
11
- ("extras", "0062_clear_secrets_changelog"),
12
- ("netbox_dns", "0002_zone_default_ttl"),
13
- ]
14
-
15
- operations = [
16
- migrations.AddField(
17
- model_name="record",
18
- name="managed",
19
- field=models.BooleanField(default=False),
20
- ),
21
- migrations.AddField(
22
- model_name="zone",
23
- name="soa_expire",
24
- field=models.PositiveIntegerField(
25
- default=2592000,
26
- validators=[django.core.validators.MinValueValidator(1)],
27
- ),
28
- preserve_default=False,
29
- ),
30
- migrations.AddField(
31
- model_name="zone",
32
- name="soa_minimum",
33
- field=models.PositiveIntegerField(
34
- default=3600, validators=[django.core.validators.MinValueValidator(1)]
35
- ),
36
- preserve_default=False,
37
- ),
38
- migrations.AddField(
39
- model_name="zone",
40
- name="soa_mname",
41
- field=models.ForeignKey(
42
- default=1,
43
- on_delete=django.db.models.deletion.PROTECT,
44
- related_name="zones_soa",
45
- to="netbox_dns.nameserver",
46
- ),
47
- preserve_default=False,
48
- ),
49
- migrations.AddField(
50
- model_name="zone",
51
- name="soa_refresh",
52
- field=models.PositiveIntegerField(
53
- default=172800, validators=[django.core.validators.MinValueValidator(1)]
54
- ),
55
- preserve_default=False,
56
- ),
57
- migrations.AddField(
58
- model_name="zone",
59
- name="soa_retry",
60
- field=models.PositiveIntegerField(
61
- default=7200, validators=[django.core.validators.MinValueValidator(1)]
62
- ),
63
- preserve_default=False,
64
- ),
65
- migrations.AddField(
66
- model_name="zone",
67
- name="soa_rname",
68
- field=models.CharField(default="hostmaster.example.com", max_length=255),
69
- preserve_default=False,
70
- ),
71
- migrations.AddField(
72
- model_name="zone",
73
- name="soa_serial",
74
- field=models.PositiveIntegerField(
75
- default=1,
76
- validators=[
77
- django.core.validators.MinValueValidator(1),
78
- django.core.validators.MaxValueValidator(2147483647),
79
- ],
80
- ),
81
- preserve_default=False,
82
- ),
83
- migrations.AddField(
84
- model_name="zone",
85
- name="soa_ttl",
86
- field=models.PositiveIntegerField(
87
- default=86400, validators=[django.core.validators.MinValueValidator(1)]
88
- ),
89
- preserve_default=False,
90
- ),
91
- migrations.AlterField(
92
- model_name="nameserver",
93
- name="tags",
94
- field=taggit.managers.TaggableManager(
95
- blank=True, through="extras.TaggedItem", to="extras.Tag"
96
- ),
97
- ),
98
- migrations.AlterField(
99
- model_name="record",
100
- name="tags",
101
- field=taggit.managers.TaggableManager(
102
- blank=True, through="extras.TaggedItem", to="extras.Tag"
103
- ),
104
- ),
105
- migrations.AlterField(
106
- model_name="zone",
107
- name="default_ttl",
108
- field=models.PositiveIntegerField(
109
- blank=True, validators=[django.core.validators.MinValueValidator(1)]
110
- ),
111
- ),
112
- ]