netbox-plugin-dns 1.0.3__py3-none-any.whl → 1.0.5__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.
Potentially problematic release.
This version of netbox-plugin-dns might be problematic. Click here for more details.
- netbox_dns/__init__.py +1 -1
- netbox_dns/api/nested_serializers.py +46 -1
- netbox_dns/api/serializers.py +2 -0
- netbox_dns/api/serializers_/contact.py +3 -0
- netbox_dns/api/serializers_/nameserver.py +4 -1
- netbox_dns/api/serializers_/record.py +5 -4
- netbox_dns/api/serializers_/record_template.py +57 -0
- netbox_dns/api/serializers_/registrar.py +3 -0
- netbox_dns/api/serializers_/view.py +3 -0
- netbox_dns/api/serializers_/zone.py +30 -6
- netbox_dns/api/serializers_/zone_template.py +129 -0
- netbox_dns/api/urls.py +4 -0
- netbox_dns/api/views.py +41 -1
- netbox_dns/choices/__init__.py +2 -0
- netbox_dns/choices/record.py +49 -0
- netbox_dns/choices/zone.py +20 -0
- netbox_dns/fields/address.py +6 -0
- netbox_dns/fields/network.py +3 -0
- netbox_dns/fields/rfc2317.py +3 -0
- netbox_dns/filtersets/__init__.py +3 -0
- netbox_dns/filtersets/contact.py +3 -0
- netbox_dns/filtersets/nameserver.py +3 -0
- netbox_dns/filtersets/record.py +5 -1
- netbox_dns/filtersets/record_template.py +54 -0
- netbox_dns/filtersets/registrar.py +3 -0
- netbox_dns/filtersets/view.py +3 -0
- netbox_dns/filtersets/zone.py +5 -8
- netbox_dns/filtersets/zone_template.py +116 -0
- netbox_dns/forms/__init__.py +2 -0
- netbox_dns/forms/contact.py +8 -0
- netbox_dns/forms/nameserver.py +8 -0
- netbox_dns/forms/record.py +25 -11
- netbox_dns/forms/record_template.py +220 -0
- netbox_dns/forms/registrar.py +8 -0
- netbox_dns/forms/view.py +10 -0
- netbox_dns/forms/zone.py +109 -36
- netbox_dns/forms/zone_template.py +298 -0
- netbox_dns/graphql/__init__.py +4 -0
- netbox_dns/graphql/filters.py +24 -1
- netbox_dns/graphql/schema.py +34 -1
- netbox_dns/graphql/types.py +73 -5
- netbox_dns/management/commands/cleanup_database.py +2 -6
- netbox_dns/management/commands/cleanup_rrset_ttl.py +2 -4
- netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +1 -2
- netbox_dns/migrations/0006_templating.py +172 -0
- netbox_dns/migrations/0021_record_ip_address.py +1 -1
- netbox_dns/mixins/object_modification.py +3 -0
- netbox_dns/models/__init__.py +7 -0
- netbox_dns/models/contact.py +6 -0
- netbox_dns/models/nameserver.py +8 -1
- netbox_dns/models/record.py +10 -122
- netbox_dns/models/record_template.py +180 -0
- netbox_dns/models/registrar.py +6 -0
- netbox_dns/models/view.py +7 -1
- netbox_dns/models/zone.py +57 -66
- netbox_dns/models/zone_template.py +149 -0
- netbox_dns/navigation.py +47 -0
- netbox_dns/tables/__init__.py +2 -0
- netbox_dns/tables/contact.py +3 -0
- netbox_dns/tables/nameserver.py +3 -2
- netbox_dns/tables/record.py +7 -3
- netbox_dns/tables/record_template.py +91 -0
- netbox_dns/tables/registrar.py +3 -0
- netbox_dns/tables/view.py +3 -0
- netbox_dns/tables/zone.py +3 -2
- netbox_dns/tables/zone_template.py +70 -0
- netbox_dns/template_content.py +2 -8
- netbox_dns/templates/netbox_dns/recordtemplate.html +84 -0
- netbox_dns/templates/netbox_dns/zonetemplate.html +86 -0
- netbox_dns/urls/__init__.py +4 -0
- netbox_dns/urls/record_template.py +65 -0
- netbox_dns/urls/zone_template.py +57 -0
- netbox_dns/utilities/ipam_coupling.py +2 -1
- netbox_dns/validators/__init__.py +1 -0
- netbox_dns/validators/dns_name.py +14 -9
- netbox_dns/validators/dns_value.py +83 -0
- netbox_dns/validators/rfc2317.py +7 -0
- netbox_dns/views/__init__.py +2 -0
- netbox_dns/views/contact.py +11 -0
- netbox_dns/views/nameserver.py +12 -0
- netbox_dns/views/record.py +14 -1
- netbox_dns/views/record_template.py +83 -0
- netbox_dns/views/registrar.py +12 -0
- netbox_dns/views/view.py +12 -0
- netbox_dns/views/zone.py +16 -0
- netbox_dns/views/zone_template.py +73 -0
- {netbox_plugin_dns-1.0.3.dist-info → netbox_plugin_dns-1.0.5.dist-info}/METADATA +2 -1
- netbox_plugin_dns-1.0.5.dist-info/RECORD +136 -0
- netbox_plugin_dns-1.0.3.dist-info/RECORD +0 -115
- {netbox_plugin_dns-1.0.3.dist-info → netbox_plugin_dns-1.0.5.dist-info}/LICENSE +0 -0
- {netbox_plugin_dns-1.0.3.dist-info → netbox_plugin_dns-1.0.5.dist-info}/WHEEL +0 -0
netbox_dns/__init__.py
CHANGED
|
@@ -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
|
+
)
|
netbox_dns/api/serializers.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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.
|
|
4
|
+
from tenancy.api.serializers import TenantSerializer
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
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
|
+
)
|
netbox_dns/api/urls.py
CHANGED
|
@@ -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
|
netbox_dns/api/views.py
CHANGED
|
@@ -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,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
|
+
]
|
netbox_dns/fields/address.py
CHANGED
netbox_dns/fields/network.py
CHANGED
netbox_dns/fields/rfc2317.py
CHANGED
|
@@ -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:
|
netbox_dns/filtersets/contact.py
CHANGED
|
@@ -7,6 +7,9 @@ from tenancy.filtersets import TenancyFilterSet
|
|
|
7
7
|
from netbox_dns.models import NameServer, Zone
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
__ALL__ = ("NameServerFilterSet",)
|
|
11
|
+
|
|
12
|
+
|
|
10
13
|
class NameServerFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
|
|
11
14
|
zone_id = django_filters.ModelMultipleChoiceFilter(
|
|
12
15
|
field_name="zones",
|
netbox_dns/filtersets/record.py
CHANGED
|
@@ -9,7 +9,11 @@ from utilities.filters import MultiValueCharFilter
|
|
|
9
9
|
|
|
10
10
|
from ipam.models import IPAddress
|
|
11
11
|
|
|
12
|
-
from netbox_dns.models import View, Zone, Record
|
|
12
|
+
from netbox_dns.models import View, Zone, Record
|
|
13
|
+
from netbox_dns.choices import RecordTypeChoices, RecordStatusChoices
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__ALL__ = ("RecordFilterSet",)
|
|
13
17
|
|
|
14
18
|
|
|
15
19
|
class RecordFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
|