netbox-plugin-dns 0.22.9__tar.gz → 1.0b1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of netbox-plugin-dns might be problematic. Click here for more details.
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/PKG-INFO +5 -7
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/README.md +2 -2
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/__init__.py +3 -14
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/api/nested_serializers.py +4 -60
- netbox_plugin_dns-1.0b1/netbox_dns/api/serializers.py +8 -0
- netbox_plugin_dns-1.0b1/netbox_dns/api/serializers_/contact.py +37 -0
- netbox_plugin_dns-1.0b1/netbox_dns/api/serializers_/nameserver.py +39 -0
- netbox_plugin_dns-1.0b1/netbox_dns/api/serializers_/record.py +90 -0
- netbox_plugin_dns-1.0b1/netbox_dns/api/serializers_/registrar.py +31 -0
- netbox_plugin_dns-1.0b1/netbox_dns/api/serializers_/view.py +29 -0
- netbox_plugin_dns-1.0b1/netbox_dns/api/serializers_/zone.py +170 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/api/views.py +13 -13
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/fields/network.py +1 -1
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/fields/rfc2317.py +1 -1
- {netbox_plugin_dns-0.22.9/netbox_dns/filters → netbox_plugin_dns-1.0b1/netbox_dns/filtersets}/contact.py +2 -1
- netbox_plugin_dns-1.0b1/netbox_dns/filtersets/nameserver.py +37 -0
- {netbox_plugin_dns-0.22.9/netbox_dns/filters → netbox_plugin_dns-1.0b1/netbox_dns/filtersets}/record.py +51 -6
- {netbox_plugin_dns-0.22.9/netbox_dns/filters → netbox_plugin_dns-1.0b1/netbox_dns/filtersets}/registrar.py +2 -1
- {netbox_plugin_dns-0.22.9/netbox_dns/filters → netbox_plugin_dns-1.0b1/netbox_dns/filtersets}/view.py +2 -2
- netbox_plugin_dns-1.0b1/netbox_dns/filtersets/zone.py +205 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/forms/contact.py +61 -33
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/forms/nameserver.py +21 -8
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/forms/record.py +35 -36
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/forms/registrar.py +45 -15
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/forms/view.py +19 -8
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/forms/zone.py +112 -87
- netbox_plugin_dns-1.0b1/netbox_dns/graphql/__init__.py +17 -0
- netbox_plugin_dns-1.0b1/netbox_dns/graphql/filters.py +49 -0
- netbox_plugin_dns-1.0b1/netbox_dns/graphql/schema.py +70 -0
- netbox_plugin_dns-1.0b1/netbox_dns/graphql/types.py +146 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/management/commands/cleanup_database.py +0 -4
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/management/commands/cleanup_rrset_ttl.py +3 -5
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/management/commands/setup_coupling.py +15 -15
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/management/commands/update_soa.py +1 -1
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -27
- netbox_plugin_dns-1.0b1/netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +556 -0
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0013_add_nameserver_zone_record_description.py → netbox_plugin_dns-1.0b1/netbox_dns/migrations/0002_contact_description_registrar_description.py +4 -9
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0020_netbox_3_4.py +1 -1
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/models/contact.py +6 -1
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/models/nameserver.py +3 -3
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/models/record.py +8 -15
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/models/registrar.py +5 -1
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/models/view.py +1 -1
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/models/zone.py +6 -9
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/navigation.py +1 -15
- netbox_plugin_dns-1.0b1/netbox_dns/signals/__init__.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/signals/ipam_coupling.py +3 -8
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/tables/contact.py +1 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/tables/nameserver.py +0 -2
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/tables/registrar.py +1 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/template_content.py +3 -7
- netbox_plugin_dns-1.0b1/netbox_dns/templates/netbox_dns/contact.html +75 -0
- netbox_plugin_dns-1.0b1/netbox_dns/templates/netbox_dns/nameserver.html +42 -0
- netbox_plugin_dns-1.0b1/netbox_dns/templates/netbox_dns/record.html +146 -0
- netbox_plugin_dns-1.0b1/netbox_dns/templates/netbox_dns/registrar.html +56 -0
- netbox_plugin_dns-1.0b1/netbox_dns/templates/netbox_dns/view.html +36 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/templates/netbox_dns/zone/base.html +5 -3
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/templates/netbox_dns/zone/child.html +3 -3
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/templates/netbox_dns/zone/managed_record.html +1 -1
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/templates/netbox_dns/zone/record.html +3 -3
- netbox_plugin_dns-1.0b1/netbox_dns/templates/netbox_dns/zone/registration.html +39 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +1 -1
- netbox_plugin_dns-1.0b1/netbox_dns/templates/netbox_dns/zone.html +179 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/utilities/__init__.py +1 -6
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/utilities/ipam_coupling.py +2 -7
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/validators/dns_name.py +4 -9
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/validators/rfc2317.py +2 -2
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/views/contact.py +4 -4
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/views/nameserver.py +5 -5
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/views/record.py +19 -12
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/views/registrar.py +4 -4
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/views/view.py +4 -4
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/views/zone.py +7 -8
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/pyproject.toml +3 -3
- netbox_plugin_dns-0.22.9/netbox_dns/api/serializers.py +0 -314
- netbox_plugin_dns-0.22.9/netbox_dns/filters/nameserver.py +0 -18
- netbox_plugin_dns-0.22.9/netbox_dns/filters/zone.py +0 -112
- netbox_plugin_dns-0.22.9/netbox_dns/graphql/__init__.py +0 -27
- netbox_plugin_dns-0.22.9/netbox_dns/graphql/contact.py +0 -19
- netbox_plugin_dns-0.22.9/netbox_dns/graphql/nameserver.py +0 -19
- netbox_plugin_dns-0.22.9/netbox_dns/graphql/record.py +0 -19
- netbox_plugin_dns-0.22.9/netbox_dns/graphql/registrar.py +0 -19
- netbox_plugin_dns-0.22.9/netbox_dns/graphql/schema.py +0 -11
- netbox_plugin_dns-0.22.9/netbox_dns/graphql/view.py +0 -19
- netbox_plugin_dns-0.22.9/netbox_dns/graphql/zone.py +0 -19
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0001_initial.py +0 -115
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0002_zone_default_ttl.py +0 -18
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0003_soa_managed_records.py +0 -112
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0004_create_ptr_for_a_aaaa_records.py +0 -80
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0005_update_ns_records.py +0 -41
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0006_zone_soa_serial_auto.py +0 -29
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0007_alter_zone_soa_serial_auto.py +0 -17
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0008_zone_status_names.py +0 -21
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0009_netbox32.py +0 -71
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0010_update_soa_records.py +0 -58
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0011_add_view_model.py +0 -70
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0012_adjust_zone_and_record.py +0 -17
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0014_add_view_description.py +0 -16
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0015_add_record_status.py +0 -17
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0016_cleanup_ptr_records.py +0 -38
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0017_alter_record_ttl.py +0 -17
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0018_zone_arpa_network.py +0 -51
- netbox_plugin_dns-0.22.9/netbox_dns/migrations/0019_update_ns_ttl.py +0 -19
- netbox_plugin_dns-0.22.9/netbox_dns/templates/netbox_dns/contact.html +0 -71
- netbox_plugin_dns-0.22.9/netbox_dns/templates/netbox_dns/nameserver.html +0 -42
- netbox_plugin_dns-0.22.9/netbox_dns/templates/netbox_dns/record.html +0 -148
- netbox_plugin_dns-0.22.9/netbox_dns/templates/netbox_dns/registrar.html +0 -54
- netbox_plugin_dns-0.22.9/netbox_dns/templates/netbox_dns/view.html +0 -36
- netbox_plugin_dns-0.22.9/netbox_dns/templates/netbox_dns/zone/registration.html +0 -40
- netbox_plugin_dns-0.22.9/netbox_dns/templates/netbox_dns/zone.html +0 -178
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/LICENSE +0 -0
- {netbox_plugin_dns-0.22.9/netbox_dns/migrations → netbox_plugin_dns-1.0b1/netbox_dns/api/serializers_}/__init__.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/api/urls.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/apps.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/fields/__init__.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/fields/address.py +0 -0
- {netbox_plugin_dns-0.22.9/netbox_dns/filters → netbox_plugin_dns-1.0b1/netbox_dns/filtersets}/__init__.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/forms/__init__.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0022_search.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0024_tenancy.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0026_domain_registration.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/migrations/0029_record_fqdn.py +0 -0
- {netbox_plugin_dns-0.22.9/netbox_dns/signals → netbox_plugin_dns-1.0b1/netbox_dns/migrations}/__init__.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/models/__init__.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/tables/__init__.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/tables/record.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/tables/view.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/tables/zone.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/templates/netbox_dns/related_dns_objects.html +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/urls.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/validators/__init__.py +0 -0
- {netbox_plugin_dns-0.22.9 → netbox_plugin_dns-1.0b1}/netbox_dns/views/__init__.py +0 -0
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: netbox-plugin-dns
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.0b1
|
|
4
4
|
Summary: NetBox DNS is a NetBox plugin for managing DNS data.
|
|
5
5
|
Home-page: https://github.com/peteeckel/netbox-plugin-dns
|
|
6
6
|
License: MIT
|
|
7
7
|
Keywords: netbox,netbox-plugin,dns
|
|
8
8
|
Author: Peter Eckel
|
|
9
9
|
Author-email: pete@netbox-dns.org
|
|
10
|
-
Requires-Python: >=3.
|
|
11
|
-
Classifier: Development Status ::
|
|
10
|
+
Requires-Python: >=3.10,<4.0
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
16
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -49,8 +47,8 @@ NetBox DNS is using the standardized NetBox plugin interface, so it also takes a
|
|
|
49
47
|
|
|
50
48
|
## Requirements
|
|
51
49
|
|
|
52
|
-
* NetBox
|
|
53
|
-
* Python 3.
|
|
50
|
+
* NetBox 4.0.0 or higher
|
|
51
|
+
* Python 3.10 or higher
|
|
54
52
|
|
|
55
53
|
## Installation & Configuration
|
|
56
54
|
|
|
@@ -1,24 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
from netbox.plugins import PluginConfig
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
from django.db.utils import OperationalError
|
|
5
|
-
|
|
6
|
-
try:
|
|
7
|
-
# NetBox 3.5.0 - 3.5.7, 3.5.9+
|
|
8
|
-
from extras.plugins import get_plugin_config
|
|
9
|
-
except ImportError:
|
|
10
|
-
# NetBox 3.5.8
|
|
11
|
-
from extras.plugins.utils import get_plugin_config
|
|
12
|
-
|
|
13
|
-
__version__ = "0.22.9"
|
|
3
|
+
__version__ = "1.0-beta1"
|
|
14
4
|
|
|
15
5
|
|
|
16
6
|
class DNSConfig(PluginConfig):
|
|
17
7
|
name = "netbox_dns"
|
|
18
8
|
verbose_name = "NetBox DNS"
|
|
19
9
|
description = "NetBox plugin for DNS data"
|
|
20
|
-
min_version = "
|
|
21
|
-
max_version = "3.99.0"
|
|
10
|
+
min_version = "4.0-beta1"
|
|
22
11
|
version = __version__
|
|
23
12
|
author = "Peter Eckel"
|
|
24
13
|
author_email = "pete@netbox-dns.org"
|
|
@@ -2,25 +2,10 @@ from rest_framework import serializers
|
|
|
2
2
|
|
|
3
3
|
from netbox.api.serializers import WritableNestedSerializer
|
|
4
4
|
|
|
5
|
-
from netbox_dns.models import
|
|
5
|
+
from netbox_dns.models import Zone, Record
|
|
6
|
+
from netbox_dns.api.serializers_.view import ViewSerializer
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
#
|
|
9
|
-
# Views
|
|
10
|
-
#
|
|
11
|
-
class NestedViewSerializer(WritableNestedSerializer):
|
|
12
|
-
url = serializers.HyperlinkedIdentityField(
|
|
13
|
-
view_name="plugins-api:netbox_dns-api:view-detail"
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
class Meta:
|
|
17
|
-
model = View
|
|
18
|
-
fields = ["id", "url", "display", "name"]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
#
|
|
22
|
-
# Zones
|
|
23
|
-
#
|
|
24
9
|
class NestedZoneSerializer(WritableNestedSerializer):
|
|
25
10
|
def to_representation(self, instance):
|
|
26
11
|
# +
|
|
@@ -39,7 +24,8 @@ class NestedZoneSerializer(WritableNestedSerializer):
|
|
|
39
24
|
url = serializers.HyperlinkedIdentityField(
|
|
40
25
|
view_name="plugins-api:netbox_dns-api:zone-detail"
|
|
41
26
|
)
|
|
42
|
-
view =
|
|
27
|
+
view = ViewSerializer(
|
|
28
|
+
nested=True,
|
|
43
29
|
many=False,
|
|
44
30
|
required=False,
|
|
45
31
|
read_only=True,
|
|
@@ -65,22 +51,6 @@ class NestedZoneSerializer(WritableNestedSerializer):
|
|
|
65
51
|
]
|
|
66
52
|
|
|
67
53
|
|
|
68
|
-
#
|
|
69
|
-
# Nameservers
|
|
70
|
-
#
|
|
71
|
-
class NestedNameServerSerializer(WritableNestedSerializer):
|
|
72
|
-
url = serializers.HyperlinkedIdentityField(
|
|
73
|
-
view_name="plugins-api:netbox_dns-api:nameserver-detail"
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
class Meta:
|
|
77
|
-
model = NameServer
|
|
78
|
-
fields = ["id", "url", "display", "name"]
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
#
|
|
82
|
-
# Records
|
|
83
|
-
#
|
|
84
54
|
class NestedRecordSerializer(WritableNestedSerializer):
|
|
85
55
|
url = serializers.HyperlinkedIdentityField(
|
|
86
56
|
view_name="plugins-api:netbox_dns-api:record-detail"
|
|
@@ -110,29 +80,3 @@ class NestedRecordSerializer(WritableNestedSerializer):
|
|
|
110
80
|
"zone",
|
|
111
81
|
"active",
|
|
112
82
|
]
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
#
|
|
116
|
-
# Registrars
|
|
117
|
-
#
|
|
118
|
-
class NestedRegistrarSerializer(WritableNestedSerializer):
|
|
119
|
-
url = serializers.HyperlinkedIdentityField(
|
|
120
|
-
view_name="plugins-api:netbox_dns-api:registrar-detail"
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
class Meta:
|
|
124
|
-
model = Registrar
|
|
125
|
-
fields = ["display", "id", "url", "name", "iana_id"]
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
#
|
|
129
|
-
# Contacts
|
|
130
|
-
#
|
|
131
|
-
class NestedContactSerializer(WritableNestedSerializer):
|
|
132
|
-
url = serializers.HyperlinkedIdentityField(
|
|
133
|
-
view_name="plugins-api:netbox_dns-api:contact-detail"
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
class Meta:
|
|
137
|
-
model = Contact
|
|
138
|
-
fields = ["display", "id", "url", "name", "contact_id"]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
|
|
3
|
+
from netbox.api.serializers import NetBoxModelSerializer
|
|
4
|
+
|
|
5
|
+
from netbox_dns.models import Contact
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ContactSerializer(NetBoxModelSerializer):
|
|
9
|
+
url = serializers.HyperlinkedIdentityField(
|
|
10
|
+
view_name="plugins-api:netbox_dns-api:contact-detail"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
class Meta:
|
|
14
|
+
model = Contact
|
|
15
|
+
fields = (
|
|
16
|
+
"id",
|
|
17
|
+
"url",
|
|
18
|
+
"display",
|
|
19
|
+
"name",
|
|
20
|
+
"description",
|
|
21
|
+
"contact_id",
|
|
22
|
+
"organization",
|
|
23
|
+
"street",
|
|
24
|
+
"city",
|
|
25
|
+
"state_province",
|
|
26
|
+
"postal_code",
|
|
27
|
+
"country",
|
|
28
|
+
"phone",
|
|
29
|
+
"phone_ext",
|
|
30
|
+
"fax",
|
|
31
|
+
"fax_ext",
|
|
32
|
+
"email",
|
|
33
|
+
"created",
|
|
34
|
+
"last_updated",
|
|
35
|
+
"custom_fields",
|
|
36
|
+
)
|
|
37
|
+
brief_fields = ("id", "url", "display", "name", "description", "contact_id")
|
|
@@ -0,0 +1,39 @@
|
|
|
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 NameServer
|
|
7
|
+
|
|
8
|
+
from netbox_dns.api.nested_serializers import NestedZoneSerializer
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class NameServerSerializer(NetBoxModelSerializer):
|
|
12
|
+
url = serializers.HyperlinkedIdentityField(
|
|
13
|
+
view_name="plugins-api:netbox_dns-api:nameserver-detail"
|
|
14
|
+
)
|
|
15
|
+
zones = NestedZoneSerializer(
|
|
16
|
+
many=True,
|
|
17
|
+
read_only=True,
|
|
18
|
+
required=False,
|
|
19
|
+
default=None,
|
|
20
|
+
help_text="Zones served by the authoritative nameserver",
|
|
21
|
+
)
|
|
22
|
+
tenant = TenantSerializer(required=False, allow_null=True)
|
|
23
|
+
|
|
24
|
+
class Meta:
|
|
25
|
+
model = NameServer
|
|
26
|
+
fields = (
|
|
27
|
+
"id",
|
|
28
|
+
"url",
|
|
29
|
+
"display",
|
|
30
|
+
"name",
|
|
31
|
+
"description",
|
|
32
|
+
"tags",
|
|
33
|
+
"zones",
|
|
34
|
+
"created",
|
|
35
|
+
"last_updated",
|
|
36
|
+
"custom_fields",
|
|
37
|
+
"tenant",
|
|
38
|
+
)
|
|
39
|
+
brief_fields = ("id", "url", "display", "name", "description")
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
|
|
3
|
+
from netbox.api.serializers import NetBoxModelSerializer
|
|
4
|
+
from ipam.api.serializers import IPAddressSerializer
|
|
5
|
+
from tenancy.api.serializers import TenantSerializer
|
|
6
|
+
|
|
7
|
+
from netbox_dns.models import Record
|
|
8
|
+
from netbox_dns.api.nested_serializers import (
|
|
9
|
+
NestedZoneSerializer,
|
|
10
|
+
NestedRecordSerializer,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class RecordSerializer(NetBoxModelSerializer):
|
|
15
|
+
url = serializers.HyperlinkedIdentityField(
|
|
16
|
+
view_name="plugins-api:netbox_dns-api:record-detail"
|
|
17
|
+
)
|
|
18
|
+
ptr_record = NestedRecordSerializer(
|
|
19
|
+
many=False,
|
|
20
|
+
read_only=True,
|
|
21
|
+
required=False,
|
|
22
|
+
allow_null=True,
|
|
23
|
+
help_text="PTR record generated from an address",
|
|
24
|
+
)
|
|
25
|
+
address_record = NestedRecordSerializer(
|
|
26
|
+
many=False,
|
|
27
|
+
read_only=True,
|
|
28
|
+
required=False,
|
|
29
|
+
allow_null=True,
|
|
30
|
+
help_text="Address record defining the PTR",
|
|
31
|
+
)
|
|
32
|
+
zone = NestedZoneSerializer(
|
|
33
|
+
many=False,
|
|
34
|
+
required=False,
|
|
35
|
+
help_text="Zone the record belongs to",
|
|
36
|
+
)
|
|
37
|
+
active = serializers.BooleanField(
|
|
38
|
+
required=False,
|
|
39
|
+
read_only=True,
|
|
40
|
+
)
|
|
41
|
+
ipam_ip_address = IPAddressSerializer(
|
|
42
|
+
nested=True,
|
|
43
|
+
many=False,
|
|
44
|
+
read_only=True,
|
|
45
|
+
required=False,
|
|
46
|
+
allow_null=True,
|
|
47
|
+
help_text="IPAddress linked to the record",
|
|
48
|
+
)
|
|
49
|
+
tenant = TenantSerializer(nested=True, required=False, allow_null=True)
|
|
50
|
+
|
|
51
|
+
class Meta:
|
|
52
|
+
model = Record
|
|
53
|
+
fields = (
|
|
54
|
+
"id",
|
|
55
|
+
"url",
|
|
56
|
+
"zone",
|
|
57
|
+
"display",
|
|
58
|
+
"type",
|
|
59
|
+
"name",
|
|
60
|
+
"fqdn",
|
|
61
|
+
"value",
|
|
62
|
+
"status",
|
|
63
|
+
"ttl",
|
|
64
|
+
"description",
|
|
65
|
+
"tags",
|
|
66
|
+
"created",
|
|
67
|
+
"last_updated",
|
|
68
|
+
"managed",
|
|
69
|
+
"disable_ptr",
|
|
70
|
+
"ptr_record",
|
|
71
|
+
"address_record",
|
|
72
|
+
"active",
|
|
73
|
+
"custom_fields",
|
|
74
|
+
"tenant",
|
|
75
|
+
"ipam_ip_address",
|
|
76
|
+
)
|
|
77
|
+
brief_fields = (
|
|
78
|
+
"id",
|
|
79
|
+
"url",
|
|
80
|
+
"zone",
|
|
81
|
+
"display",
|
|
82
|
+
"type",
|
|
83
|
+
"name",
|
|
84
|
+
"fqdn",
|
|
85
|
+
"value",
|
|
86
|
+
"status",
|
|
87
|
+
"ttl",
|
|
88
|
+
"description",
|
|
89
|
+
"active",
|
|
90
|
+
)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
|
|
3
|
+
from netbox.api.serializers import NetBoxModelSerializer
|
|
4
|
+
|
|
5
|
+
from netbox_dns.models import Registrar
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RegistrarSerializer(NetBoxModelSerializer):
|
|
9
|
+
url = serializers.HyperlinkedIdentityField(
|
|
10
|
+
view_name="plugins-api:netbox_dns-api:registrar-detail"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
class Meta:
|
|
14
|
+
model = Registrar
|
|
15
|
+
fields = (
|
|
16
|
+
"id",
|
|
17
|
+
"url",
|
|
18
|
+
"display",
|
|
19
|
+
"name",
|
|
20
|
+
"description",
|
|
21
|
+
"iana_id",
|
|
22
|
+
"address",
|
|
23
|
+
"referral_url",
|
|
24
|
+
"whois_server",
|
|
25
|
+
"abuse_email",
|
|
26
|
+
"abuse_phone",
|
|
27
|
+
"created",
|
|
28
|
+
"last_updated",
|
|
29
|
+
"custom_fields",
|
|
30
|
+
)
|
|
31
|
+
brief_fields = ("id", "url", "display", "name", "description", "iana_id")
|
|
@@ -0,0 +1,29 @@
|
|
|
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 View
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ViewSerializer(NetBoxModelSerializer):
|
|
10
|
+
url = serializers.HyperlinkedIdentityField(
|
|
11
|
+
view_name="plugins-api:netbox_dns-api:view-detail"
|
|
12
|
+
)
|
|
13
|
+
tenant = TenantSerializer(nested=True, required=False, allow_null=True)
|
|
14
|
+
|
|
15
|
+
class Meta:
|
|
16
|
+
model = View
|
|
17
|
+
fields = (
|
|
18
|
+
"id",
|
|
19
|
+
"url",
|
|
20
|
+
"display",
|
|
21
|
+
"name",
|
|
22
|
+
"tags",
|
|
23
|
+
"description",
|
|
24
|
+
"created",
|
|
25
|
+
"last_updated",
|
|
26
|
+
"custom_fields",
|
|
27
|
+
"tenant",
|
|
28
|
+
)
|
|
29
|
+
brief_fields = ("id", "url", "display", "name", "description")
|
|
@@ -0,0 +1,170 @@
|
|
|
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.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
|
|
11
|
+
|
|
12
|
+
from netbox_dns.models import Zone
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ZoneSerializer(NetBoxModelSerializer):
|
|
16
|
+
# +
|
|
17
|
+
# This is a hack to avoid the exception raised by the UniqueTogetherValidator
|
|
18
|
+
# after NetBox commit https://github.com/netbox-community/netbox/commit/78e284c
|
|
19
|
+
#
|
|
20
|
+
# See https://github.com/netbox-community/netbox/issues/15351 for details.
|
|
21
|
+
# -
|
|
22
|
+
def __init__(self, *args, **kwargs):
|
|
23
|
+
super().__init__(*args, **kwargs)
|
|
24
|
+
if self.nested:
|
|
25
|
+
self.validators = []
|
|
26
|
+
|
|
27
|
+
url = serializers.HyperlinkedIdentityField(
|
|
28
|
+
view_name="plugins-api:netbox_dns-api:zone-detail"
|
|
29
|
+
)
|
|
30
|
+
view = ViewSerializer(
|
|
31
|
+
nested=True,
|
|
32
|
+
many=False,
|
|
33
|
+
read_only=False,
|
|
34
|
+
required=False,
|
|
35
|
+
default=None,
|
|
36
|
+
help_text="View the zone belongs to",
|
|
37
|
+
)
|
|
38
|
+
nameservers = NameServerSerializer(
|
|
39
|
+
nested=True,
|
|
40
|
+
many=True,
|
|
41
|
+
read_only=False,
|
|
42
|
+
required=False,
|
|
43
|
+
help_text="Nameservers for the zone",
|
|
44
|
+
)
|
|
45
|
+
soa_mname = NameServerSerializer(
|
|
46
|
+
nested=True,
|
|
47
|
+
many=False,
|
|
48
|
+
read_only=False,
|
|
49
|
+
required=False,
|
|
50
|
+
help_text="Primary nameserver for the zone",
|
|
51
|
+
)
|
|
52
|
+
rfc2317_parent_zone = NestedZoneSerializer(
|
|
53
|
+
many=False,
|
|
54
|
+
read_only=True,
|
|
55
|
+
required=False,
|
|
56
|
+
help_text="RFC2317 arent zone for the zone",
|
|
57
|
+
)
|
|
58
|
+
rfc2317_child_zones = NestedZoneSerializer(
|
|
59
|
+
many=True,
|
|
60
|
+
read_only=True,
|
|
61
|
+
required=False,
|
|
62
|
+
help_text="RFC2317 child zones of the zone",
|
|
63
|
+
)
|
|
64
|
+
registrar = RegistrarSerializer(
|
|
65
|
+
nested=True,
|
|
66
|
+
many=False,
|
|
67
|
+
read_only=False,
|
|
68
|
+
required=False,
|
|
69
|
+
help_text="The registrar the domain is registered with",
|
|
70
|
+
)
|
|
71
|
+
registrant = ContactSerializer(
|
|
72
|
+
many=False,
|
|
73
|
+
read_only=False,
|
|
74
|
+
required=False,
|
|
75
|
+
help_text="The owner of the domain",
|
|
76
|
+
)
|
|
77
|
+
admin_c = ContactSerializer(
|
|
78
|
+
many=False,
|
|
79
|
+
read_only=False,
|
|
80
|
+
required=False,
|
|
81
|
+
help_text="The administrative contact for the domain",
|
|
82
|
+
)
|
|
83
|
+
tech_c = ContactSerializer(
|
|
84
|
+
many=False,
|
|
85
|
+
read_only=False,
|
|
86
|
+
required=False,
|
|
87
|
+
help_text="The technical contact for the domain",
|
|
88
|
+
)
|
|
89
|
+
billing_c = ContactSerializer(
|
|
90
|
+
many=False,
|
|
91
|
+
read_only=False,
|
|
92
|
+
required=False,
|
|
93
|
+
help_text="The billing contact for the domain",
|
|
94
|
+
)
|
|
95
|
+
active = serializers.BooleanField(
|
|
96
|
+
required=False,
|
|
97
|
+
read_only=True,
|
|
98
|
+
allow_null=True,
|
|
99
|
+
)
|
|
100
|
+
tenant = TenantSerializer(nested=True, required=False, allow_null=True)
|
|
101
|
+
|
|
102
|
+
def create(self, validated_data):
|
|
103
|
+
nameservers = validated_data.pop("nameservers", None)
|
|
104
|
+
|
|
105
|
+
zone = super().create(validated_data)
|
|
106
|
+
|
|
107
|
+
if nameservers is not None:
|
|
108
|
+
zone.nameservers.set(nameservers)
|
|
109
|
+
|
|
110
|
+
return zone
|
|
111
|
+
|
|
112
|
+
def update(self, instance, validated_data):
|
|
113
|
+
nameservers = validated_data.pop("nameservers", None)
|
|
114
|
+
|
|
115
|
+
zone = super().update(instance, validated_data)
|
|
116
|
+
|
|
117
|
+
if nameservers is not None:
|
|
118
|
+
zone.nameservers.set(nameservers)
|
|
119
|
+
|
|
120
|
+
return zone
|
|
121
|
+
|
|
122
|
+
class Meta:
|
|
123
|
+
model = Zone
|
|
124
|
+
fields = (
|
|
125
|
+
"id",
|
|
126
|
+
"url",
|
|
127
|
+
"name",
|
|
128
|
+
"view",
|
|
129
|
+
"display",
|
|
130
|
+
"nameservers",
|
|
131
|
+
"status",
|
|
132
|
+
"description",
|
|
133
|
+
"tags",
|
|
134
|
+
"created",
|
|
135
|
+
"last_updated",
|
|
136
|
+
"default_ttl",
|
|
137
|
+
"soa_ttl",
|
|
138
|
+
"soa_mname",
|
|
139
|
+
"soa_rname",
|
|
140
|
+
"soa_serial",
|
|
141
|
+
"soa_serial_auto",
|
|
142
|
+
"soa_refresh",
|
|
143
|
+
"soa_retry",
|
|
144
|
+
"soa_expire",
|
|
145
|
+
"soa_minimum",
|
|
146
|
+
"rfc2317_prefix",
|
|
147
|
+
"rfc2317_parent_managed",
|
|
148
|
+
"rfc2317_parent_zone",
|
|
149
|
+
"rfc2317_child_zones",
|
|
150
|
+
"registrar",
|
|
151
|
+
"registry_domain_id",
|
|
152
|
+
"registrant",
|
|
153
|
+
"tech_c",
|
|
154
|
+
"admin_c",
|
|
155
|
+
"billing_c",
|
|
156
|
+
"active",
|
|
157
|
+
"custom_fields",
|
|
158
|
+
"tenant",
|
|
159
|
+
)
|
|
160
|
+
brief_fields = (
|
|
161
|
+
"id",
|
|
162
|
+
"url",
|
|
163
|
+
"name",
|
|
164
|
+
"view",
|
|
165
|
+
"display",
|
|
166
|
+
"status",
|
|
167
|
+
"description",
|
|
168
|
+
"rfc2317_prefix",
|
|
169
|
+
"active",
|
|
170
|
+
)
|
|
@@ -13,13 +13,13 @@ from netbox_dns.api.serializers import (
|
|
|
13
13
|
RegistrarSerializer,
|
|
14
14
|
ContactSerializer,
|
|
15
15
|
)
|
|
16
|
-
from netbox_dns.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
from netbox_dns.filtersets import (
|
|
17
|
+
ViewFilterSet,
|
|
18
|
+
ZoneFilterSet,
|
|
19
|
+
NameServerFilterSet,
|
|
20
|
+
RecordFilterSet,
|
|
21
|
+
RegistrarFilterSet,
|
|
22
|
+
ContactFilterSet,
|
|
23
23
|
)
|
|
24
24
|
from netbox_dns.models import View, Zone, NameServer, Record, Registrar, Contact
|
|
25
25
|
|
|
@@ -32,7 +32,7 @@ class NetBoxDNSRootView(APIRootView):
|
|
|
32
32
|
class ViewViewSet(NetBoxModelViewSet):
|
|
33
33
|
queryset = View.objects.all()
|
|
34
34
|
serializer_class = ViewSerializer
|
|
35
|
-
filterset_class =
|
|
35
|
+
filterset_class = ViewFilterSet
|
|
36
36
|
|
|
37
37
|
@action(detail=True, methods=["get"])
|
|
38
38
|
def views(self, request, pk=None):
|
|
@@ -51,7 +51,7 @@ class ZoneViewSet(NetBoxModelViewSet):
|
|
|
51
51
|
"tenant",
|
|
52
52
|
)
|
|
53
53
|
serializer_class = ZoneSerializer
|
|
54
|
-
filterset_class =
|
|
54
|
+
filterset_class = ZoneFilterSet
|
|
55
55
|
|
|
56
56
|
@action(detail=True, methods=["get"])
|
|
57
57
|
def records(self, request, pk=None):
|
|
@@ -71,7 +71,7 @@ class ZoneViewSet(NetBoxModelViewSet):
|
|
|
71
71
|
class NameServerViewSet(NetBoxModelViewSet):
|
|
72
72
|
queryset = NameServer.objects.prefetch_related("zones", "tenant")
|
|
73
73
|
serializer_class = NameServerSerializer
|
|
74
|
-
filterset_class =
|
|
74
|
+
filterset_class = NameServerFilterSet
|
|
75
75
|
|
|
76
76
|
@action(detail=True, methods=["get"])
|
|
77
77
|
def zones(self, request, pk=None):
|
|
@@ -83,7 +83,7 @@ class NameServerViewSet(NetBoxModelViewSet):
|
|
|
83
83
|
class RecordViewSet(NetBoxModelViewSet):
|
|
84
84
|
queryset = Record.objects.all().prefetch_related("zone", "zone__view", "tenant")
|
|
85
85
|
serializer_class = RecordSerializer
|
|
86
|
-
filterset_class =
|
|
86
|
+
filterset_class = RecordFilterSet
|
|
87
87
|
|
|
88
88
|
def destroy(self, request, *args, **kwargs):
|
|
89
89
|
v_object = self.get_object()
|
|
@@ -105,10 +105,10 @@ class RecordViewSet(NetBoxModelViewSet):
|
|
|
105
105
|
class RegistrarViewSet(NetBoxModelViewSet):
|
|
106
106
|
queryset = Registrar.objects.all()
|
|
107
107
|
serializer_class = RegistrarSerializer
|
|
108
|
-
filterset_class =
|
|
108
|
+
filterset_class = RegistrarFilterSet
|
|
109
109
|
|
|
110
110
|
|
|
111
111
|
class ContactViewSet(NetBoxModelViewSet):
|
|
112
112
|
queryset = Contact.objects.all()
|
|
113
113
|
serializer_class = ContactSerializer
|
|
114
|
-
filterset_class =
|
|
114
|
+
filterset_class = ContactFilterSet
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from django import forms
|
|
2
2
|
from django.db import models
|
|
3
|
-
from django.db.models import Lookup, Transform
|
|
3
|
+
from django.db.models import Lookup, Transform, IntegerField
|
|
4
4
|
from django.core.exceptions import ValidationError
|
|
5
5
|
|
|
6
6
|
from netaddr import AddrFormatError, IPNetwork
|
|
@@ -51,7 +51,7 @@ class RFC2317NetworkField(models.Field):
|
|
|
51
51
|
|
|
52
52
|
try:
|
|
53
53
|
ip_network = IPNetwork(value)
|
|
54
|
-
except (
|
|
54
|
+
except (AddrFormatError, TypeError, ValueError) as exc:
|
|
55
55
|
raise ValidationError(exc)
|
|
56
56
|
|
|
57
57
|
if ip_network.version != 4:
|
|
@@ -5,12 +5,13 @@ from netbox.filtersets import NetBoxModelFilterSet
|
|
|
5
5
|
from netbox_dns.models import Contact
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class ContactFilterSet(NetBoxModelFilterSet):
|
|
9
9
|
class Meta:
|
|
10
10
|
model = Contact
|
|
11
11
|
fields = (
|
|
12
12
|
"id",
|
|
13
13
|
"name",
|
|
14
|
+
"description",
|
|
14
15
|
"contact_id",
|
|
15
16
|
"organization",
|
|
16
17
|
"street",
|