netbox-plugin-dns 0.22.4__tar.gz → 0.22.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-0.22.4 → netbox_plugin_dns-0.22.5}/PKG-INFO +11 -11
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/README.md +9 -10
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/__init__.py +3 -2
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/api/serializers.py +1 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/filters/registrar.py +1 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/forms/registrar.py +11 -1
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/forms/zone.py +31 -21
- netbox_plugin_dns-0.22.5/netbox_dns/management/commands/cleanup_rrset_ttl.py +62 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/models/record.py +141 -25
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/models/zone.py +82 -18
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/registrar.html +4 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/zone.html +7 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/pyproject.toml +5 -2
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/LICENSE +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/api/nested_serializers.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/api/urls.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/api/views.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/apps.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/fields/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/fields/address.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/fields/network.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/fields/rfc2317.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/filters/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/filters/contact.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/filters/nameserver.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/filters/record.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/filters/view.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/filters/zone.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/forms/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/forms/contact.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/forms/nameserver.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/forms/record.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/forms/view.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/graphql/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/graphql/contact.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/graphql/nameserver.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/graphql/record.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/graphql/registrar.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/graphql/schema.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/graphql/view.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/graphql/zone.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/management/commands/cleanup_database.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/management/commands/setup_coupling.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/management/commands/update_soa.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0001_initial.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0002_zone_default_ttl.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0003_soa_managed_records.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0004_create_ptr_for_a_aaaa_records.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0005_update_ns_records.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0006_zone_soa_serial_auto.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0007_alter_zone_soa_serial_auto.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0008_zone_status_names.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0009_netbox32.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0010_update_soa_records.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0011_add_view_model.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0012_adjust_zone_and_record.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0013_add_nameserver_zone_record_description.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0014_add_view_description.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0015_add_record_status.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0016_cleanup_ptr_records.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0017_alter_record_ttl.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0018_zone_arpa_network.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0019_update_ns_ttl.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0022_search.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0024_tenancy.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0026_domain_registration.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/migrations/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/models/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/models/contact.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/models/nameserver.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/models/registrar.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/models/view.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/navigation.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/signals/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/signals/ipam_coupling.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/tables/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/tables/contact.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/tables/nameserver.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/tables/record.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/tables/registrar.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/tables/view.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/tables/zone.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/template_content.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/contact.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/nameserver.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/record.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/related_dns_objects.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/view.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/urls.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/utilities/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/utilities/ipam_coupling.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/validators/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/validators/dns_name.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/validators/rfc2317.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/views/__init__.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/views/contact.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/views/nameserver.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/views/record.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/views/registrar.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/views/view.py +0 -0
- {netbox_plugin_dns-0.22.4 → netbox_plugin_dns-0.22.5}/netbox_dns/views/zone.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: netbox-plugin-dns
|
|
3
|
-
Version: 0.22.
|
|
3
|
+
Version: 0.22.5
|
|
4
4
|
Summary: NetBox DNS is a NetBox plugin for managing DNS data.
|
|
5
5
|
Home-page: https://github.com/peteeckel/netbox-plugin-dns
|
|
6
6
|
License: MIT
|
|
@@ -8,6 +8,7 @@ Keywords: netbox,netbox-plugin,dns
|
|
|
8
8
|
Author: Peter Eckel
|
|
9
9
|
Author-email: pete@netbox-dns.org
|
|
10
10
|
Requires-Python: >=3.8,<4.0
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
12
13
|
Classifier: Programming Language :: Python :: 3
|
|
13
14
|
Classifier: Programming Language :: Python :: 3.8
|
|
@@ -19,16 +20,15 @@ Requires-Dist: dnspython (>=2.2.1,<3.0.0)
|
|
|
19
20
|
Project-URL: Repository, https://github.com/peteeckel/netbox-plugin-dns
|
|
20
21
|
Description-Content-Type: text/markdown
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<p align="center"><i>NetBox DNS is a NetBox plugin for managing DNS views, zones, name servers and records.</i></p>
|
|
23
|
+
# NetBox DNS
|
|
24
|
+
The NetBox DNS plugin enables NetBox to manage operational DNS data such as name servers, zones, records and views, as well as registration data for domains. It can automate tasks like creating PTR records, generating zone serial numbers, NS and SOA records, as well as validate names and values values for resource records to ensure zone data is consistent, current and conforming to the relevant RFCs.
|
|
25
25
|
|
|
26
26
|
<div align="center">
|
|
27
27
|
<a href="https://pypi.org/project/netbox-plugin-dns/"><img src="https://img.shields.io/pypi/v/netbox-plugin-dns" alt="PyPi"/></a>
|
|
28
|
-
<a href="https://github.com/peteeckel/netbox-plugin-dns/stargazers"><img src="https://img.shields.io/github/stars/peteeckel/netbox-plugin-dns" alt="Stars Badge"/></a>
|
|
29
|
-
<a href="https://github.com/peteeckel/netbox-plugin-dns/network/members"><img src="https://img.shields.io/github/forks/peteeckel/netbox-plugin-dns" alt="Forks Badge"/></a>
|
|
30
|
-
<a href="https://github.com/peteeckel/netbox-plugin-dns/pulls"><img src="https://img.shields.io/github/issues-pr/peteeckel/netbox-plugin-dns" alt="Pull Requests Badge"/></a>
|
|
28
|
+
<a href="https://github.com/peteeckel/netbox-plugin-dns/stargazers"><img src="https://img.shields.io/github/stars/peteeckel/netbox-plugin-dns?style=flat" alt="Stars Badge"/></a>
|
|
29
|
+
<a href="https://github.com/peteeckel/netbox-plugin-dns/network/members"><img src="https://img.shields.io/github/forks/peteeckel/netbox-plugin-dns?style=flat" alt="Forks Badge"/></a>
|
|
31
30
|
<a href="https://github.com/peteeckel/netbox-plugin-dns/issues"><img src="https://img.shields.io/github/issues/peteeckel/netbox-plugin-dns" alt="Issues Badge"/></a>
|
|
31
|
+
<a href="https://github.com/peteeckel/netbox-plugin-dns/pulls"><img src="https://img.shields.io/github/issues-pr/peteeckel/netbox-plugin-dns" alt="Pull Requests Badge"/></a>
|
|
32
32
|
<a href="https://github.com/peteeckel/netbox-plugin-dns/graphs/contributors"><img alt="GitHub contributors" src="https://img.shields.io/github/contributors/peteeckel/netbox-plugin-dns?color=2b9348"></a>
|
|
33
33
|
<a href="https://github.com/peteeckel/netbox-plugin-dns/blob/master/LICENSE"><img src="https://img.shields.io/github/license/peteeckel/netbox-plugin-dns?color=2b9348" alt="License Badge"/></a>
|
|
34
34
|
<a href="https://pepy.tech/project/netbox-plugin-dns"><img alt="Downloads" src="https://static.pepy.tech/badge/netbox-plugin-dns"></a>
|
|
@@ -40,10 +40,10 @@ Description-Content-Type: text/markdown
|
|
|
40
40
|
|
|
41
41
|
* Manage name servers, zones and records
|
|
42
42
|
* Automatically generate SOA and NS records for zones
|
|
43
|
-
* Automatically create and update PTR records for IPv4 and IPv6 records
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
43
|
+
* Automatically create and update PTR records for IPv4 and IPv6 address records
|
|
44
|
+
* Organize DNS zones in views for split horizon DNS and multi-site deployments
|
|
45
|
+
* Manage domain registrar and registrant information for domains related to zones
|
|
46
|
+
* Manage RFC2317 reverse zones for IPv4 prefixes with a network mask length longer than 24 bits
|
|
47
47
|
|
|
48
48
|
NetBox DNS is using the standardized NetBox plugin interface, so it also takes advantage of the NetBox tagging and change log features.
|
|
49
49
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
<p align="center"><i>NetBox DNS is a NetBox plugin for managing DNS views, zones, name servers and records.</i></p>
|
|
1
|
+
# NetBox DNS
|
|
2
|
+
The NetBox DNS plugin enables NetBox to manage operational DNS data such as name servers, zones, records and views, as well as registration data for domains. It can automate tasks like creating PTR records, generating zone serial numbers, NS and SOA records, as well as validate names and values values for resource records to ensure zone data is consistent, current and conforming to the relevant RFCs.
|
|
4
3
|
|
|
5
4
|
<div align="center">
|
|
6
5
|
<a href="https://pypi.org/project/netbox-plugin-dns/"><img src="https://img.shields.io/pypi/v/netbox-plugin-dns" alt="PyPi"/></a>
|
|
7
|
-
<a href="https://github.com/peteeckel/netbox-plugin-dns/stargazers"><img src="https://img.shields.io/github/stars/peteeckel/netbox-plugin-dns" alt="Stars Badge"/></a>
|
|
8
|
-
<a href="https://github.com/peteeckel/netbox-plugin-dns/network/members"><img src="https://img.shields.io/github/forks/peteeckel/netbox-plugin-dns" alt="Forks Badge"/></a>
|
|
9
|
-
<a href="https://github.com/peteeckel/netbox-plugin-dns/pulls"><img src="https://img.shields.io/github/issues-pr/peteeckel/netbox-plugin-dns" alt="Pull Requests Badge"/></a>
|
|
6
|
+
<a href="https://github.com/peteeckel/netbox-plugin-dns/stargazers"><img src="https://img.shields.io/github/stars/peteeckel/netbox-plugin-dns?style=flat" alt="Stars Badge"/></a>
|
|
7
|
+
<a href="https://github.com/peteeckel/netbox-plugin-dns/network/members"><img src="https://img.shields.io/github/forks/peteeckel/netbox-plugin-dns?style=flat" alt="Forks Badge"/></a>
|
|
10
8
|
<a href="https://github.com/peteeckel/netbox-plugin-dns/issues"><img src="https://img.shields.io/github/issues/peteeckel/netbox-plugin-dns" alt="Issues Badge"/></a>
|
|
9
|
+
<a href="https://github.com/peteeckel/netbox-plugin-dns/pulls"><img src="https://img.shields.io/github/issues-pr/peteeckel/netbox-plugin-dns" alt="Pull Requests Badge"/></a>
|
|
11
10
|
<a href="https://github.com/peteeckel/netbox-plugin-dns/graphs/contributors"><img alt="GitHub contributors" src="https://img.shields.io/github/contributors/peteeckel/netbox-plugin-dns?color=2b9348"></a>
|
|
12
11
|
<a href="https://github.com/peteeckel/netbox-plugin-dns/blob/master/LICENSE"><img src="https://img.shields.io/github/license/peteeckel/netbox-plugin-dns?color=2b9348" alt="License Badge"/></a>
|
|
13
12
|
<a href="https://pepy.tech/project/netbox-plugin-dns"><img alt="Downloads" src="https://static.pepy.tech/badge/netbox-plugin-dns"></a>
|
|
@@ -19,10 +18,10 @@
|
|
|
19
18
|
|
|
20
19
|
* Manage name servers, zones and records
|
|
21
20
|
* Automatically generate SOA and NS records for zones
|
|
22
|
-
* Automatically create and update PTR records for IPv4 and IPv6 records
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* Automatically create and update PTR records for IPv4 and IPv6 address records
|
|
22
|
+
* Organize DNS zones in views for split horizon DNS and multi-site deployments
|
|
23
|
+
* Manage domain registrar and registrant information for domains related to zones
|
|
24
|
+
* Manage RFC2317 reverse zones for IPv4 prefixes with a network mask length longer than 24 bits
|
|
26
25
|
|
|
27
26
|
NetBox DNS is using the standardized NetBox plugin interface, so it also takes advantage of the NetBox tagging and change log features.
|
|
28
27
|
|
|
@@ -10,7 +10,7 @@ except ImportError:
|
|
|
10
10
|
# NetBox 3.5.8
|
|
11
11
|
from extras.plugins.utils import get_plugin_config
|
|
12
12
|
|
|
13
|
-
__version__ = "0.22.
|
|
13
|
+
__version__ = "0.22.5"
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class DNSConfig(PluginConfig):
|
|
@@ -38,7 +38,8 @@ class DNSConfig(PluginConfig):
|
|
|
38
38
|
],
|
|
39
39
|
"tolerate_non_rfc1035_types": [],
|
|
40
40
|
"enable_root_zones": False,
|
|
41
|
-
"enforce_unique_records":
|
|
41
|
+
"enforce_unique_records": True,
|
|
42
|
+
"enforce_unique_rrset_ttl": True,
|
|
42
43
|
}
|
|
43
44
|
base_url = "netbox-dns"
|
|
44
45
|
|
|
@@ -17,6 +17,7 @@ class RegistrarForm(NetBoxModelForm):
|
|
|
17
17
|
fields = (
|
|
18
18
|
"name",
|
|
19
19
|
"iana_id",
|
|
20
|
+
"address",
|
|
20
21
|
"referral_url",
|
|
21
22
|
"whois_server",
|
|
22
23
|
"abuse_email",
|
|
@@ -29,12 +30,18 @@ class RegistrarFilterForm(NetBoxModelFilterSetForm):
|
|
|
29
30
|
model = Registrar
|
|
30
31
|
fieldsets = (
|
|
31
32
|
(None, ("q", "name", "iana_id", "tags")),
|
|
32
|
-
(
|
|
33
|
+
(
|
|
34
|
+
"Contact",
|
|
35
|
+
("address", "referral_url", "whois_server", "abuse_email", "abuse_phone"),
|
|
36
|
+
),
|
|
33
37
|
)
|
|
34
38
|
|
|
35
39
|
name = forms.CharField(
|
|
36
40
|
required=False,
|
|
37
41
|
)
|
|
42
|
+
address = forms.CharField(
|
|
43
|
+
required=False,
|
|
44
|
+
)
|
|
38
45
|
iana_id = forms.IntegerField(
|
|
39
46
|
required=False,
|
|
40
47
|
label="IANA ID",
|
|
@@ -64,6 +71,7 @@ class RegistrarImportForm(NetBoxModelImportForm):
|
|
|
64
71
|
fields = (
|
|
65
72
|
"name",
|
|
66
73
|
"iana_id",
|
|
74
|
+
"address",
|
|
67
75
|
"referral_url",
|
|
68
76
|
"whois_server",
|
|
69
77
|
"abuse_email",
|
|
@@ -96,6 +104,7 @@ class RegistrarBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
96
104
|
(
|
|
97
105
|
None,
|
|
98
106
|
(
|
|
107
|
+
"address",
|
|
99
108
|
"referral_url",
|
|
100
109
|
"whois_server",
|
|
101
110
|
"abuse_email",
|
|
@@ -105,6 +114,7 @@ class RegistrarBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
105
114
|
)
|
|
106
115
|
|
|
107
116
|
nullable_fields = (
|
|
117
|
+
"address",
|
|
108
118
|
"referral_url",
|
|
109
119
|
"whois_server",
|
|
110
120
|
"abuse_email",
|
|
@@ -315,7 +315,7 @@ class ZoneImportForm(NetBoxModelImportForm):
|
|
|
315
315
|
required=False,
|
|
316
316
|
help_text="Mailbox of the zone's administrator",
|
|
317
317
|
)
|
|
318
|
-
soa_serial_auto = forms.
|
|
318
|
+
soa_serial_auto = forms.NullBooleanField(
|
|
319
319
|
required=False,
|
|
320
320
|
help_text="Generate the SOA serial",
|
|
321
321
|
)
|
|
@@ -443,26 +443,6 @@ class ZoneImportForm(NetBoxModelImportForm):
|
|
|
443
443
|
def clean_soa_rname(self):
|
|
444
444
|
return self._clean_field_with_defaults("soa_rname")
|
|
445
445
|
|
|
446
|
-
def clean_soa_serial_auto(self):
|
|
447
|
-
try:
|
|
448
|
-
return self._clean_field_with_defaults("soa_serial_auto")
|
|
449
|
-
except ValidationError:
|
|
450
|
-
if self.cleaned_data["soa_serial"] or self._get_default_value("soa_serial"):
|
|
451
|
-
return None
|
|
452
|
-
|
|
453
|
-
raise
|
|
454
|
-
|
|
455
|
-
def clean_soa_serial(self):
|
|
456
|
-
try:
|
|
457
|
-
return self._clean_field_with_defaults("soa_serial")
|
|
458
|
-
except ValidationError:
|
|
459
|
-
if self.cleaned_data["soa_serial_auto"] or self._get_default_value(
|
|
460
|
-
"soa_serial_auto"
|
|
461
|
-
):
|
|
462
|
-
return None
|
|
463
|
-
|
|
464
|
-
raise
|
|
465
|
-
|
|
466
446
|
def clean_soa_refresh(self):
|
|
467
447
|
return self._clean_field_with_defaults("soa_refresh")
|
|
468
448
|
|
|
@@ -475,6 +455,36 @@ class ZoneImportForm(NetBoxModelImportForm):
|
|
|
475
455
|
def clean_soa_minimum(self):
|
|
476
456
|
return self._clean_field_with_defaults("soa_minimum")
|
|
477
457
|
|
|
458
|
+
def clean(self, *args, **kwargs):
|
|
459
|
+
super().clean(*args, **kwargs)
|
|
460
|
+
|
|
461
|
+
soa_serial_auto = self.cleaned_data.get("soa_serial_auto")
|
|
462
|
+
soa_serial = self.cleaned_data.get("soa_serial")
|
|
463
|
+
|
|
464
|
+
if soa_serial is None:
|
|
465
|
+
soa_serial = self._get_default_value("soa_serial")
|
|
466
|
+
|
|
467
|
+
if soa_serial_auto is None:
|
|
468
|
+
if self._get_default_value("soa_serial_auto") is not None:
|
|
469
|
+
soa_serial_auto = self._get_default_value("soa_serial_auto")
|
|
470
|
+
|
|
471
|
+
elif soa_serial is not None:
|
|
472
|
+
soa_serial_auto = False
|
|
473
|
+
|
|
474
|
+
else:
|
|
475
|
+
raise ValidationError(
|
|
476
|
+
"SOA Serial Auto not set and no default value and SOA Serial available"
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
if "soa_serial_auto" in self.cleaned_data:
|
|
480
|
+
self.cleaned_data["soa_serial_auto"] = soa_serial_auto
|
|
481
|
+
|
|
482
|
+
if "soa_serial" in self.cleaned_data:
|
|
483
|
+
if soa_serial_auto:
|
|
484
|
+
self.cleaned_data["soa_serial"] = None
|
|
485
|
+
else:
|
|
486
|
+
self.cleaned_data["soa_serial"] = soa_serial
|
|
487
|
+
|
|
478
488
|
class Meta:
|
|
479
489
|
model = Zone
|
|
480
490
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from django.core.management.base import BaseCommand
|
|
2
|
+
from django.db.models import Max, Min
|
|
3
|
+
|
|
4
|
+
from netbox_dns.models import (
|
|
5
|
+
Record,
|
|
6
|
+
RecordTypeChoices,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Command(BaseCommand):
|
|
11
|
+
help = "Clean up the TTLs for RRSets"
|
|
12
|
+
|
|
13
|
+
def add_arguments(self, parser):
|
|
14
|
+
min_max = parser.add_mutually_exclusive_group()
|
|
15
|
+
min_max.add_argument(
|
|
16
|
+
"--min",
|
|
17
|
+
action="store_true",
|
|
18
|
+
help="Use the minimum TTL of an RRSet for all Records",
|
|
19
|
+
)
|
|
20
|
+
min_max.add_argument(
|
|
21
|
+
"--max",
|
|
22
|
+
action="store_true",
|
|
23
|
+
help="Use the maximum TTL of an RRSet for all Records",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
def handle(self, *model_names, **options):
|
|
27
|
+
self.cleanup_rrset_ttl(**options)
|
|
28
|
+
|
|
29
|
+
self.stdout.write("RRSet cleanup completed.")
|
|
30
|
+
|
|
31
|
+
def cleanup_rrset_ttl(self, **options):
|
|
32
|
+
verbose = options.get("verbosity") > 1
|
|
33
|
+
|
|
34
|
+
ttl_records = (
|
|
35
|
+
Record.objects.filter(ttl__isnull=False)
|
|
36
|
+
.exclude(type=RecordTypeChoices.SOA)
|
|
37
|
+
.exclude(type=RecordTypeChoices.PTR, maanged=True)
|
|
38
|
+
)
|
|
39
|
+
for record in ttl_records:
|
|
40
|
+
records = Record.objects.filter(
|
|
41
|
+
name=record.name,
|
|
42
|
+
zone=record.zone,
|
|
43
|
+
type=record.type,
|
|
44
|
+
).exclude(type=RecordTypeChoices.PTR, maanged=True)
|
|
45
|
+
|
|
46
|
+
if records.count() == 1:
|
|
47
|
+
if options.get("verbosity") > 2:
|
|
48
|
+
self.stdout.write(f"Ignoring single record {record.id} ({record})")
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
if options.get("max"):
|
|
52
|
+
ttl = records.aggregate(Max("ttl")).get("ttl__max")
|
|
53
|
+
else:
|
|
54
|
+
ttl = records.aggregate(Min("ttl")).get("ttl__min")
|
|
55
|
+
|
|
56
|
+
for record in records.exclude(ttl=ttl):
|
|
57
|
+
if options.get("verbosity") > 1:
|
|
58
|
+
self.stdout.write(
|
|
59
|
+
f"Updating TTL for record {record.id} ({record}) to {ttl}"
|
|
60
|
+
)
|
|
61
|
+
record.ttl = ttl
|
|
62
|
+
record.save(update_fields=["ttl"], update_rrset_ttl=False)
|
|
@@ -6,7 +6,7 @@ from dns import name as dns_name
|
|
|
6
6
|
|
|
7
7
|
from django.core.exceptions import ValidationError
|
|
8
8
|
from django.db import transaction, models
|
|
9
|
-
from django.db.models import Q, ExpressionWrapper, BooleanField
|
|
9
|
+
from django.db.models import Q, ExpressionWrapper, BooleanField, Min
|
|
10
10
|
from django.db.models.functions import Length
|
|
11
11
|
from django.urls import reverse
|
|
12
12
|
|
|
@@ -38,6 +38,10 @@ from netbox_dns.validators import (
|
|
|
38
38
|
import netbox_dns.models.zone as zone
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
def min_ttl(*ttl_list):
|
|
42
|
+
return min((ttl for ttl in ttl_list if ttl is not None), default=None)
|
|
43
|
+
|
|
44
|
+
|
|
41
45
|
class RecordManager(models.Manager.from_queryset(RestrictedQuerySet)):
|
|
42
46
|
"""Special Manager for records providing the activity status annotation"""
|
|
43
47
|
|
|
@@ -207,7 +211,8 @@ class Record(NetBoxModel):
|
|
|
207
211
|
try:
|
|
208
212
|
name = (
|
|
209
213
|
dns_name.from_text(
|
|
210
|
-
|
|
214
|
+
str(self.name),
|
|
215
|
+
origin=dns_name.from_text(self.zone.name, origin=None),
|
|
211
216
|
)
|
|
212
217
|
.relativize(dns_name.root)
|
|
213
218
|
.to_unicode()
|
|
@@ -309,7 +314,7 @@ class Record(NetBoxModel):
|
|
|
309
314
|
|
|
310
315
|
return ptr_zone
|
|
311
316
|
|
|
312
|
-
def update_ptr_record(self, update_rfc2317_cname=True):
|
|
317
|
+
def update_ptr_record(self, update_rfc2317_cname=True, save_zone_serial=True):
|
|
313
318
|
ptr_zone = self.ptr_zone
|
|
314
319
|
|
|
315
320
|
if (
|
|
@@ -339,14 +344,16 @@ class Record(NetBoxModel):
|
|
|
339
344
|
not ptr_record.zone.is_rfc2317_zone
|
|
340
345
|
and ptr_record.rfc2317_cname_record is not None
|
|
341
346
|
):
|
|
342
|
-
ptr_record.rfc2317_cname_record.delete(
|
|
347
|
+
ptr_record.rfc2317_cname_record.delete(
|
|
348
|
+
save_zone_serial=save_zone_serial
|
|
349
|
+
)
|
|
343
350
|
|
|
344
351
|
with transaction.atomic():
|
|
345
352
|
if ptr_record is not None:
|
|
346
353
|
if ptr_record.zone.pk != ptr_zone.pk:
|
|
347
354
|
if ptr_record.rfc2317_cname_record is not None:
|
|
348
355
|
ptr_record.rfc2317_cname_record.delete()
|
|
349
|
-
ptr_record.delete()
|
|
356
|
+
ptr_record.delete(save_zone_serial=save_zone_serial)
|
|
350
357
|
ptr_record = None
|
|
351
358
|
|
|
352
359
|
else:
|
|
@@ -358,7 +365,7 @@ class Record(NetBoxModel):
|
|
|
358
365
|
ptr_record.name = ptr_name
|
|
359
366
|
ptr_record.value = ptr_value
|
|
360
367
|
ptr_record.ttl = self.ttl
|
|
361
|
-
ptr_record.save()
|
|
368
|
+
ptr_record.save(save_zone_serial=save_zone_serial)
|
|
362
369
|
|
|
363
370
|
if ptr_record is None:
|
|
364
371
|
ptr_record = Record(
|
|
@@ -369,11 +376,14 @@ class Record(NetBoxModel):
|
|
|
369
376
|
value=ptr_value,
|
|
370
377
|
managed=True,
|
|
371
378
|
)
|
|
372
|
-
ptr_record.save(
|
|
379
|
+
ptr_record.save(
|
|
380
|
+
update_rfc2317_cname=update_rfc2317_cname,
|
|
381
|
+
save_zone_serial=save_zone_serial,
|
|
382
|
+
)
|
|
373
383
|
|
|
374
384
|
self.ptr_record = ptr_record
|
|
375
385
|
|
|
376
|
-
def update_rfc2317_cname_record(self):
|
|
386
|
+
def update_rfc2317_cname_record(self, save_zone_serial=True):
|
|
377
387
|
if self.zone.rfc2317_parent_managed:
|
|
378
388
|
cname_name = dns_name.from_text(
|
|
379
389
|
ipaddress.ip_address(self.ip_address).reverse_pointer
|
|
@@ -383,7 +393,13 @@ class Record(NetBoxModel):
|
|
|
383
393
|
self.rfc2317_cname_record.name = cname_name
|
|
384
394
|
self.rfc2317_cname_record.zone = self.zone.rfc2317_parent_zone
|
|
385
395
|
self.rfc2317_cname_record.value = self.fqdn
|
|
386
|
-
self.rfc2317_cname_record.
|
|
396
|
+
self.rfc2317_cname_record.ttl = min_ttl(
|
|
397
|
+
self.rfc2317_cname_record.rfc2317_ptr_records.exclude(pk=self.pk)
|
|
398
|
+
.aggregate(Min("ttl"))
|
|
399
|
+
.get("ttl__min"),
|
|
400
|
+
self.ttl,
|
|
401
|
+
)
|
|
402
|
+
self.rfc2317_cname_record.save(save_zone_serial=save_zone_serial)
|
|
387
403
|
else:
|
|
388
404
|
rfc2317_cname_record = Record.objects.filter(
|
|
389
405
|
name=cname_name,
|
|
@@ -392,20 +408,34 @@ class Record(NetBoxModel):
|
|
|
392
408
|
managed=True,
|
|
393
409
|
value=self.fqdn,
|
|
394
410
|
).first()
|
|
395
|
-
|
|
396
|
-
|
|
411
|
+
|
|
412
|
+
if rfc2317_cname_record is not None:
|
|
413
|
+
rfc2317_cname_record.ttl = min_ttl(
|
|
414
|
+
rfc2317_cname_record.rfc2317_ptr_records.exclude(pk=self.pk)
|
|
415
|
+
.aggregate(Min("ttl"))
|
|
416
|
+
.get("ttl__min"),
|
|
417
|
+
self.ttl,
|
|
418
|
+
)
|
|
419
|
+
rfc2317_cname_record.save(
|
|
420
|
+
update_fields=["ttl"], save_zone_serial=save_zone_serial
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
else:
|
|
424
|
+
rfc2317_cname_record = Record(
|
|
397
425
|
name=cname_name,
|
|
398
426
|
type=RecordTypeChoices.CNAME,
|
|
399
427
|
zone=self.zone.rfc2317_parent_zone,
|
|
400
428
|
managed=True,
|
|
401
429
|
value=self.fqdn,
|
|
430
|
+
ttl=self.ttl,
|
|
402
431
|
)
|
|
432
|
+
rfc2317_cname_record.save(save_zone_serial=save_zone_serial)
|
|
403
433
|
|
|
404
434
|
self.rfc2317_cname_record = rfc2317_cname_record
|
|
405
435
|
|
|
406
436
|
else:
|
|
407
437
|
if self.rfc2317_cname_record is not None:
|
|
408
|
-
self.rfc2317_cname_record.delete()
|
|
438
|
+
self.rfc2317_cname_record.delete(save_zone_serial=save_zone_serial)
|
|
409
439
|
self.rfc2317_cname_record = None
|
|
410
440
|
|
|
411
441
|
def validate_name(self):
|
|
@@ -475,7 +505,7 @@ class Record(NetBoxModel):
|
|
|
475
505
|
}
|
|
476
506
|
) from None
|
|
477
507
|
|
|
478
|
-
def
|
|
508
|
+
def check_unique_record(self):
|
|
479
509
|
if not get_plugin_config("netbox_dns", "enforce_unique_records", False):
|
|
480
510
|
return
|
|
481
511
|
|
|
@@ -489,6 +519,10 @@ class Record(NetBoxModel):
|
|
|
489
519
|
value=self.value,
|
|
490
520
|
status__in=Record.ACTIVE_STATUS_LIST,
|
|
491
521
|
)
|
|
522
|
+
|
|
523
|
+
if self.pk is not None:
|
|
524
|
+
records = records.exclude(pk=self.pk)
|
|
525
|
+
|
|
492
526
|
if len(records):
|
|
493
527
|
raise ValidationError(
|
|
494
528
|
{
|
|
@@ -496,6 +530,64 @@ class Record(NetBoxModel):
|
|
|
496
530
|
}
|
|
497
531
|
) from None
|
|
498
532
|
|
|
533
|
+
def check_unique_rrset_ttl(self):
|
|
534
|
+
if self.pk is not None:
|
|
535
|
+
return
|
|
536
|
+
|
|
537
|
+
if not get_plugin_config("netbox_dns", "enforce_unique_rrset_ttl", False):
|
|
538
|
+
return
|
|
539
|
+
|
|
540
|
+
if self.type == RecordTypeChoices.PTR and self.managed:
|
|
541
|
+
return
|
|
542
|
+
|
|
543
|
+
records = (
|
|
544
|
+
Record.objects.filter(
|
|
545
|
+
zone=self.zone,
|
|
546
|
+
name=self.name,
|
|
547
|
+
type=self.type,
|
|
548
|
+
)
|
|
549
|
+
.exclude(ttl=self.ttl)
|
|
550
|
+
.exclude(type=RecordTypeChoices.PTR, managed=True)
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
if not records.exists():
|
|
554
|
+
return
|
|
555
|
+
|
|
556
|
+
conflicting_ttls = ", ".join(set(str(record.ttl) for record in records))
|
|
557
|
+
raise ValidationError(
|
|
558
|
+
{
|
|
559
|
+
"ttl": f"There is at least one active {self.type} record for name {self.name} in zone {self.zone} and TTL is different ({conflicting_ttls})."
|
|
560
|
+
}
|
|
561
|
+
) from None
|
|
562
|
+
|
|
563
|
+
def update_rrset_ttl(self, ttl=None):
|
|
564
|
+
if self.pk is None:
|
|
565
|
+
return
|
|
566
|
+
|
|
567
|
+
if not get_plugin_config("netbox_dns", "enforce_unique_rrset_ttl", False):
|
|
568
|
+
return
|
|
569
|
+
|
|
570
|
+
if self.type == RecordTypeChoices.PTR and self.managed:
|
|
571
|
+
return
|
|
572
|
+
|
|
573
|
+
if ttl is None:
|
|
574
|
+
ttl = self.ttl
|
|
575
|
+
|
|
576
|
+
records = (
|
|
577
|
+
Record.objects.filter(
|
|
578
|
+
zone=self.zone,
|
|
579
|
+
name=self.name,
|
|
580
|
+
type=self.type,
|
|
581
|
+
)
|
|
582
|
+
.exclude(pk=self.pk)
|
|
583
|
+
.exclude(ttl=ttl)
|
|
584
|
+
.exclude(type=RecordTypeChoices.PTR, managed=True)
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
for record in records:
|
|
588
|
+
record.ttl = ttl
|
|
589
|
+
record.save(update_fields=["ttl"], update_rrset_ttl=False)
|
|
590
|
+
|
|
499
591
|
def clean_fields(self, *args, **kwargs):
|
|
500
592
|
self.type = self.type.upper()
|
|
501
593
|
super().clean_fields(*args, **kwargs)
|
|
@@ -503,7 +595,9 @@ class Record(NetBoxModel):
|
|
|
503
595
|
def clean(self, *args, **kwargs):
|
|
504
596
|
self.validate_name()
|
|
505
597
|
self.validate_value()
|
|
506
|
-
self.
|
|
598
|
+
self.check_unique_record()
|
|
599
|
+
if self.pk is None:
|
|
600
|
+
self.check_unique_rrset_ttl()
|
|
507
601
|
|
|
508
602
|
if not self.is_active:
|
|
509
603
|
return
|
|
@@ -578,14 +672,24 @@ class Record(NetBoxModel):
|
|
|
578
672
|
}
|
|
579
673
|
) from None
|
|
580
674
|
|
|
581
|
-
def save(
|
|
675
|
+
def save(
|
|
676
|
+
self,
|
|
677
|
+
*args,
|
|
678
|
+
update_rfc2317_cname=True,
|
|
679
|
+
save_zone_serial=True,
|
|
680
|
+
update_rrset_ttl=True,
|
|
681
|
+
**kwargs,
|
|
682
|
+
):
|
|
582
683
|
self.full_clean()
|
|
583
684
|
|
|
685
|
+
if self.pk is not None and update_rrset_ttl:
|
|
686
|
+
self.update_rrset_ttl()
|
|
687
|
+
|
|
584
688
|
if self.is_ptr_record:
|
|
585
689
|
if self.zone.is_rfc2317_zone:
|
|
586
690
|
self.ip_address = self.address_from_rfc2317_name
|
|
587
691
|
if update_rfc2317_cname:
|
|
588
|
-
self.update_rfc2317_cname_record()
|
|
692
|
+
self.update_rfc2317_cname_record(save_zone_serial=save_zone_serial)
|
|
589
693
|
else:
|
|
590
694
|
self.ip_address = self.address_from_name
|
|
591
695
|
|
|
@@ -595,7 +699,10 @@ class Record(NetBoxModel):
|
|
|
595
699
|
self.ip_address = None
|
|
596
700
|
|
|
597
701
|
if self.is_address_record:
|
|
598
|
-
self.update_ptr_record(
|
|
702
|
+
self.update_ptr_record(
|
|
703
|
+
update_rfc2317_cname=update_rfc2317_cname,
|
|
704
|
+
save_zone_serial=save_zone_serial,
|
|
705
|
+
)
|
|
599
706
|
elif self.ptr_record is not None:
|
|
600
707
|
self.ptr_record.delete()
|
|
601
708
|
self.ptr_record = None
|
|
@@ -604,15 +711,24 @@ class Record(NetBoxModel):
|
|
|
604
711
|
|
|
605
712
|
zone = self.zone
|
|
606
713
|
if self.type != RecordTypeChoices.SOA and zone.soa_serial_auto:
|
|
607
|
-
zone.update_serial()
|
|
714
|
+
zone.update_serial(save_zone_serial=save_zone_serial)
|
|
608
715
|
|
|
609
|
-
def delete(self, *args, **kwargs):
|
|
716
|
+
def delete(self, *args, save_zone_serial=True, **kwargs):
|
|
610
717
|
if self.rfc2317_cname_record:
|
|
611
|
-
if
|
|
612
|
-
self.rfc2317_cname_record.
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
718
|
+
if self.rfc2317_cname_record.pk:
|
|
719
|
+
if self.rfc2317_cname_record.rfc2317_ptr_records.count() == 1:
|
|
720
|
+
self.rfc2317_cname_record.delete()
|
|
721
|
+
else:
|
|
722
|
+
self.rfc2317_cname_record.ttl = (
|
|
723
|
+
self.rfc2317_cname_record.rfc2317_ptr_records.exclude(
|
|
724
|
+
pk=self.pk
|
|
725
|
+
)
|
|
726
|
+
.aggregate(Min("ttl"))
|
|
727
|
+
.get("ttl__min")
|
|
728
|
+
)
|
|
729
|
+
self.rfc2317_cname_record.save(
|
|
730
|
+
update_fields=["ttl"], save_zone_serial=save_zone_serial
|
|
731
|
+
)
|
|
616
732
|
|
|
617
733
|
if self.ptr_record:
|
|
618
734
|
self.ptr_record.delete()
|
|
@@ -621,7 +737,7 @@ class Record(NetBoxModel):
|
|
|
621
737
|
|
|
622
738
|
zone = self.zone
|
|
623
739
|
if zone.soa_serial_auto:
|
|
624
|
-
zone.update_serial()
|
|
740
|
+
zone.update_serial(save_zone_serial=save_zone_serial)
|
|
625
741
|
|
|
626
742
|
|
|
627
743
|
@register_search
|