netbox-plugin-dns 1.2.3__tar.gz → 1.2.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of netbox-plugin-dns might be problematic. Click here for more details.
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/PKG-INFO +2 -2
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/README.md +1 -1
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/__init__.py +2 -1
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/zone.py +14 -2
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/zone_template.py +9 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/filtersets/zone_template.py +14 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/forms/record_template.py +4 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/forms/zone.py +42 -9
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/forms/zone_template.py +54 -2
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/graphql/types.py +7 -0
- netbox_plugin_dns-1.2.5/netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_plugin_dns-1.2.5/netbox_dns/migrations/0013_zonetemplate_soa_mname_zonetemplate_soa_rname.py +30 -0
- netbox_plugin_dns-1.2.5/netbox_dns/migrations/0014_alter_unique_constraints_lowercase.py +42 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/models/nameserver.py +20 -2
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/models/record.py +20 -10
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/models/record_template.py +11 -5
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/models/registrar.py +1 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/models/registration_contact.py +1 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/models/view.py +1 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/models/zone.py +54 -21
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/models/zone_template.py +44 -10
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/zone_template.py +8 -1
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zonetemplate.html +8 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/utilities/conversions.py +5 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/utilities/dns.py +1 -2
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/utilities/ipam_dnssync.py +5 -2
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/views/record.py +17 -7
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_plugin_dns.egg-info/PKG-INFO +2 -2
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_plugin_dns.egg-info/SOURCES.txt +2 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/pyproject.toml +1 -1
- netbox_plugin_dns-1.2.3/netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/LICENSE +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/nested_serializers.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/nameserver.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/prefix.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/record.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/record_template.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/registrar.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/registration_contact.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/serializers_/view.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/urls.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/api/views.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/apps.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/choices/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/choices/record.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/choices/zone.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/fields/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/fields/address.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/fields/ipam.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/fields/network.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/fields/rfc2317.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/filtersets/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/filtersets/nameserver.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/filtersets/record.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/filtersets/record_template.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/filtersets/registrar.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/filtersets/registration_contact.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/filtersets/view.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/filtersets/zone.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/forms/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/forms/nameserver.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/forms/record.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/forms/registrar.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/forms/registration_contact.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/forms/view.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/graphql/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/graphql/filters.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/graphql/schema.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/management/commands/cleanup_database.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/management/commands/cleanup_rrset_ttl.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/management/commands/rebuild_dnssync.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/management/commands/setup_dnssync.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/management/commands/update_soa.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0002_contact_description_registrar_description.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0003_default_view.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0004_create_and_assign_default_view.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0005_alter_zone_view_not_null.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0006_templating.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0007_alter_ordering_options.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0008_view_prefixes.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0009_rename_contact_registrationcontact.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0010_view_ip_address_filter.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0011_rename_related_fields.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0012_natural_ordering.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0022_search.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0024_tenancy.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0026_domain_registration.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/0029_record_fqdn.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/migrations/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/mixins/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/mixins/object_modification.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/models/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/navigation.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/signals/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/signals/ipam_dnssync.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/ipam_dnssync.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/nameserver.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/record.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/record_template.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/registrar.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/registration_contact.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/view.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/tables/zone.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/template_content.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/nameserver.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/record.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/recordtemplate.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/registrar.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/registrationcontact.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/view/button.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/view/prefix.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/view/related.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/view.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zone/child_zone.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zone/delegation_record.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templates/netbox_dns/zone.html +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templatetags/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/templatetags/netbox_dns.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/urls.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/utilities/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/validators/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/validators/dns_name.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/validators/dns_value.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/validators/rfc2317.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/views/__init__.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/views/nameserver.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/views/record_template.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/views/registrar.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/views/registration_contact.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/views/view.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/views/zone.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_dns/views/zone_template.py +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_plugin_dns.egg-info/dependency_links.txt +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_plugin_dns.egg-info/requires.txt +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/netbox_plugin_dns.egg-info/top_level.txt +0 -0
- {netbox_plugin_dns-1.2.3 → netbox_plugin_dns-1.2.5}/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.5
|
|
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
|
|
@@ -99,7 +99,7 @@ PLUGINS = [
|
|
|
99
99
|
]
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
To permanently keep the plugin installed when updating NetBox via `
|
|
102
|
+
To permanently keep the plugin installed when updating NetBox via `upgrade.sh`:
|
|
103
103
|
|
|
104
104
|
```
|
|
105
105
|
echo netbox-plugin-dns >> ~/netbox/local_requirements.txt
|
|
@@ -83,7 +83,7 @@ PLUGINS = [
|
|
|
83
83
|
]
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
To permanently keep the plugin installed when updating NetBox via `
|
|
86
|
+
To permanently keep the plugin installed when updating NetBox via `upgrade.sh`:
|
|
87
87
|
|
|
88
88
|
```
|
|
89
89
|
echo netbox-plugin-dns >> ~/netbox/local_requirements.txt
|
|
@@ -7,7 +7,7 @@ from ipam.choices import IPAddressStatusChoices
|
|
|
7
7
|
|
|
8
8
|
from netbox_dns.choices import RecordTypeChoices, RecordStatusChoices, ZoneStatusChoices
|
|
9
9
|
|
|
10
|
-
__version__ = "1.2.
|
|
10
|
+
__version__ = "1.2.5"
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def _check_list(setting):
|
|
@@ -64,6 +64,7 @@ class DNSConfig(PluginConfig):
|
|
|
64
64
|
"enforce_unique_rrset_ttl": True,
|
|
65
65
|
"menu_name": "DNS",
|
|
66
66
|
"top_level_menu": True,
|
|
67
|
+
"convert_names_to_lowercase": False,
|
|
67
68
|
}
|
|
68
69
|
base_url = "netbox-dns"
|
|
69
70
|
|
|
@@ -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.3 → netbox_plugin_dns-1.2.5}/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)
|
|
@@ -191,6 +191,10 @@ class RecordTemplateImportForm(NetBoxModelImportForm):
|
|
|
191
191
|
class RecordTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
192
192
|
model = RecordTemplate
|
|
193
193
|
|
|
194
|
+
record_name = forms.CharField(
|
|
195
|
+
required=False,
|
|
196
|
+
label=_("Record Name"),
|
|
197
|
+
)
|
|
194
198
|
type = forms.ChoiceField(
|
|
195
199
|
choices=add_blank_choice(RecordSelectableTypeChoices),
|
|
196
200
|
required=False,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from packaging.version import Version
|
|
2
|
+
|
|
1
3
|
from django import forms
|
|
2
4
|
from django.db import transaction
|
|
3
5
|
from django.conf import settings
|
|
@@ -20,6 +22,7 @@ from utilities.forms.fields import (
|
|
|
20
22
|
CSVModelMultipleChoiceField,
|
|
21
23
|
DynamicModelChoiceField,
|
|
22
24
|
)
|
|
25
|
+
from utilities.release import load_release_data
|
|
23
26
|
from utilities.forms.widgets import BulkEditNullBooleanSelect
|
|
24
27
|
from utilities.forms.rendering import FieldSet
|
|
25
28
|
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, add_blank_choice
|
|
@@ -47,6 +50,8 @@ __all__ = (
|
|
|
47
50
|
"ZoneBulkEditForm",
|
|
48
51
|
)
|
|
49
52
|
|
|
53
|
+
QUICK_ADD = Version(load_release_data().version) >= Version("4.2.5")
|
|
54
|
+
|
|
50
55
|
|
|
51
56
|
class RollbackTransaction(Exception):
|
|
52
57
|
pass
|
|
@@ -66,13 +71,20 @@ class ZoneTemplateUpdateMixin:
|
|
|
66
71
|
self.cleaned_data["tags"] = template.tags.all()
|
|
67
72
|
|
|
68
73
|
for field in template.template_fields:
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
):
|
|
74
|
+
if self.cleaned_data.get(field) in (None, "") and getattr(
|
|
75
|
+
template, field
|
|
76
|
+
) not in (None, ""):
|
|
73
77
|
self.cleaned_data[field] = getattr(template, field)
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
if self.cleaned_data.get("soa_mname") is None:
|
|
80
|
+
self.add_error(
|
|
81
|
+
"soa_mname",
|
|
82
|
+
_("soa_mname not set and no template or default value defined"),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
if self.errors:
|
|
86
|
+
return
|
|
87
|
+
|
|
76
88
|
saved_events_queue = events_queue.get()
|
|
77
89
|
|
|
78
90
|
try:
|
|
@@ -106,13 +118,20 @@ class ZoneTemplateUpdateMixin:
|
|
|
106
118
|
raise RollbackTransaction
|
|
107
119
|
|
|
108
120
|
except ValidationError as exc:
|
|
109
|
-
|
|
121
|
+
if hasattr(exc, "error_dict"):
|
|
122
|
+
for field_name in self.fields.keys():
|
|
123
|
+
exc.error_dict.pop(field_name, None)
|
|
124
|
+
errors = exc.error_dict.values()
|
|
125
|
+
else:
|
|
126
|
+
errors = exc.messages
|
|
127
|
+
|
|
128
|
+
for error in errors:
|
|
129
|
+
self.add_error("template", error)
|
|
130
|
+
|
|
110
131
|
except RollbackTransaction:
|
|
111
132
|
pass
|
|
112
133
|
|
|
113
134
|
events_queue.set(saved_events_queue)
|
|
114
|
-
if template_error is not None:
|
|
115
|
-
raise ValidationError({"template": template_error})
|
|
116
135
|
|
|
117
136
|
return self.cleaned_data
|
|
118
137
|
|
|
@@ -126,6 +145,12 @@ class ZoneTemplateUpdateMixin:
|
|
|
126
145
|
|
|
127
146
|
|
|
128
147
|
class ZoneForm(ZoneTemplateUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
148
|
+
view = DynamicModelChoiceField(
|
|
149
|
+
queryset=View.objects.all(),
|
|
150
|
+
required=True,
|
|
151
|
+
label=_("View"),
|
|
152
|
+
quick_add=QUICK_ADD,
|
|
153
|
+
)
|
|
129
154
|
name = forms.CharField(
|
|
130
155
|
required=True,
|
|
131
156
|
label=_("Name"),
|
|
@@ -144,6 +169,7 @@ class ZoneForm(ZoneTemplateUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
|
144
169
|
queryset=NameServer.objects.all(),
|
|
145
170
|
required=False,
|
|
146
171
|
label=_("Nameservers"),
|
|
172
|
+
quick_add=QUICK_ADD,
|
|
147
173
|
)
|
|
148
174
|
default_ttl = forms.IntegerField(
|
|
149
175
|
required=False,
|
|
@@ -161,8 +187,15 @@ class ZoneForm(ZoneTemplateUpdateMixin, TenancyForm, NetBoxModelForm):
|
|
|
161
187
|
validators=[MinValueValidator(1)],
|
|
162
188
|
label=_("SOA TTL"),
|
|
163
189
|
)
|
|
190
|
+
soa_mname = DynamicModelChoiceField(
|
|
191
|
+
queryset=NameServer.objects.all(),
|
|
192
|
+
help_text=_("Primary nameserver this zone"),
|
|
193
|
+
required=False,
|
|
194
|
+
label=_("SOA MName"),
|
|
195
|
+
quick_add=QUICK_ADD,
|
|
196
|
+
)
|
|
164
197
|
soa_rname = forms.CharField(
|
|
165
|
-
required=
|
|
198
|
+
required=False,
|
|
166
199
|
help_text=_("Mailbox of the zone's administrator"),
|
|
167
200
|
label=_("SOA RName"),
|
|
168
201
|
)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from packaging.version import Version
|
|
2
|
+
|
|
1
3
|
from django import forms
|
|
2
4
|
from django.utils.translation import gettext_lazy as _
|
|
3
5
|
|
|
@@ -7,6 +9,7 @@ from netbox.forms import (
|
|
|
7
9
|
NetBoxModelImportForm,
|
|
8
10
|
NetBoxModelForm,
|
|
9
11
|
)
|
|
12
|
+
from utilities.release import load_release_data
|
|
10
13
|
from utilities.forms.fields import (
|
|
11
14
|
DynamicModelMultipleChoiceField,
|
|
12
15
|
TagFilterField,
|
|
@@ -34,19 +37,30 @@ __all__ = (
|
|
|
34
37
|
"ZoneTemplateBulkEditForm",
|
|
35
38
|
)
|
|
36
39
|
|
|
40
|
+
QUICK_ADD = Version(load_release_data().version) >= Version("4.2.5")
|
|
41
|
+
|
|
37
42
|
|
|
38
43
|
class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
39
44
|
nameservers = DynamicModelMultipleChoiceField(
|
|
40
45
|
queryset=NameServer.objects.all(),
|
|
41
46
|
required=False,
|
|
47
|
+
quick_add=QUICK_ADD,
|
|
48
|
+
)
|
|
49
|
+
soa_mname = DynamicModelChoiceField(
|
|
50
|
+
queryset=NameServer.objects.all(),
|
|
51
|
+
required=False,
|
|
52
|
+
label=_("MName"),
|
|
53
|
+
quick_add=QUICK_ADD,
|
|
42
54
|
)
|
|
43
55
|
record_templates = DynamicModelMultipleChoiceField(
|
|
44
56
|
queryset=RecordTemplate.objects.all(),
|
|
45
57
|
required=False,
|
|
58
|
+
quick_add=QUICK_ADD,
|
|
46
59
|
)
|
|
47
60
|
|
|
48
61
|
fieldsets = (
|
|
49
62
|
FieldSet("name", "description", "nameservers", name=_("Zone Template")),
|
|
63
|
+
FieldSet("soa_mname", "soa_rname", name=_("SOA")),
|
|
50
64
|
FieldSet("record_templates", name=_("Record Templates")),
|
|
51
65
|
FieldSet(
|
|
52
66
|
"registrar",
|
|
@@ -66,6 +80,8 @@ class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
|
66
80
|
fields = (
|
|
67
81
|
"name",
|
|
68
82
|
"nameservers",
|
|
83
|
+
"soa_mname",
|
|
84
|
+
"soa_rname",
|
|
69
85
|
"record_templates",
|
|
70
86
|
"description",
|
|
71
87
|
"registrar",
|
|
@@ -77,6 +93,9 @@ class ZoneTemplateForm(TenancyForm, NetBoxModelForm):
|
|
|
77
93
|
"tenant",
|
|
78
94
|
"tags",
|
|
79
95
|
)
|
|
96
|
+
labels = {
|
|
97
|
+
"soa_rname": _("RName"),
|
|
98
|
+
}
|
|
80
99
|
|
|
81
100
|
|
|
82
101
|
class ZoneTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
@@ -84,6 +103,7 @@ class ZoneTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
84
103
|
fieldsets = (
|
|
85
104
|
FieldSet("q", "filter_id", "tag"),
|
|
86
105
|
FieldSet("name", "nameserver_id", "description", name=_("Attributes")),
|
|
106
|
+
FieldSet("soa_mname_id", "soa_rname", name=_("SOA")),
|
|
87
107
|
FieldSet("record_template_id", name=_("Record Templates")),
|
|
88
108
|
FieldSet(
|
|
89
109
|
"registrar_id",
|
|
@@ -105,6 +125,15 @@ class ZoneTemplateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
105
125
|
required=False,
|
|
106
126
|
label=_("Nameservers"),
|
|
107
127
|
)
|
|
128
|
+
soa_mname_id = DynamicModelMultipleChoiceField(
|
|
129
|
+
queryset=NameServer.objects.all(),
|
|
130
|
+
required=False,
|
|
131
|
+
label=_("MName"),
|
|
132
|
+
)
|
|
133
|
+
soa_rname = forms.CharField(
|
|
134
|
+
required=False,
|
|
135
|
+
label=_("RName"),
|
|
136
|
+
)
|
|
108
137
|
record_template_id = DynamicModelMultipleChoiceField(
|
|
109
138
|
queryset=RecordTemplate.objects.all(),
|
|
110
139
|
required=False,
|
|
@@ -148,11 +177,17 @@ class ZoneTemplateImportForm(NetBoxModelImportForm):
|
|
|
148
177
|
required=False,
|
|
149
178
|
label=_("Nameservers"),
|
|
150
179
|
)
|
|
180
|
+
soa_mname = CSVModelChoiceField(
|
|
181
|
+
queryset=NameServer.objects.all(),
|
|
182
|
+
to_field_name="name",
|
|
183
|
+
required=False,
|
|
184
|
+
label=_("SOA MName"),
|
|
185
|
+
)
|
|
151
186
|
record_templates = CSVModelMultipleChoiceField(
|
|
152
187
|
queryset=RecordTemplate.objects.all(),
|
|
153
188
|
to_field_name="name",
|
|
154
189
|
required=False,
|
|
155
|
-
label=_("Record
|
|
190
|
+
label=_("Record Templates"),
|
|
156
191
|
)
|
|
157
192
|
registrar = CSVModelChoiceField(
|
|
158
193
|
queryset=Registrar.objects.all(),
|
|
@@ -212,6 +247,8 @@ class ZoneTemplateImportForm(NetBoxModelImportForm):
|
|
|
212
247
|
fields = (
|
|
213
248
|
"name",
|
|
214
249
|
"nameservers",
|
|
250
|
+
"soa_mname",
|
|
251
|
+
"soa_rname",
|
|
215
252
|
"record_templates",
|
|
216
253
|
"description",
|
|
217
254
|
"registrar",
|
|
@@ -230,12 +267,20 @@ class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
230
267
|
required=False,
|
|
231
268
|
label=_("Nameservers"),
|
|
232
269
|
)
|
|
270
|
+
soa_mname = DynamicModelChoiceField(
|
|
271
|
+
queryset=NameServer.objects.all(),
|
|
272
|
+
required=False,
|
|
273
|
+
label=_("MName"),
|
|
274
|
+
)
|
|
275
|
+
soa_rname = forms.CharField(max_length=255, required=False, label=_("RName"))
|
|
233
276
|
record_templates = DynamicModelMultipleChoiceField(
|
|
234
277
|
queryset=RecordTemplate.objects.all(),
|
|
235
278
|
required=False,
|
|
236
279
|
label=_("Record Templates"),
|
|
237
280
|
)
|
|
238
|
-
description = forms.CharField(
|
|
281
|
+
description = forms.CharField(
|
|
282
|
+
max_length=200, required=False, label=_("Description")
|
|
283
|
+
)
|
|
239
284
|
registrar = DynamicModelChoiceField(
|
|
240
285
|
queryset=Registrar.objects.all(),
|
|
241
286
|
required=False,
|
|
@@ -280,6 +325,11 @@ class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
280
325
|
"description",
|
|
281
326
|
name=_("Attributes"),
|
|
282
327
|
),
|
|
328
|
+
FieldSet(
|
|
329
|
+
"soa_mname",
|
|
330
|
+
"soa_rname",
|
|
331
|
+
name=_("SOA"),
|
|
332
|
+
),
|
|
283
333
|
FieldSet(
|
|
284
334
|
"record_templates",
|
|
285
335
|
name=_("Record Templates"),
|
|
@@ -298,6 +348,8 @@ class ZoneTemplateBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
298
348
|
nullable_fields = (
|
|
299
349
|
"description",
|
|
300
350
|
"nameservers",
|
|
351
|
+
"soa_mname",
|
|
352
|
+
"soa_rname",
|
|
301
353
|
"record_templates",
|
|
302
354
|
"registrar",
|
|
303
355
|
"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.5/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
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Generated by Django 5.1.6 on 2025-02-27 19:36
|
|
2
|
+
|
|
3
|
+
import django.db.models.functions.text
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("extras", "0122_charfield_null_choices"),
|
|
11
|
+
("netbox_dns", "0013_zonetemplate_soa_mname_zonetemplate_soa_rname"),
|
|
12
|
+
("tenancy", "0017_natural_ordering"),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
operations = [
|
|
16
|
+
migrations.AlterUniqueTogether(
|
|
17
|
+
name="zone",
|
|
18
|
+
unique_together=set(),
|
|
19
|
+
),
|
|
20
|
+
migrations.AlterField(
|
|
21
|
+
model_name="nameserver",
|
|
22
|
+
name="name",
|
|
23
|
+
field=models.CharField(db_collation="natural_sort", max_length=255),
|
|
24
|
+
),
|
|
25
|
+
migrations.AddConstraint(
|
|
26
|
+
model_name="nameserver",
|
|
27
|
+
constraint=models.UniqueConstraint(
|
|
28
|
+
django.db.models.functions.text.Lower("name"),
|
|
29
|
+
name="name_unique_ci",
|
|
30
|
+
violation_error_message="There is already a nameserver with this name",
|
|
31
|
+
),
|
|
32
|
+
),
|
|
33
|
+
migrations.AddConstraint(
|
|
34
|
+
model_name="zone",
|
|
35
|
+
constraint=models.UniqueConstraint(
|
|
36
|
+
django.db.models.functions.text.Lower("name"),
|
|
37
|
+
models.F("view"),
|
|
38
|
+
name="name_view_unique_ci",
|
|
39
|
+
violation_error_message="There is already a zone with the same name in this view",
|
|
40
|
+
),
|
|
41
|
+
),
|
|
42
|
+
]
|
|
@@ -2,13 +2,15 @@ from dns import name as dns_name
|
|
|
2
2
|
|
|
3
3
|
from django.core.exceptions import ValidationError
|
|
4
4
|
from django.db import models, transaction
|
|
5
|
-
from django.db.models import Q
|
|
5
|
+
from django.db.models import Q, UniqueConstraint
|
|
6
|
+
from django.db.models.functions import Lower
|
|
6
7
|
from django.urls import reverse
|
|
7
8
|
from django.utils.translation import gettext_lazy as _
|
|
8
9
|
|
|
9
10
|
from netbox.models import NetBoxModel
|
|
10
11
|
from netbox.search import SearchIndex, register_search
|
|
11
12
|
from netbox.models.features import ContactsMixin
|
|
13
|
+
from netbox.plugins.utils import get_plugin_config
|
|
12
14
|
|
|
13
15
|
from netbox_dns.utilities import (
|
|
14
16
|
name_to_unicode,
|
|
@@ -29,7 +31,6 @@ __all__ = (
|
|
|
29
31
|
class NameServer(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
30
32
|
name = models.CharField(
|
|
31
33
|
verbose_name=_("Name"),
|
|
32
|
-
unique=True,
|
|
33
34
|
max_length=255,
|
|
34
35
|
db_collation="natural_sort",
|
|
35
36
|
)
|
|
@@ -59,6 +60,16 @@ class NameServer(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
59
60
|
|
|
60
61
|
ordering = ("name",)
|
|
61
62
|
|
|
63
|
+
constraints = [
|
|
64
|
+
UniqueConstraint(
|
|
65
|
+
Lower("name"),
|
|
66
|
+
name="name_unique_ci",
|
|
67
|
+
violation_error_message=_(
|
|
68
|
+
"There is already a nameserver with this name"
|
|
69
|
+
),
|
|
70
|
+
),
|
|
71
|
+
]
|
|
72
|
+
|
|
62
73
|
def __str__(self):
|
|
63
74
|
try:
|
|
64
75
|
return dns_name.from_text(self.name, origin=None).to_unicode()
|
|
@@ -69,9 +80,16 @@ class NameServer(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
69
80
|
def display_name(self):
|
|
70
81
|
return name_to_unicode(self.name)
|
|
71
82
|
|
|
83
|
+
# TODO: Remove in version 1.3.0 (NetBox #18555)
|
|
72
84
|
def get_absolute_url(self):
|
|
73
85
|
return reverse("plugins:netbox_dns:nameserver", kwargs={"pk": self.pk})
|
|
74
86
|
|
|
87
|
+
def clean_fields(self, exclude=None):
|
|
88
|
+
if get_plugin_config("netbox_dns", "convert_names_to_lowercase", False):
|
|
89
|
+
self.name = self.name.lower()
|
|
90
|
+
|
|
91
|
+
super().clean_fields(exclude=exclude)
|
|
92
|
+
|
|
75
93
|
def clean(self, *args, **kwargs):
|
|
76
94
|
try:
|
|
77
95
|
self.name = normalize_name(self.name)
|
|
@@ -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
|
|
|
@@ -370,9 +371,11 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
370
371
|
if ptr_zone.is_rfc2317_zone:
|
|
371
372
|
ptr_name = self.rfc2317_ptr_name
|
|
372
373
|
else:
|
|
373
|
-
ptr_name =
|
|
374
|
-
ipaddress.ip_address(self.value).reverse_pointer
|
|
375
|
-
|
|
374
|
+
ptr_name = (
|
|
375
|
+
dns_name.from_text(ipaddress.ip_address(self.value).reverse_pointer)
|
|
376
|
+
.relativize(dns_name.from_text(ptr_zone.name))
|
|
377
|
+
.to_text()
|
|
378
|
+
)
|
|
376
379
|
|
|
377
380
|
ptr_value = self.fqdn
|
|
378
381
|
ptr_record = self.ptr_record
|
|
@@ -439,12 +442,16 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
439
442
|
|
|
440
443
|
def update_rfc2317_cname_record(self, save_zone_serial=True):
|
|
441
444
|
if self.zone.rfc2317_parent_managed:
|
|
442
|
-
cname_name =
|
|
443
|
-
|
|
444
|
-
|
|
445
|
+
cname_name = (
|
|
446
|
+
dns_name.from_text(
|
|
447
|
+
ipaddress.ip_address(self.ip_address).reverse_pointer
|
|
448
|
+
)
|
|
449
|
+
.relativize(dns_name.from_text(self.zone.rfc2317_parent_zone.name))
|
|
450
|
+
.to_text()
|
|
451
|
+
)
|
|
445
452
|
|
|
446
453
|
if self.rfc2317_cname_record is not None:
|
|
447
|
-
if self.rfc2317_cname_record.name == cname_name
|
|
454
|
+
if self.rfc2317_cname_record.name == cname_name:
|
|
448
455
|
self.rfc2317_cname_record.zone = self.zone.rfc2317_parent_zone
|
|
449
456
|
self.rfc2317_cname_record.value = self.fqdn
|
|
450
457
|
self.rfc2317_cname_record.ttl = min_ttl(
|
|
@@ -612,7 +619,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
612
619
|
new_zone = self.zone
|
|
613
620
|
|
|
614
621
|
records = new_zone.records.filter(
|
|
615
|
-
|
|
622
|
+
name__iexact=self.name,
|
|
616
623
|
type=self.type,
|
|
617
624
|
value=self.value,
|
|
618
625
|
status__in=RECORD_ACTIVE_STATUS_LIST,
|
|
@@ -769,9 +776,12 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
769
776
|
record.ttl = ttl
|
|
770
777
|
record.save(update_fields=["ttl"], update_rrset_ttl=False)
|
|
771
778
|
|
|
772
|
-
def clean_fields(self,
|
|
779
|
+
def clean_fields(self, exclude=None):
|
|
773
780
|
self.type = self.type.upper()
|
|
774
|
-
|
|
781
|
+
if get_plugin_config("netbox_dns", "convert_names_to_lowercase", False):
|
|
782
|
+
self.name = self.name.lower()
|
|
783
|
+
|
|
784
|
+
super().clean_fields(exclude=exclude)
|
|
775
785
|
|
|
776
786
|
def clean(self, *args, new_zone=None, **kwargs):
|
|
777
787
|
self.validate_name(new_zone=new_zone)
|
|
@@ -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,17 +164,22 @@ 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():
|
|
172
175
|
record.tags.set(tags)
|
|
173
176
|
|
|
174
|
-
def clean_fields(self,
|
|
177
|
+
def clean_fields(self, exclude=None):
|
|
175
178
|
self.type = self.type.upper()
|
|
176
|
-
|
|
179
|
+
if get_plugin_config("netbox_dns", "convert_names_to_lowercase", False):
|
|
180
|
+
self.record_name = self.record_name.lower()
|
|
181
|
+
|
|
182
|
+
super().clean_fields(exclude=exclude)
|
|
177
183
|
|
|
178
184
|
def clean(self, *args, **kwargs):
|
|
179
185
|
self.validate_name()
|