netbox-plugin-dns 1.2.2__tar.gz → 1.2.4__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-1.2.2 → netbox_plugin_dns-1.2.4}/PKG-INFO +4 -3
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/README.md +3 -2
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/__init__.py +1 -1
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/zone.py +14 -2
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/zone_template.py +9 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/filtersets/zone_template.py +14 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/forms/zone.py +37 -10
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/forms/zone_template.py +46 -2
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/graphql/types.py +7 -0
- netbox_plugin_dns-1.2.4/netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_plugin_dns-1.2.4/netbox_dns/migrations/0013_zonetemplate_soa_mname_zonetemplate_soa_rname.py +30 -0
- netbox_plugin_dns-1.2.4/netbox_dns/models/__init__.py +8 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/models/nameserver.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/models/record.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/models/record_template.py +6 -3
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/models/registrar.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/models/registration_contact.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/models/view.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/models/zone.py +26 -9
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/models/zone_template.py +44 -10
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/zone_template.py +8 -1
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/nameserver.html +2 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/record.html +20 -20
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/view.html +2 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zone.html +2 -4
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zonetemplate.html +8 -2
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/utilities/conversions.py +25 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/validators/dns_name.py +9 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/views/nameserver.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/views/record.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/views/record_template.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/views/registrar.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/views/registration_contact.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/views/view.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/views/zone.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/views/zone_template.py +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_plugin_dns.egg-info/PKG-INFO +4 -3
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_plugin_dns.egg-info/SOURCES.txt +1 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/pyproject.toml +1 -1
- netbox_plugin_dns-1.2.2/netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_plugin_dns-1.2.2/netbox_dns/models/__init__.py +0 -13
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/LICENSE +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/nested_serializers.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/nameserver.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/prefix.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/record.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/record_template.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/registrar.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/registration_contact.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/view.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/urls.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/views.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/apps.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/choices/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/choices/record.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/choices/zone.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/fields/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/fields/address.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/fields/ipam.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/fields/network.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/fields/rfc2317.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/filtersets/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/filtersets/nameserver.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/filtersets/record.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/filtersets/record_template.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/filtersets/registrar.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/filtersets/registration_contact.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/filtersets/view.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/filtersets/zone.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/forms/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/forms/nameserver.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/forms/record.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/forms/record_template.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/forms/registrar.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/forms/registration_contact.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/forms/view.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/graphql/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/graphql/filters.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/graphql/schema.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/management/commands/cleanup_database.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/management/commands/cleanup_rrset_ttl.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/management/commands/rebuild_dnssync.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/management/commands/setup_dnssync.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/management/commands/update_soa.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0002_contact_description_registrar_description.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0003_default_view.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0004_create_and_assign_default_view.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0005_alter_zone_view_not_null.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0006_templating.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0007_alter_ordering_options.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0008_view_prefixes.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0009_rename_contact_registrationcontact.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0010_view_ip_address_filter.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0011_rename_related_fields.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0012_natural_ordering.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0022_search.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0024_tenancy.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0026_domain_registration.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/0029_record_fqdn.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/migrations/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/mixins/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/mixins/object_modification.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/navigation.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/signals/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/signals/ipam_dnssync.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/ipam_dnssync.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/nameserver.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/record.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/record_template.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/registrar.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/registration_contact.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/view.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/tables/zone.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/template_content.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/recordtemplate.html +6 -6
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/registrar.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/registrationcontact.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/view/button.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/view/prefix.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/view/related.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zone/child_zone.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zone/delegation_record.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templatetags/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/templatetags/netbox_dns.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/urls.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/utilities/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/utilities/dns.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/utilities/ipam_dnssync.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/validators/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/validators/dns_value.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/validators/rfc2317.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/views/__init__.py +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_plugin_dns.egg-info/dependency_links.txt +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_plugin_dns.egg-info/requires.txt +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_plugin_dns.egg-info/top_level.txt +0 -0
- {netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: netbox-plugin-dns
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.4
|
|
4
4
|
Summary: NetBox DNS is a NetBox plugin for managing DNS data.
|
|
5
5
|
Author-email: Peter Eckel <pete@netbox-dns.org>
|
|
6
6
|
Project-URL: Homepage, https://github.com/peteeckel/netbox-plugin-dns
|
|
@@ -69,7 +69,7 @@ For integration with a large number of DNS server implementations integration to
|
|
|
69
69
|
* NetBox 4.2.0 or higher
|
|
70
70
|
* Python 3.10 or higher
|
|
71
71
|
|
|
72
|
-
## Compatibility with
|
|
72
|
+
## Compatibility with NetBox Versions
|
|
73
73
|
|
|
74
74
|
NetBox Version | NetBox DNS Version | Comment
|
|
75
75
|
-------------- | ------------------ | -------
|
|
@@ -78,6 +78,7 @@ NetBox Version | NetBox DNS Version | Comment
|
|
|
78
78
|
3.7 | 0.22 |
|
|
79
79
|
4.0 - 4.1 | 1.0 | Supports legacy IPAM Coupling
|
|
80
80
|
4.0 - 4.1 | 1.1 | Supports IPAM DNSsync
|
|
81
|
+
4.2 | 1.2 |
|
|
81
82
|
|
|
82
83
|
## Installation & Configuration
|
|
83
84
|
|
|
@@ -98,7 +99,7 @@ PLUGINS = [
|
|
|
98
99
|
]
|
|
99
100
|
```
|
|
100
101
|
|
|
101
|
-
To permanently keep the plugin installed when updating NetBox via `
|
|
102
|
+
To permanently keep the plugin installed when updating NetBox via `upgrade.sh`:
|
|
102
103
|
|
|
103
104
|
```
|
|
104
105
|
echo netbox-plugin-dns >> ~/netbox/local_requirements.txt
|
|
@@ -53,7 +53,7 @@ For integration with a large number of DNS server implementations integration to
|
|
|
53
53
|
* NetBox 4.2.0 or higher
|
|
54
54
|
* Python 3.10 or higher
|
|
55
55
|
|
|
56
|
-
## Compatibility with
|
|
56
|
+
## Compatibility with NetBox Versions
|
|
57
57
|
|
|
58
58
|
NetBox Version | NetBox DNS Version | Comment
|
|
59
59
|
-------------- | ------------------ | -------
|
|
@@ -62,6 +62,7 @@ NetBox Version | NetBox DNS Version | Comment
|
|
|
62
62
|
3.7 | 0.22 |
|
|
63
63
|
4.0 - 4.1 | 1.0 | Supports legacy IPAM Coupling
|
|
64
64
|
4.0 - 4.1 | 1.1 | Supports IPAM DNSsync
|
|
65
|
+
4.2 | 1.2 |
|
|
65
66
|
|
|
66
67
|
## Installation & Configuration
|
|
67
68
|
|
|
@@ -82,7 +83,7 @@ PLUGINS = [
|
|
|
82
83
|
]
|
|
83
84
|
```
|
|
84
85
|
|
|
85
|
-
To permanently keep the plugin installed when updating NetBox via `
|
|
86
|
+
To permanently keep the plugin installed when updating NetBox via `upgrade.sh`:
|
|
86
87
|
|
|
87
88
|
```
|
|
88
89
|
echo netbox-plugin-dns >> ~/netbox/local_requirements.txt
|
|
@@ -44,6 +44,12 @@ class ZoneSerializer(NetBoxModelSerializer):
|
|
|
44
44
|
required=False,
|
|
45
45
|
help_text=_("Primary nameserver for the zone"),
|
|
46
46
|
)
|
|
47
|
+
soa_rname = serializers.CharField(
|
|
48
|
+
max_length=255,
|
|
49
|
+
read_only=False,
|
|
50
|
+
required=False,
|
|
51
|
+
help_text=_("Contact email for the zone"),
|
|
52
|
+
)
|
|
47
53
|
rfc2317_parent_zone = NestedZoneSerializer(
|
|
48
54
|
many=False,
|
|
49
55
|
read_only=True,
|
|
@@ -105,6 +111,12 @@ class ZoneSerializer(NetBoxModelSerializer):
|
|
|
105
111
|
)
|
|
106
112
|
tenant = TenantSerializer(nested=True, required=False, allow_null=True)
|
|
107
113
|
|
|
114
|
+
def validate(self, data):
|
|
115
|
+
if (template := data.get("template")) is not None:
|
|
116
|
+
template.apply_to_zone_data(data)
|
|
117
|
+
|
|
118
|
+
return super().validate(data)
|
|
119
|
+
|
|
108
120
|
def create(self, validated_data):
|
|
109
121
|
template = validated_data.pop("template", None)
|
|
110
122
|
nameservers = validated_data.pop("nameservers", None)
|
|
@@ -115,7 +127,7 @@ class ZoneSerializer(NetBoxModelSerializer):
|
|
|
115
127
|
zone.nameservers.set(nameservers)
|
|
116
128
|
|
|
117
129
|
if template is not None:
|
|
118
|
-
template.
|
|
130
|
+
template.apply_to_zone_relations(zone)
|
|
119
131
|
|
|
120
132
|
return zone
|
|
121
133
|
|
|
@@ -129,7 +141,7 @@ class ZoneSerializer(NetBoxModelSerializer):
|
|
|
129
141
|
zone.nameservers.set(nameservers)
|
|
130
142
|
|
|
131
143
|
if template is not None:
|
|
132
|
-
template.
|
|
144
|
+
template.apply_to_zone_relations(zone)
|
|
133
145
|
|
|
134
146
|
return zone
|
|
135
147
|
|
{netbox_plugin_dns-1.2.2 → netbox_plugin_dns-1.2.4}/netbox_dns/api/serializers_/zone_template.py
RENAMED
|
@@ -26,6 +26,13 @@ class ZoneTemplateSerializer(NetBoxModelSerializer):
|
|
|
26
26
|
required=False,
|
|
27
27
|
help_text=_("Nameservers for the zone"),
|
|
28
28
|
)
|
|
29
|
+
soa_mname = NameServerSerializer(
|
|
30
|
+
nested=True,
|
|
31
|
+
many=False,
|
|
32
|
+
read_only=False,
|
|
33
|
+
required=False,
|
|
34
|
+
help_text=_("Primary nameserver for the zone"),
|
|
35
|
+
)
|
|
29
36
|
record_templates = NestedRecordTemplateSerializer(
|
|
30
37
|
many=True,
|
|
31
38
|
read_only=False,
|
|
@@ -108,6 +115,8 @@ class ZoneTemplateSerializer(NetBoxModelSerializer):
|
|
|
108
115
|
"name",
|
|
109
116
|
"display",
|
|
110
117
|
"nameservers",
|
|
118
|
+
"soa_mname",
|
|
119
|
+
"soa_rname",
|
|
111
120
|
"description",
|
|
112
121
|
"tags",
|
|
113
122
|
"created",
|
|
@@ -43,6 +43,18 @@ class ZoneTemplateFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
|
|
|
43
43
|
to_field_name="name",
|
|
44
44
|
label=_("Nameserver"),
|
|
45
45
|
)
|
|
46
|
+
soa_mname_id = django_filters.ModelMultipleChoiceFilter(
|
|
47
|
+
queryset=NameServer.objects.all(),
|
|
48
|
+
field_name="soa_mname",
|
|
49
|
+
to_field_name="id",
|
|
50
|
+
label=_("SOA MNAME ID"),
|
|
51
|
+
)
|
|
52
|
+
soa_mname = django_filters.ModelMultipleChoiceFilter(
|
|
53
|
+
queryset=NameServer.objects.all(),
|
|
54
|
+
field_name="soa_mname__name",
|
|
55
|
+
to_field_name="name",
|
|
56
|
+
label=_("SOA MNAME"),
|
|
57
|
+
)
|
|
46
58
|
registrar_id = django_filters.ModelMultipleChoiceFilter(
|
|
47
59
|
queryset=Registrar.objects.all(),
|
|
48
60
|
label=_("Registrar ID"),
|
|
@@ -100,6 +112,7 @@ class ZoneTemplateFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
|
|
|
100
112
|
"id",
|
|
101
113
|
"name",
|
|
102
114
|
"description",
|
|
115
|
+
"soa_rname",
|
|
103
116
|
)
|
|
104
117
|
|
|
105
118
|
def search(self, queryset, name, value):
|
|
@@ -107,6 +120,7 @@ class ZoneTemplateFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
|
|
|
107
120
|
return queryset
|
|
108
121
|
qs_filter = (
|
|
109
122
|
Q(name__icontains=value)
|
|
123
|
+
| Q(soa_rname__icontains=value)
|
|
110
124
|
| Q(registrar__name__icontains=value)
|
|
111
125
|
| Q(registry_domain_id__icontains=value)
|
|
112
126
|
| Q(registrant__name__icontains=value)
|
|
@@ -35,7 +35,7 @@ from netbox_dns.models import (
|
|
|
35
35
|
ZoneTemplate,
|
|
36
36
|
)
|
|
37
37
|
from netbox_dns.choices import ZoneStatusChoices
|
|
38
|
-
from netbox_dns.utilities import name_to_unicode
|
|
38
|
+
from netbox_dns.utilities import name_to_unicode, network_to_reverse
|
|
39
39
|
from netbox_dns.fields import RFC2317NetworkFormField
|
|
40
40
|
from netbox_dns.validators import validate_ipv4, validate_prefix, validate_rfc2317
|
|
41
41
|
|
|
@@ -66,13 +66,20 @@ class ZoneTemplateUpdateMixin:
|
|
|
66
66
|
self.cleaned_data["tags"] = template.tags.all()
|
|
67
67
|
|
|
68
68
|
for field in template.template_fields:
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
):
|
|
69
|
+
if self.cleaned_data.get(field) in (None, "") and getattr(
|
|
70
|
+
template, field
|
|
71
|
+
) not in (None, ""):
|
|
73
72
|
self.cleaned_data[field] = getattr(template, field)
|
|
74
73
|
|
|
75
|
-
|
|
74
|
+
if self.cleaned_data.get("soa_mname") is None:
|
|
75
|
+
self.add_error(
|
|
76
|
+
"soa_mname",
|
|
77
|
+
_("soa_mname not set and no template or default value defined"),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if self.errors:
|
|
81
|
+
return
|
|
82
|
+
|
|
76
83
|
saved_events_queue = events_queue.get()
|
|
77
84
|
|
|
78
85
|
try:
|
|
@@ -106,13 +113,20 @@ class ZoneTemplateUpdateMixin:
|
|
|
106
113
|
raise RollbackTransaction
|
|
107
114
|
|
|
108
115
|
except ValidationError as exc:
|
|
109
|
-
|
|
116
|
+
if hasattr(exc, "error_dict"):
|
|
117
|
+
for field_name in self.fields.keys():
|
|
118
|
+
exc.error_dict.pop(field_name, None)
|
|
119
|
+
errors = exc.error_dict.values()
|
|
120
|
+
else:
|
|
121
|
+
errors = exc.messages
|
|
122
|
+
|
|
123
|
+
for error in errors:
|
|
124
|
+
self.add_error("template", error)
|
|
125
|
+
|
|
110
126
|
except RollbackTransaction:
|
|
111
127
|
pass
|
|
112
128
|
|
|
113
129
|
events_queue.set(saved_events_queue)
|
|
114
|
-
if template_error is not None:
|
|
115
|
-
raise ValidationError({"template": template_error})
|
|
116
130
|
|
|
117
131
|
return self.cleaned_data
|
|
118
132
|
|
|
@@ -161,8 +175,14 @@ class ZoneForm(ZoneTemplateUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
|
161
175
|
validators=[MinValueValidator(1)],
|
|
162
176
|
label=_("SOA TTL"),
|
|
163
177
|
)
|
|
178
|
+
soa_mname = DynamicModelChoiceField(
|
|
179
|
+
queryset=NameServer.objects.all(),
|
|
180
|
+
help_text=_("Primary nameserver this zone"),
|
|
181
|
+
required=False,
|
|
182
|
+
label=_("SOA MName"),
|
|
183
|
+
)
|
|
164
184
|
soa_rname = forms.CharField(
|
|
165
|
-
required=
|
|
185
|
+
required=False,
|
|
166
186
|
help_text=_("Mailbox of the zone's administrator"),
|
|
167
187
|
label=_("SOA RName"),
|
|
168
188
|
)
|
|
@@ -307,6 +327,13 @@ class ZoneForm(ZoneTemplateUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
|
307
327
|
else self.initial["default_ttl"]
|
|
308
328
|
)
|
|
309
329
|
|
|
330
|
+
def clean_name(self):
|
|
331
|
+
name = self.cleaned_data["name"]
|
|
332
|
+
if reverse_name := network_to_reverse(name):
|
|
333
|
+
return reverse_name
|
|
334
|
+
else:
|
|
335
|
+
return name
|
|
336
|
+
|
|
310
337
|
class Meta:
|
|
311
338
|
model = Zone
|
|
312
339
|
|
|
@@ -40,6 +40,11 @@ class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
|
40
40
|
queryset=NameServer.objects.all(),
|
|
41
41
|
required=False,
|
|
42
42
|
)
|
|
43
|
+
soa_mname = DynamicModelChoiceField(
|
|
44
|
+
queryset=NameServer.objects.all(),
|
|
45
|
+
required=False,
|
|
46
|
+
label=_("MName"),
|
|
47
|
+
)
|
|
43
48
|
record_templates = DynamicModelMultipleChoiceField(
|
|
44
49
|
queryset=RecordTemplate.objects.all(),
|
|
45
50
|
required=False,
|
|
@@ -47,6 +52,7 @@ class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
|
47
52
|
|
|
48
53
|
fieldsets = (
|
|
49
54
|
FieldSet("name", "description", "nameservers", name=_("Zone Template")),
|
|
55
|
+
FieldSet("soa_mname", "soa_rname", name=_("SOA")),
|
|
50
56
|
FieldSet("record_templates", name=_("Record Templates")),
|
|
51
57
|
FieldSet(
|
|
52
58
|
"registrar",
|
|
@@ -66,6 +72,8 @@ class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
|
66
72
|
fields = (
|
|
67
73
|
"name",
|
|
68
74
|
"nameservers",
|
|
75
|
+
"soa_mname",
|
|
76
|
+
"soa_rname",
|
|
69
77
|
"record_templates",
|
|
70
78
|
"description",
|
|
71
79
|
"registrar",
|
|
@@ -77,6 +85,9 @@ class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
|
77
85
|
"tenant",
|
|
78
86
|
"tags",
|
|
79
87
|
)
|
|
88
|
+
labels = {
|
|
89
|
+
"soa_rname": _("RName"),
|
|
90
|
+
}
|
|
80
91
|
|
|
81
92
|
|
|
82
93
|
class ZoneTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
@@ -84,6 +95,7 @@ class ZoneTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
84
95
|
fieldsets = (
|
|
85
96
|
FieldSet("q", "filter_id", "tag"),
|
|
86
97
|
FieldSet("name", "nameserver_id", "description", name=_("Attributes")),
|
|
98
|
+
FieldSet("soa_mname_id", "soa_rname", name=_("SOA")),
|
|
87
99
|
FieldSet("record_template_id", name=_("Record Templates")),
|
|
88
100
|
FieldSet(
|
|
89
101
|
"registrar_id",
|
|
@@ -105,6 +117,15 @@ class ZoneTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
105
117
|
required=False,
|
|
106
118
|
label=_("Nameservers"),
|
|
107
119
|
)
|
|
120
|
+
soa_mname_id = DynamicModelMultipleChoiceField(
|
|
121
|
+
queryset=NameServer.objects.all(),
|
|
122
|
+
required=False,
|
|
123
|
+
label=_("MName"),
|
|
124
|
+
)
|
|
125
|
+
soa_rname = forms.CharField(
|
|
126
|
+
required=False,
|
|
127
|
+
label=_("RName"),
|
|
128
|
+
)
|
|
108
129
|
record_template_id = DynamicModelMultipleChoiceField(
|
|
109
130
|
queryset=RecordTemplate.objects.all(),
|
|
110
131
|
required=False,
|
|
@@ -148,11 +169,17 @@ class ZoneTemplateImportForm(NetBoxModelImportForm):
|
|
|
148
169
|
required=False,
|
|
149
170
|
label=_("Nameservers"),
|
|
150
171
|
)
|
|
172
|
+
soa_mname = CSVModelChoiceField(
|
|
173
|
+
queryset=NameServer.objects.all(),
|
|
174
|
+
to_field_name="name",
|
|
175
|
+
required=False,
|
|
176
|
+
label=_("SOA MName"),
|
|
177
|
+
)
|
|
151
178
|
record_templates = CSVModelMultipleChoiceField(
|
|
152
179
|
queryset=RecordTemplate.objects.all(),
|
|
153
180
|
to_field_name="name",
|
|
154
181
|
required=False,
|
|
155
|
-
label=_("Record
|
|
182
|
+
label=_("Record Templates"),
|
|
156
183
|
)
|
|
157
184
|
registrar = CSVModelChoiceField(
|
|
158
185
|
queryset=Registrar.objects.all(),
|
|
@@ -212,6 +239,8 @@ class ZoneTemplateImportForm(NetBoxModelImportForm):
|
|
|
212
239
|
fields = (
|
|
213
240
|
"name",
|
|
214
241
|
"nameservers",
|
|
242
|
+
"soa_mname",
|
|
243
|
+
"soa_rname",
|
|
215
244
|
"record_templates",
|
|
216
245
|
"description",
|
|
217
246
|
"registrar",
|
|
@@ -230,12 +259,20 @@ class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
230
259
|
required=False,
|
|
231
260
|
label=_("Nameservers"),
|
|
232
261
|
)
|
|
262
|
+
soa_mname = DynamicModelChoiceField(
|
|
263
|
+
queryset=NameServer.objects.all(),
|
|
264
|
+
required=False,
|
|
265
|
+
label=_("MName"),
|
|
266
|
+
)
|
|
267
|
+
soa_rname = forms.CharField(max_length=255, required=False, label=_("RName"))
|
|
233
268
|
record_templates = DynamicModelMultipleChoiceField(
|
|
234
269
|
queryset=RecordTemplate.objects.all(),
|
|
235
270
|
required=False,
|
|
236
271
|
label=_("Record Templates"),
|
|
237
272
|
)
|
|
238
|
-
description = forms.CharField(
|
|
273
|
+
description = forms.CharField(
|
|
274
|
+
max_length=200, required=False, label=_("Description")
|
|
275
|
+
)
|
|
239
276
|
registrar = DynamicModelChoiceField(
|
|
240
277
|
queryset=Registrar.objects.all(),
|
|
241
278
|
required=False,
|
|
@@ -280,6 +317,11 @@ class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
280
317
|
"description",
|
|
281
318
|
name=_("Attributes"),
|
|
282
319
|
),
|
|
320
|
+
FieldSet(
|
|
321
|
+
"soa_mname",
|
|
322
|
+
"soa_rname",
|
|
323
|
+
name=_("SOA"),
|
|
324
|
+
),
|
|
283
325
|
FieldSet(
|
|
284
326
|
"record_templates",
|
|
285
327
|
name=_("Record Templates"),
|
|
@@ -298,6 +340,8 @@ class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
298
340
|
nullable_fields = (
|
|
299
341
|
"description",
|
|
300
342
|
"nameservers",
|
|
343
|
+
"soa_mname",
|
|
344
|
+
"soa_rname",
|
|
301
345
|
"record_templates",
|
|
302
346
|
"registrar",
|
|
303
347
|
"registrant",
|
|
@@ -219,6 +219,13 @@ class NetBoxDNSZoneTemplateType(NetBoxObjectType):
|
|
|
219
219
|
"NetBoxDNSNameServerType", strawberry.lazy("netbox_dns.graphql.types")
|
|
220
220
|
]
|
|
221
221
|
]
|
|
222
|
+
soa_mname: (
|
|
223
|
+
Annotated[
|
|
224
|
+
"NetBoxDNSNameServerType", strawberry.lazy("netbox_dns.graphql.types")
|
|
225
|
+
]
|
|
226
|
+
| None
|
|
227
|
+
)
|
|
228
|
+
soa_rname: str | None
|
|
222
229
|
record_templates: List[
|
|
223
230
|
Annotated[
|
|
224
231
|
"NetBoxDNSRecordTemplateType", strawberry.lazy("netbox_dns.graphql.types")
|
|
Binary file
|
netbox_plugin_dns-1.2.4/netbox_dns/migrations/0013_zonetemplate_soa_mname_zonetemplate_soa_rname.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Generated by Django 5.1.5 on 2025-02-17 11:37
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("netbox_dns", "0012_natural_ordering"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AddField(
|
|
15
|
+
model_name="zonetemplate",
|
|
16
|
+
name="soa_mname",
|
|
17
|
+
field=models.ForeignKey(
|
|
18
|
+
blank=True,
|
|
19
|
+
null=True,
|
|
20
|
+
on_delete=django.db.models.deletion.PROTECT,
|
|
21
|
+
related_name="+",
|
|
22
|
+
to="netbox_dns.nameserver",
|
|
23
|
+
),
|
|
24
|
+
),
|
|
25
|
+
migrations.AddField(
|
|
26
|
+
model_name="zonetemplate",
|
|
27
|
+
name="soa_rname",
|
|
28
|
+
field=models.CharField(blank=True, max_length=255),
|
|
29
|
+
),
|
|
30
|
+
]
|
|
@@ -69,6 +69,7 @@ class NameServer(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
69
69
|
def display_name(self):
|
|
70
70
|
return name_to_unicode(self.name)
|
|
71
71
|
|
|
72
|
+
# TODO: Remove in version 1.3.0 (NetBox #18555)
|
|
72
73
|
def get_absolute_url(self):
|
|
73
74
|
return reverse("plugins:netbox_dns:nameserver", kwargs={"pk": self.pk})
|
|
74
75
|
|
|
@@ -263,6 +263,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
263
263
|
def get_status_color(self):
|
|
264
264
|
return RecordStatusChoices.colors.get(self.status)
|
|
265
265
|
|
|
266
|
+
# TODO: Remove in version 1.3.0 (NetBox #18555)
|
|
266
267
|
def get_absolute_url(self):
|
|
267
268
|
return reverse("plugins:netbox_dns:record", kwargs={"pk": self.pk})
|
|
268
269
|
|
|
@@ -104,6 +104,7 @@ class RecordTemplate(NetBoxModel):
|
|
|
104
104
|
def get_status_color(self):
|
|
105
105
|
return RecordStatusChoices.colors.get(self.status)
|
|
106
106
|
|
|
107
|
+
# TODO: Remove in version 1.3.0 (NetBox #18555)
|
|
107
108
|
def get_absolute_url(self):
|
|
108
109
|
return reverse("plugins:netbox_dns:recordtemplate", kwargs={"pk": self.pk})
|
|
109
110
|
|
|
@@ -163,9 +164,11 @@ class RecordTemplate(NetBoxModel):
|
|
|
163
164
|
record = Record.objects.create(**record_data)
|
|
164
165
|
except ValidationError as exc:
|
|
165
166
|
raise ValidationError(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
{
|
|
168
|
+
None: _(
|
|
169
|
+
"Error while processing record template {template}: {error}"
|
|
170
|
+
).format(template=self, error=exc.messages[0])
|
|
171
|
+
}
|
|
169
172
|
)
|
|
170
173
|
|
|
171
174
|
if tags := self.tags.all():
|
|
@@ -71,6 +71,7 @@ class View(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
71
71
|
def get_default_view(cls):
|
|
72
72
|
return cls.objects.get(default_view=True)
|
|
73
73
|
|
|
74
|
+
# TODO: Remove in version 1.3.0 (NetBox #18555)
|
|
74
75
|
def get_absolute_url(self):
|
|
75
76
|
return reverse("plugins:netbox_dns:view", kwargs={"pk": self.pk})
|
|
76
77
|
|
|
@@ -350,6 +350,7 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
350
350
|
def get_status_color(self):
|
|
351
351
|
return ZoneStatusChoices.colors.get(self.status)
|
|
352
352
|
|
|
353
|
+
# TODO: Remove in version 1.3.0 (NetBox #18555)
|
|
353
354
|
def get_absolute_url(self):
|
|
354
355
|
return reverse("plugins:netbox_dns:zone", kwargs={"pk": self.pk})
|
|
355
356
|
|
|
@@ -670,15 +671,25 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
670
671
|
if value not in (None, ""):
|
|
671
672
|
setattr(self, field, value)
|
|
672
673
|
|
|
673
|
-
if self.soa_mname_id is None:
|
|
674
|
-
default_soa_mname
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
674
|
+
if self.soa_mname_id is None and "soa_mname" not in exclude:
|
|
675
|
+
if default_soa_mname := defaults.get("zone_soa_mname"):
|
|
676
|
+
try:
|
|
677
|
+
self.soa_mname = NameServer.objects.get(name=default_soa_mname)
|
|
678
|
+
except NameServer.DoesNotExist:
|
|
679
|
+
raise ValidationError(
|
|
680
|
+
{
|
|
681
|
+
"soa_mname": _(
|
|
682
|
+
"Default soa_mname instance {nameserver} does not exist"
|
|
683
|
+
).format(nameserver=default_soa_mname)
|
|
684
|
+
}
|
|
681
685
|
)
|
|
686
|
+
else:
|
|
687
|
+
raise ValidationError(
|
|
688
|
+
{
|
|
689
|
+
"soa_mname": _(
|
|
690
|
+
"soa_mname not set and no template or default value defined"
|
|
691
|
+
)
|
|
692
|
+
}
|
|
682
693
|
)
|
|
683
694
|
|
|
684
695
|
super().clean_fields(exclude=exclude)
|
|
@@ -706,7 +717,13 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
706
717
|
)
|
|
707
718
|
|
|
708
719
|
if self.soa_rname in (None, ""):
|
|
709
|
-
raise ValidationError(
|
|
720
|
+
raise ValidationError(
|
|
721
|
+
{
|
|
722
|
+
"soa_rname": _(
|
|
723
|
+
"soa_rname not set and no template or default value defined"
|
|
724
|
+
),
|
|
725
|
+
}
|
|
726
|
+
)
|
|
710
727
|
try:
|
|
711
728
|
dns_name.from_text(self.soa_rname, origin=dns_name.root)
|
|
712
729
|
validate_rname(self.soa_rname)
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
from dns import name as dns_name
|
|
2
|
+
from dns.exception import DNSException
|
|
3
|
+
|
|
1
4
|
from django.db import models
|
|
2
5
|
from django.urls import reverse
|
|
3
6
|
from django.utils.translation import gettext_lazy as _
|
|
7
|
+
from django.core.exceptions import ValidationError
|
|
4
8
|
|
|
5
9
|
from netbox.models import NetBoxModel
|
|
6
10
|
from netbox.search import SearchIndex, register_search
|
|
7
11
|
|
|
12
|
+
from netbox_dns.validators import validate_rname
|
|
13
|
+
|
|
8
14
|
|
|
9
15
|
__all__ = (
|
|
10
16
|
"ZoneTemplate",
|
|
@@ -30,6 +36,19 @@ class ZoneTemplate(NetBoxModel):
|
|
|
30
36
|
related_name="+",
|
|
31
37
|
blank=True,
|
|
32
38
|
)
|
|
39
|
+
soa_mname = models.ForeignKey(
|
|
40
|
+
verbose_name=_("SOA MName"),
|
|
41
|
+
to="NameServer",
|
|
42
|
+
related_name="+",
|
|
43
|
+
on_delete=models.PROTECT,
|
|
44
|
+
blank=True,
|
|
45
|
+
null=True,
|
|
46
|
+
)
|
|
47
|
+
soa_rname = models.CharField(
|
|
48
|
+
verbose_name=_("SOA RName"),
|
|
49
|
+
max_length=255,
|
|
50
|
+
blank=True,
|
|
51
|
+
)
|
|
33
52
|
record_templates = models.ManyToManyField(
|
|
34
53
|
verbose_name=_("Record Templates"),
|
|
35
54
|
to="RecordTemplate",
|
|
@@ -98,6 +117,8 @@ class ZoneTemplate(NetBoxModel):
|
|
|
98
117
|
)
|
|
99
118
|
|
|
100
119
|
template_fields = (
|
|
120
|
+
"soa_mname",
|
|
121
|
+
"soa_rname",
|
|
101
122
|
"tenant",
|
|
102
123
|
"registrar",
|
|
103
124
|
"registrant",
|
|
@@ -115,31 +136,44 @@ class ZoneTemplate(NetBoxModel):
|
|
|
115
136
|
def __str__(self):
|
|
116
137
|
return str(self.name)
|
|
117
138
|
|
|
139
|
+
# TODO: Remove in version 1.3.0 (NetBox #18555)
|
|
118
140
|
def get_absolute_url(self):
|
|
119
141
|
return reverse("plugins:netbox_dns:zonetemplate", kwargs={"pk": self.pk})
|
|
120
142
|
|
|
121
|
-
def
|
|
143
|
+
def apply_to_zone_data(self, data):
|
|
144
|
+
fields_changed = False
|
|
145
|
+
for field in self.template_fields:
|
|
146
|
+
if data.get(field) in (None, "") and getattr(self, field) not in (None, ""):
|
|
147
|
+
fields_changed = True
|
|
148
|
+
data[field] = getattr(self, field)
|
|
149
|
+
|
|
150
|
+
return fields_changed
|
|
151
|
+
|
|
152
|
+
def apply_to_zone_relations(self, zone):
|
|
122
153
|
if not zone.nameservers.all() and self.nameservers.all():
|
|
123
154
|
zone.nameservers.set(self.nameservers.all())
|
|
124
155
|
|
|
125
156
|
if not zone.tags.all() and self.tags.all():
|
|
126
157
|
zone.tags.set(self.tags.all())
|
|
127
158
|
|
|
128
|
-
fields_changed = True
|
|
129
|
-
for field in self.template_fields:
|
|
130
|
-
if getattr(zone, field) is None and getattr(self, field) is not None:
|
|
131
|
-
fields_changed = True
|
|
132
|
-
setattr(zone, field, getattr(self, field))
|
|
133
|
-
|
|
134
|
-
if fields_changed:
|
|
135
|
-
zone.save()
|
|
136
|
-
|
|
137
159
|
self.create_records(zone)
|
|
138
160
|
|
|
139
161
|
def create_records(self, zone):
|
|
140
162
|
for record_template in self.record_templates.all():
|
|
141
163
|
record_template.create_record(zone=zone)
|
|
142
164
|
|
|
165
|
+
def clean(self, *args, **kwargs):
|
|
166
|
+
if self.soa_rname:
|
|
167
|
+
try:
|
|
168
|
+
dns_name.from_text(self.soa_rname, origin=dns_name.root)
|
|
169
|
+
validate_rname(self.soa_rname)
|
|
170
|
+
except (DNSException, ValidationError) as exc:
|
|
171
|
+
raise ValidationError(
|
|
172
|
+
{
|
|
173
|
+
"soa_rname": exc,
|
|
174
|
+
}
|
|
175
|
+
)
|
|
176
|
+
|
|
143
177
|
|
|
144
178
|
@register_search
|
|
145
179
|
class ZoneTemplateIndex(SearchIndex):
|