netbox-plugin-dns 1.0.3__tar.gz → 1.0.5__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 (137) hide show
  1. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/PKG-INFO +2 -1
  2. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/README.md +1 -0
  3. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/__init__.py +1 -1
  4. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/nested_serializers.py +46 -1
  5. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/serializers.py +2 -0
  6. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/serializers_/contact.py +3 -0
  7. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/serializers_/nameserver.py +4 -1
  8. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/serializers_/record.py +5 -4
  9. netbox_plugin_dns-1.0.5/netbox_dns/api/serializers_/record_template.py +57 -0
  10. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/serializers_/registrar.py +3 -0
  11. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/serializers_/view.py +3 -0
  12. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/serializers_/zone.py +30 -6
  13. netbox_plugin_dns-1.0.5/netbox_dns/api/serializers_/zone_template.py +129 -0
  14. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/urls.py +4 -0
  15. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/views.py +41 -1
  16. netbox_plugin_dns-1.0.5/netbox_dns/choices/__init__.py +2 -0
  17. netbox_plugin_dns-1.0.5/netbox_dns/choices/record.py +49 -0
  18. netbox_plugin_dns-1.0.5/netbox_dns/choices/zone.py +20 -0
  19. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/fields/address.py +6 -0
  20. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/fields/network.py +3 -0
  21. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/fields/rfc2317.py +3 -0
  22. {netbox_plugin_dns-1.0.3/netbox_dns/models → netbox_plugin_dns-1.0.5/netbox_dns/filtersets}/__init__.py +3 -2
  23. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/filtersets/contact.py +3 -0
  24. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/filtersets/nameserver.py +3 -0
  25. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/filtersets/record.py +5 -1
  26. netbox_plugin_dns-1.0.5/netbox_dns/filtersets/record_template.py +54 -0
  27. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/filtersets/registrar.py +3 -0
  28. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/filtersets/view.py +3 -0
  29. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/filtersets/zone.py +5 -8
  30. netbox_plugin_dns-1.0.5/netbox_dns/filtersets/zone_template.py +116 -0
  31. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/forms/__init__.py +2 -0
  32. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/forms/contact.py +8 -0
  33. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/forms/nameserver.py +8 -0
  34. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/forms/record.py +25 -11
  35. netbox_plugin_dns-1.0.5/netbox_dns/forms/record_template.py +220 -0
  36. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/forms/registrar.py +8 -0
  37. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/forms/view.py +10 -0
  38. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/forms/zone.py +109 -36
  39. netbox_plugin_dns-1.0.5/netbox_dns/forms/zone_template.py +298 -0
  40. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/graphql/__init__.py +4 -0
  41. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/graphql/filters.py +24 -1
  42. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/graphql/schema.py +34 -1
  43. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/graphql/types.py +73 -5
  44. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/management/commands/cleanup_database.py +2 -6
  45. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/management/commands/cleanup_rrset_ttl.py +2 -4
  46. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +1 -2
  47. netbox_plugin_dns-1.0.5/netbox_dns/migrations/0006_templating.py +172 -0
  48. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0021_record_ip_address.py +1 -1
  49. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/mixins/object_modification.py +3 -0
  50. netbox_plugin_dns-1.0.5/netbox_dns/models/__init__.py +15 -0
  51. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/models/contact.py +6 -0
  52. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/models/nameserver.py +8 -1
  53. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/models/record.py +10 -122
  54. netbox_plugin_dns-1.0.5/netbox_dns/models/record_template.py +180 -0
  55. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/models/registrar.py +6 -0
  56. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/models/view.py +7 -1
  57. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/models/zone.py +57 -66
  58. netbox_plugin_dns-1.0.5/netbox_dns/models/zone_template.py +149 -0
  59. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/navigation.py +47 -0
  60. {netbox_plugin_dns-1.0.3/netbox_dns/filtersets → netbox_plugin_dns-1.0.5/netbox_dns/tables}/__init__.py +2 -0
  61. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/tables/contact.py +3 -0
  62. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/tables/nameserver.py +3 -2
  63. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/tables/record.py +7 -3
  64. netbox_plugin_dns-1.0.5/netbox_dns/tables/record_template.py +91 -0
  65. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/tables/registrar.py +3 -0
  66. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/tables/view.py +3 -0
  67. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/tables/zone.py +3 -2
  68. netbox_plugin_dns-1.0.5/netbox_dns/tables/zone_template.py +70 -0
  69. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/template_content.py +2 -8
  70. netbox_plugin_dns-1.0.5/netbox_dns/templates/netbox_dns/recordtemplate.html +84 -0
  71. netbox_plugin_dns-1.0.5/netbox_dns/templates/netbox_dns/zonetemplate.html +86 -0
  72. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/urls/__init__.py +4 -0
  73. netbox_plugin_dns-1.0.5/netbox_dns/urls/record_template.py +65 -0
  74. netbox_plugin_dns-1.0.5/netbox_dns/urls/zone_template.py +57 -0
  75. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/utilities/ipam_coupling.py +2 -1
  76. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/validators/__init__.py +1 -0
  77. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/validators/dns_name.py +14 -9
  78. netbox_plugin_dns-1.0.5/netbox_dns/validators/dns_value.py +83 -0
  79. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/validators/rfc2317.py +7 -0
  80. {netbox_plugin_dns-1.0.3/netbox_dns/tables → netbox_plugin_dns-1.0.5/netbox_dns/views}/__init__.py +2 -0
  81. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/views/contact.py +11 -0
  82. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/views/nameserver.py +12 -0
  83. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/views/record.py +14 -1
  84. netbox_plugin_dns-1.0.5/netbox_dns/views/record_template.py +83 -0
  85. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/views/registrar.py +12 -0
  86. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/views/view.py +12 -0
  87. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/views/zone.py +16 -0
  88. netbox_plugin_dns-1.0.5/netbox_dns/views/zone_template.py +73 -0
  89. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/pyproject.toml +1 -1
  90. netbox_plugin_dns-1.0.3/netbox_dns/views/__init__.py +0 -6
  91. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/LICENSE +0 -0
  92. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/api/serializers_/__init__.py +0 -0
  93. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/apps.py +0 -0
  94. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/fields/__init__.py +0 -0
  95. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/management/commands/setup_coupling.py +0 -0
  96. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/management/commands/update_soa.py +0 -0
  97. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
  98. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0002_contact_description_registrar_description.py +0 -0
  99. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0003_default_view.py +0 -0
  100. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0004_create_and_assign_default_view.py +0 -0
  101. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0005_alter_zone_view_not_null.py +0 -0
  102. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
  103. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0022_search.py +0 -0
  104. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
  105. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0024_tenancy.py +0 -0
  106. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
  107. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0026_domain_registration.py +0 -0
  108. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
  109. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
  110. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/0029_record_fqdn.py +0 -0
  111. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/migrations/__init__.py +0 -0
  112. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/mixins/__init__.py +0 -0
  113. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/signals/__init__.py +0 -0
  114. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/signals/ipam_coupling.py +0 -0
  115. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/contact.html +0 -0
  116. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/nameserver.html +0 -0
  117. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
  118. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
  119. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/record.html +0 -0
  120. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/registrar.html +0 -0
  121. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/related_dns_objects.html +0 -0
  122. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/view.html +0 -0
  123. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
  124. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
  125. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/zone/child_zone.html +0 -0
  126. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
  127. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
  128. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
  129. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
  130. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/templates/netbox_dns/zone.html +0 -0
  131. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/urls/contact.py +0 -0
  132. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/urls/nameserver.py +0 -0
  133. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/urls/record.py +0 -0
  134. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/urls/registrar.py +0 -0
  135. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/urls/view.py +0 -0
  136. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/urls/zone.py +0 -0
  137. {netbox_plugin_dns-1.0.3 → netbox_plugin_dns-1.0.5}/netbox_dns/utilities/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-plugin-dns
3
- Version: 1.0.3
3
+ Version: 1.0.5
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
@@ -47,6 +47,7 @@ The main focus of the plugin is to ensure the quality of the data stored in it.
47
47
  * Validation of changes to the SOA SERIAL number, whether they are done automatically or manually
48
48
  * Validation of record types such as CNAME and singletons, to ensure DNS zone validity
49
49
  * Support for [RFC 2317](https://datatracker.ietf.org/doc/html/rfc2317) delegation of PTR zones for IPv4 subnets longer than 24 bits
50
+ * Templating for zones and records enables faster creations of zones with given boilerplate object relations, such as name servers, tags, tenants or registration information, or records like standard SPF or MX records that are the same for a subset of zones
50
51
 
51
52
  Other main features include:
52
53
 
@@ -27,6 +27,7 @@ The main focus of the plugin is to ensure the quality of the data stored in it.
27
27
  * Validation of changes to the SOA SERIAL number, whether they are done automatically or manually
28
28
  * Validation of record types such as CNAME and singletons, to ensure DNS zone validity
29
29
  * Support for [RFC 2317](https://datatracker.ietf.org/doc/html/rfc2317) delegation of PTR zones for IPv4 subnets longer than 24 bits
30
+ * Templating for zones and records enables faster creations of zones with given boilerplate object relations, such as name servers, tags, tenants or registration information, or records like standard SPF or MX records that are the same for a subset of zones
30
31
 
31
32
  Other main features include:
32
33
 
@@ -1,6 +1,6 @@
1
1
  from netbox.plugins import PluginConfig
2
2
 
3
- __version__ = "1.0.3"
3
+ __version__ = "1.0.5"
4
4
 
5
5
 
6
6
  class DNSConfig(PluginConfig):
@@ -2,10 +2,18 @@ from rest_framework import serializers
2
2
 
3
3
  from netbox.api.serializers import WritableNestedSerializer
4
4
 
5
- from netbox_dns.models import Zone, Record
5
+ from netbox_dns.models import Zone, Record, ZoneTemplate, RecordTemplate
6
6
  from netbox_dns.api.serializers_.view import ViewSerializer
7
7
 
8
8
 
9
+ __ALL__ = (
10
+ "NestedZoneSerializer",
11
+ "NestedRecordSerializer",
12
+ "NestedZoneTemplateSerializer",
13
+ "NestedRecordTemplateSerializer",
14
+ )
15
+
16
+
9
17
  class NestedZoneSerializer(WritableNestedSerializer):
10
18
  def to_representation(self, instance):
11
19
  # +
@@ -80,3 +88,40 @@ class NestedRecordSerializer(WritableNestedSerializer):
80
88
  "zone",
81
89
  "active",
82
90
  ]
91
+
92
+
93
+ class NestedRecordTemplateSerializer(WritableNestedSerializer):
94
+ url = serializers.HyperlinkedIdentityField(
95
+ view_name="plugins-api:netbox_dns-api:recordtemplate-detail"
96
+ )
97
+
98
+ class Meta:
99
+ model = RecordTemplate
100
+ fields = (
101
+ "id",
102
+ "url",
103
+ "display",
104
+ "type",
105
+ "name",
106
+ "record_name",
107
+ "value",
108
+ "status",
109
+ "ttl",
110
+ "description",
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
+ )
@@ -4,5 +4,7 @@ from .serializers_.record import *
4
4
  from .serializers_.registrar import *
5
5
  from .serializers_.view import *
6
6
  from .serializers_.zone import *
7
+ from .serializers_.zone_template import *
8
+ from .serializers_.record_template import *
7
9
 
8
10
  from .nested_serializers import *
@@ -5,6 +5,9 @@ from netbox.api.serializers import NetBoxModelSerializer
5
5
  from netbox_dns.models import Contact
6
6
 
7
7
 
8
+ __ALL__ = ("ContactSerializer",)
9
+
10
+
8
11
  class ContactSerializer(NetBoxModelSerializer):
9
12
  url = serializers.HyperlinkedIdentityField(
10
13
  view_name="plugins-api:netbox_dns-api:contact-detail"
@@ -5,7 +5,10 @@ from tenancy.api.serializers_.tenants import TenantSerializer
5
5
 
6
6
  from netbox_dns.models import NameServer
7
7
 
8
- from netbox_dns.api.nested_serializers import NestedZoneSerializer
8
+ from ..nested_serializers import NestedZoneSerializer
9
+
10
+
11
+ __ALL__ = ("NameServerSerializer",)
9
12
 
10
13
 
11
14
  class NameServerSerializer(NetBoxModelSerializer):
@@ -5,10 +5,11 @@ from ipam.api.serializers import IPAddressSerializer
5
5
  from tenancy.api.serializers import TenantSerializer
6
6
 
7
7
  from netbox_dns.models import Record
8
- from netbox_dns.api.nested_serializers import (
9
- NestedZoneSerializer,
10
- NestedRecordSerializer,
11
- )
8
+
9
+ from ..nested_serializers import NestedZoneSerializer, NestedRecordSerializer
10
+
11
+
12
+ __ALL__ = ("RecordSerializer",)
12
13
 
13
14
 
14
15
  class RecordSerializer(NetBoxModelSerializer):
@@ -0,0 +1,57 @@
1
+ from rest_framework import serializers
2
+
3
+ from netbox.api.serializers import NetBoxModelSerializer
4
+ from tenancy.api.serializers import TenantSerializer
5
+
6
+ from netbox_dns.models import RecordTemplate
7
+
8
+ from ..nested_serializers import NestedZoneTemplateSerializer
9
+
10
+ __ALL__ = ("RecordTemplateSerializer",)
11
+
12
+
13
+ class RecordTemplateSerializer(NetBoxModelSerializer):
14
+ url = serializers.HyperlinkedIdentityField(
15
+ view_name="plugins-api:netbox_dns-api:recordtemplate-detail"
16
+ )
17
+ tenant = TenantSerializer(nested=True, required=False, allow_null=True)
18
+ zone_templates = NestedZoneTemplateSerializer(
19
+ many=True,
20
+ read_only=True,
21
+ required=False,
22
+ help_text="Zone templates using the record template",
23
+ )
24
+
25
+ class Meta:
26
+ model = RecordTemplate
27
+ fields = (
28
+ "id",
29
+ "url",
30
+ "display",
31
+ "type",
32
+ "name",
33
+ "record_name",
34
+ "value",
35
+ "status",
36
+ "ttl",
37
+ "description",
38
+ "tags",
39
+ "created",
40
+ "last_updated",
41
+ "disable_ptr",
42
+ "custom_fields",
43
+ "tenant",
44
+ "zone_templates",
45
+ )
46
+ brief_fields = (
47
+ "id",
48
+ "url",
49
+ "display",
50
+ "type",
51
+ "name",
52
+ "record_name",
53
+ "value",
54
+ "status",
55
+ "ttl",
56
+ "description",
57
+ )
@@ -5,6 +5,9 @@ from netbox.api.serializers import NetBoxModelSerializer
5
5
  from netbox_dns.models import Registrar
6
6
 
7
7
 
8
+ __ALL__ = ("RegistrarSerializer",)
9
+
10
+
8
11
  class RegistrarSerializer(NetBoxModelSerializer):
9
12
  url = serializers.HyperlinkedIdentityField(
10
13
  view_name="plugins-api:netbox_dns-api:registrar-detail"
@@ -6,6 +6,9 @@ from tenancy.api.serializers_.tenants import TenantSerializer
6
6
  from netbox_dns.models import View
7
7
 
8
8
 
9
+ __ALL__ = ("ViewSerializer",)
10
+
11
+
9
12
  class ViewSerializer(NetBoxModelSerializer):
10
13
  url = serializers.HyperlinkedIdentityField(
11
14
  view_name="plugins-api:netbox_dns-api:view-detail"
@@ -1,16 +1,20 @@
1
1
  from rest_framework import serializers
2
2
 
3
3
  from netbox.api.serializers import NetBoxModelSerializer
4
- from tenancy.api.serializers_.tenants import TenantSerializer
4
+ from tenancy.api.serializers import TenantSerializer
5
5
 
6
- from netbox_dns.api.serializers_.view import ViewSerializer
7
- from netbox_dns.api.serializers_.nameserver import NameServerSerializer
8
- from netbox_dns.api.serializers_.registrar import RegistrarSerializer
9
- from netbox_dns.api.serializers_.contact import ContactSerializer
10
- from netbox_dns.api.nested_serializers import NestedZoneSerializer
6
+ from .view import ViewSerializer
7
+ from .nameserver import NameServerSerializer
8
+ from .registrar import RegistrarSerializer
9
+ from .contact import ContactSerializer
10
+ from .zone_template import ZoneTemplateSerializer
11
+
12
+ from ..nested_serializers import NestedZoneSerializer
11
13
 
12
14
  from netbox_dns.models import Zone
13
15
 
16
+ __ALL__ = ("NameServerSerializer",)
17
+
14
18
 
15
19
  class ZoneSerializer(NetBoxModelSerializer):
16
20
  url = serializers.HyperlinkedIdentityField(
@@ -58,29 +62,40 @@ class ZoneSerializer(NetBoxModelSerializer):
58
62
  help_text="The registrar the domain is registered with",
59
63
  )
60
64
  registrant = ContactSerializer(
65
+ nested=True,
61
66
  many=False,
62
67
  read_only=False,
63
68
  required=False,
64
69
  help_text="The owner of the domain",
65
70
  )
66
71
  admin_c = ContactSerializer(
72
+ nested=True,
67
73
  many=False,
68
74
  read_only=False,
69
75
  required=False,
70
76
  help_text="The administrative contact for the domain",
71
77
  )
72
78
  tech_c = ContactSerializer(
79
+ nested=True,
73
80
  many=False,
74
81
  read_only=False,
75
82
  required=False,
76
83
  help_text="The technical contact for the domain",
77
84
  )
78
85
  billing_c = ContactSerializer(
86
+ nested=True,
79
87
  many=False,
80
88
  read_only=False,
81
89
  required=False,
82
90
  help_text="The billing contact for the domain",
83
91
  )
92
+ template = ZoneTemplateSerializer(
93
+ nested=True,
94
+ write_only=True,
95
+ required=False,
96
+ default=None,
97
+ help_text="Template to apply to the zone",
98
+ )
84
99
  active = serializers.BooleanField(
85
100
  required=False,
86
101
  read_only=True,
@@ -89,6 +104,7 @@ class ZoneSerializer(NetBoxModelSerializer):
89
104
  tenant = TenantSerializer(nested=True, required=False, allow_null=True)
90
105
 
91
106
  def create(self, validated_data):
107
+ template = validated_data.pop("template", None)
92
108
  nameservers = validated_data.pop("nameservers", None)
93
109
 
94
110
  zone = super().create(validated_data)
@@ -96,9 +112,13 @@ class ZoneSerializer(NetBoxModelSerializer):
96
112
  if nameservers is not None:
97
113
  zone.nameservers.set(nameservers)
98
114
 
115
+ if template is not None:
116
+ template.apply_to_zone(zone)
117
+
99
118
  return zone
100
119
 
101
120
  def update(self, instance, validated_data):
121
+ template = validated_data.pop("template", None)
102
122
  nameservers = validated_data.pop("nameservers", None)
103
123
 
104
124
  zone = super().update(instance, validated_data)
@@ -106,6 +126,9 @@ class ZoneSerializer(NetBoxModelSerializer):
106
126
  if nameservers is not None:
107
127
  zone.nameservers.set(nameservers)
108
128
 
129
+ if template is not None:
130
+ template.apply_to_zone(zone)
131
+
109
132
  return zone
110
133
 
111
134
  class Meta:
@@ -145,6 +168,7 @@ class ZoneSerializer(NetBoxModelSerializer):
145
168
  "active",
146
169
  "custom_fields",
147
170
  "tenant",
171
+ "template",
148
172
  )
149
173
  brief_fields = (
150
174
  "id",
@@ -0,0 +1,129 @@
1
+ from rest_framework import serializers
2
+
3
+ from netbox.api.serializers import NetBoxModelSerializer
4
+ from tenancy.api.serializers_.tenants import TenantSerializer
5
+
6
+ from netbox_dns.models import ZoneTemplate
7
+ from netbox_dns.api.nested_serializers import NestedRecordTemplateSerializer
8
+
9
+ from .nameserver import NameServerSerializer
10
+ from .registrar import RegistrarSerializer
11
+ from .contact import ContactSerializer
12
+
13
+ __ALL__ = ("ZoneTemplateSerializer",)
14
+
15
+
16
+ class ZoneTemplateSerializer(NetBoxModelSerializer):
17
+ url = serializers.HyperlinkedIdentityField(
18
+ view_name="plugins-api:netbox_dns-api:zonetemplate-detail"
19
+ )
20
+ nameservers = NameServerSerializer(
21
+ nested=True,
22
+ many=True,
23
+ read_only=False,
24
+ required=False,
25
+ help_text="Nameservers for the zone",
26
+ )
27
+ record_templates = NestedRecordTemplateSerializer(
28
+ many=True,
29
+ read_only=False,
30
+ required=False,
31
+ help_text="Record templates assigned to the zone",
32
+ )
33
+ registrar = RegistrarSerializer(
34
+ nested=True,
35
+ many=False,
36
+ read_only=False,
37
+ required=False,
38
+ help_text="The registrar the domain is registered with",
39
+ )
40
+ registrant = ContactSerializer(
41
+ nested=True,
42
+ many=False,
43
+ read_only=False,
44
+ required=False,
45
+ help_text="The owner of the domain",
46
+ )
47
+ admin_c = ContactSerializer(
48
+ nested=True,
49
+ many=False,
50
+ read_only=False,
51
+ required=False,
52
+ help_text="The administrative contact for the domain",
53
+ )
54
+ tech_c = ContactSerializer(
55
+ nested=True,
56
+ many=False,
57
+ read_only=False,
58
+ required=False,
59
+ help_text="The technical contact for the domain",
60
+ )
61
+ billing_c = ContactSerializer(
62
+ nested=True,
63
+ many=False,
64
+ read_only=False,
65
+ required=False,
66
+ help_text="The billing contact for the domain",
67
+ )
68
+ active = serializers.BooleanField(
69
+ required=False,
70
+ read_only=True,
71
+ allow_null=True,
72
+ )
73
+ tenant = TenantSerializer(nested=True, required=False, allow_null=True)
74
+
75
+ def create(self, validated_data):
76
+ nameservers = validated_data.pop("nameservers", None)
77
+ record_templates = validated_data.pop("record_templates", None)
78
+
79
+ zone_template = super().create(validated_data)
80
+
81
+ if nameservers is not None:
82
+ zone_template.nameservers.set(nameservers)
83
+ if record_templates is not None:
84
+ zone_template.record_templates.set(record_templates)
85
+
86
+ return zone_template
87
+
88
+ def update(self, instance, validated_data):
89
+ nameservers = validated_data.pop("nameservers", None)
90
+ record_templates = validated_data.pop("record_templates", None)
91
+
92
+ zone_template = super().update(instance, validated_data)
93
+
94
+ if nameservers is not None:
95
+ zone_template.nameservers.set(nameservers)
96
+ if record_templates is not None:
97
+ zone_template.record_templates.set(record_templates)
98
+
99
+ return zone_template
100
+
101
+ class Meta:
102
+ model = ZoneTemplate
103
+ fields = (
104
+ "id",
105
+ "url",
106
+ "name",
107
+ "display",
108
+ "nameservers",
109
+ "description",
110
+ "tags",
111
+ "created",
112
+ "last_updated",
113
+ "registrar",
114
+ "registrant",
115
+ "tech_c",
116
+ "admin_c",
117
+ "billing_c",
118
+ "active",
119
+ "custom_fields",
120
+ "tenant",
121
+ "record_templates",
122
+ )
123
+ brief_fields = (
124
+ "id",
125
+ "url",
126
+ "name",
127
+ "display",
128
+ "description",
129
+ )
@@ -8,6 +8,8 @@ from netbox_dns.api.views import (
8
8
  RecordViewSet,
9
9
  RegistrarViewSet,
10
10
  ContactViewSet,
11
+ ZoneTemplateViewSet,
12
+ RecordTemplateViewSet,
11
13
  )
12
14
 
13
15
  router = NetBoxRouter()
@@ -19,5 +21,7 @@ router.register("nameservers", NameServerViewSet)
19
21
  router.register("records", RecordViewSet)
20
22
  router.register("registrars", RegistrarViewSet)
21
23
  router.register("contacts", ContactViewSet)
24
+ router.register("zonetemplates", ZoneTemplateViewSet)
25
+ router.register("recordtemplates", RecordTemplateViewSet)
22
26
 
23
27
  urlpatterns = router.urls
@@ -12,6 +12,8 @@ from netbox_dns.api.serializers import (
12
12
  RecordSerializer,
13
13
  RegistrarSerializer,
14
14
  ContactSerializer,
15
+ ZoneTemplateSerializer,
16
+ RecordTemplateSerializer,
15
17
  )
16
18
  from netbox_dns.filtersets import (
17
19
  ViewFilterSet,
@@ -20,8 +22,19 @@ from netbox_dns.filtersets import (
20
22
  RecordFilterSet,
21
23
  RegistrarFilterSet,
22
24
  ContactFilterSet,
25
+ ZoneTemplateFilterSet,
26
+ RecordTemplateFilterSet,
27
+ )
28
+ from netbox_dns.models import (
29
+ View,
30
+ Zone,
31
+ NameServer,
32
+ Record,
33
+ Registrar,
34
+ Contact,
35
+ ZoneTemplate,
36
+ RecordTemplate,
23
37
  )
24
- from netbox_dns.models import View, Zone, NameServer, Record, Registrar, Contact
25
38
 
26
39
 
27
40
  class NetBoxDNSRootView(APIRootView):
@@ -85,6 +98,16 @@ class RecordViewSet(NetBoxModelViewSet):
85
98
  serializer_class = RecordSerializer
86
99
  filterset_class = RecordFilterSet
87
100
 
101
+ def create(self, request, *args, **kwargs):
102
+ data = request.data
103
+ if not isinstance(data, list):
104
+ data = [data]
105
+
106
+ if any(record.get("managed") for record in data):
107
+ raise serializers.ValidationError("'managed' is True, refusing create")
108
+
109
+ return super().create(request, *args, **kwargs)
110
+
88
111
  def destroy(self, request, *args, **kwargs):
89
112
  v_object = self.get_object()
90
113
  if v_object.managed:
@@ -99,6 +122,11 @@ class RecordViewSet(NetBoxModelViewSet):
99
122
  if v_object.managed:
100
123
  raise serializers.ValidationError(f"{v_object} is managed, refusing update")
101
124
 
125
+ if request.data.get("managed"):
126
+ raise serializers.ValidationError(
127
+ f"{v_object} is unmanaged, refusing update to managed"
128
+ )
129
+
102
130
  return super().update(request, *args, **kwargs)
103
131
 
104
132
 
@@ -112,3 +140,15 @@ class ContactViewSet(NetBoxModelViewSet):
112
140
  queryset = Contact.objects.all()
113
141
  serializer_class = ContactSerializer
114
142
  filterset_class = ContactFilterSet
143
+
144
+
145
+ class ZoneTemplateViewSet(NetBoxModelViewSet):
146
+ queryset = ZoneTemplate.objects.all()
147
+ serializer_class = ZoneTemplateSerializer
148
+ filterset_class = ZoneTemplateFilterSet
149
+
150
+
151
+ class RecordTemplateViewSet(NetBoxModelViewSet):
152
+ queryset = RecordTemplate.objects.all()
153
+ serializer_class = RecordTemplateSerializer
154
+ filterset_class = RecordTemplateFilterSet
@@ -0,0 +1,2 @@
1
+ from .record import *
2
+ from .zone import *
@@ -0,0 +1,49 @@
1
+ from dns import rdatatype, rdataclass
2
+
3
+ from utilities.choices import ChoiceSet
4
+
5
+
6
+ def initialize_choice_names(cls):
7
+ for choice in cls.CHOICES:
8
+ setattr(cls, choice[0], choice[0])
9
+ return cls
10
+
11
+
12
+ __ALL__ = (
13
+ "RecordTypeChoices",
14
+ "RecordClassChoices",
15
+ "RecordStatusChoices",
16
+ )
17
+
18
+
19
+ @initialize_choice_names
20
+ class RecordTypeChoices(ChoiceSet):
21
+ CHOICES = [
22
+ (rdtype.name, rdtype.name)
23
+ for rdtype in sorted(rdatatype.RdataType, key=lambda a: a.name)
24
+ if not rdatatype.is_metatype(rdtype)
25
+ ]
26
+ SINGLETONS = [
27
+ rdtype.name for rdtype in rdatatype.RdataType if rdatatype.is_singleton(rdtype)
28
+ ]
29
+
30
+
31
+ @initialize_choice_names
32
+ class RecordClassChoices(ChoiceSet):
33
+ CHOICES = [
34
+ (rdclass.name, rdclass.name)
35
+ for rdclass in sorted(rdataclass.RdataClass)
36
+ if not rdataclass.is_metaclass(rdclass)
37
+ ]
38
+
39
+
40
+ class RecordStatusChoices(ChoiceSet):
41
+ key = "Record.status"
42
+
43
+ STATUS_ACTIVE = "active"
44
+ STATUS_INACTIVE = "inactive"
45
+
46
+ CHOICES = [
47
+ (STATUS_ACTIVE, "Active", "blue"),
48
+ (STATUS_INACTIVE, "Inactive", "red"),
49
+ ]
@@ -0,0 +1,20 @@
1
+ from utilities.choices import ChoiceSet
2
+
3
+
4
+ __ALL__ = ("ZoneStatusChoices",)
5
+
6
+
7
+ class ZoneStatusChoices(ChoiceSet):
8
+ key = "Zone.status"
9
+
10
+ STATUS_ACTIVE = "active"
11
+ STATUS_RESERVED = "reserved"
12
+ STATUS_DEPRECATED = "deprecated"
13
+ STATUS_PARKED = "parked"
14
+
15
+ CHOICES = [
16
+ (STATUS_ACTIVE, "Active", "blue"),
17
+ (STATUS_RESERVED, "Reserved", "cyan"),
18
+ (STATUS_DEPRECATED, "Deprecated", "red"),
19
+ (STATUS_PARKED, "Parked", "gray"),
20
+ ]
@@ -5,6 +5,12 @@ from django.core.exceptions import ValidationError
5
5
  from netaddr import AddrFormatError, IPAddress
6
6
 
7
7
 
8
+ __ALL__ = (
9
+ "AddressFormField",
10
+ "AddressField",
11
+ )
12
+
13
+
8
14
  class AddressFormField(forms.Field):
9
15
  def to_python(self, value):
10
16
  if not value:
@@ -6,6 +6,9 @@ from django.core.exceptions import ValidationError
6
6
  from netaddr import AddrFormatError, IPNetwork
7
7
 
8
8
 
9
+ __ALL__ = ()
10
+
11
+
9
12
  class NetContains(Lookup):
10
13
  lookup_name = "net_contains"
11
14
 
@@ -10,6 +10,9 @@ from .network import NetContains, NetContained, NetOverlap, NetMaskLength
10
10
  INVALID_RFC2317 = "RFC2317 requires an IPv4 prefix with a length of at least 25 bits."
11
11
 
12
12
 
13
+ __ALL__ = ()
14
+
15
+
13
16
  class RFC2317NetworkFormField(forms.Field):
14
17
  def to_python(self, value):
15
18
  if not value:
@@ -1,8 +1,9 @@
1
+ from .view import *
1
2
  from .zone import *
2
3
  from .nameserver import *
3
4
  from .record import *
4
- from .view import *
5
5
  from .contact import *
6
6
  from .registrar import *
7
7
 
8
- from netbox_dns.signals import ipam_coupling
8
+ from .zone_template import *
9
+ from .record_template import *