netbox-plugin-dns 1.3b2__tar.gz → 1.3.2__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.3b2 → netbox_plugin_dns-1.3.2}/PKG-INFO +3 -2
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/README.md +1 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/__init__.py +2 -2
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/dnssec_key_template.py +1 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/dnssec_policy.py +1 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/nameserver.py +5 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/record.py +5 -5
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/record.py +2 -2
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/zone.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/dnssec_key_template.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/dnssec_policy.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/nameserver.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/record.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/record_template.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/registrar.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/registration_contact.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/view.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/zone.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/zone_template.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/types.py +2 -3
- netbox_plugin_dns-1.3.2/netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_plugin_dns-1.3.2/netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
- netbox_plugin_dns-1.3.2/netbox_dns/management/commands/remove_orphaned_ptr_records.py +35 -0
- netbox_plugin_dns-1.3.2/netbox_dns/migrations/0021_alter_record_ptr_record.py +25 -0
- netbox_plugin_dns-1.3.2/netbox_dns/migrations/0022_alter_record_ipam_ip_address.py +26 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/record.py +115 -46
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/zone.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/record.py +26 -13
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/view.py +1 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/template_content.py +13 -2
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/record.html +20 -11
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/utilities/ipam_dnssync.py +21 -3
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/validators/dns_name.py +1 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/dnssec_key_template.py +3 -3
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/record.py +19 -3
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/record_template.py +3 -1
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/zone_template.py +5 -3
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_plugin_dns.egg-info/PKG-INFO +3 -2
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_plugin_dns.egg-info/SOURCES.txt +3 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/pyproject.toml +2 -2
- netbox_plugin_dns-1.3b2/netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_plugin_dns-1.3b2/netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/LICENSE +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/field_serializers.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/nested_serializers.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/prefix.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/record_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/registrar.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/registration_contact.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/view.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/zone.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/zone_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/urls.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/views.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/apps.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/choices/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/choices/dnssec_key_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/choices/dnssec_policy.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/choices/record.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/choices/utilities.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/choices/zone.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/fields/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/fields/address.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/fields/choice_array.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/fields/ipam.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/fields/network.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/fields/rfc2317.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/fields/timeperiod.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/dnssec_key_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/dnssec_policy.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/nameserver.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/record_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/registrar.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/registration_contact.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/view.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/zone.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/filtersets/zone_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/dnssec_key_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/dnssec_policy.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/nameserver.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/record.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/record_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/registrar.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/registration_contact.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/view.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/forms/zone_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/enums.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filter_lookups.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/schema.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/management/commands/cleanup_database.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/management/commands/cleanup_rrset_ttl.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/management/commands/rebuild_dnssync.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/management/commands/setup_dnssync.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/management/commands/update_soa.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0002_contact_description_registrar_description.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0003_default_view.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0004_create_and_assign_default_view.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0005_alter_zone_view_not_null.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0006_templating.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0007_alter_ordering_options.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0008_view_prefixes.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0009_rename_contact_registrationcontact.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0010_view_ip_address_filter.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0011_rename_related_fields.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0012_natural_ordering.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0013_zonetemplate_soa_mname_zonetemplate_soa_rname.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0014_alter_unique_constraints_lowercase.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0015_dnssec.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0016_dnssec_policy_status.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0017_dnssec_policy_zone_zone_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0018_zone_domain_status_zone_expiration_date.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0019_dnssecpolicy_parental_agents.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0020_netbox_3_4.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0020_remove_dnssecpolicy_parental_agents_and_more.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0021_record_ip_address.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0022_search.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0023_alter_record_value.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0024_tenancy.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0025_ipam_coupling_cf.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0026_domain_registration.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0027_alter_registrar_iana_id.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0028_rfc2317_fields.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/0029_record_fqdn.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/migrations/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/mixins/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/mixins/object_modification.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/dnssec_key_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/dnssec_policy.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/nameserver.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/record_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/registrar.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/registration_contact.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/view.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/models/zone_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/navigation.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/signals/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/signals/dnssec.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/signals/ipam_dnssync.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/dnssec_key_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/dnssec_policy.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/ipam_dnssync.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/nameserver.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/record_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/registrar.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/registration_contact.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/zone.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/tables/zone_template.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/dnsseckeytemplate.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/dnssecpolicy.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/nameserver.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/record/managed.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/record/related.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/recordtemplate.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/registrar.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/registrationcontact.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/view/button.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/view/prefix.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/view/related.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/view.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zone/base.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zone/child.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zone/child_zone.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zone/delegation_record.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zone/managed_record.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zone/record.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zone/registration.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zone.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zonetemplate/child.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templates/netbox_dns/zonetemplate.html +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templatetags/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/templatetags/netbox_dns.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/urls.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/utilities/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/utilities/conversions.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/utilities/dns.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/validators/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/validators/dns_value.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/validators/dnssec.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/validators/rfc2317.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/__init__.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/dnssec_policy.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/nameserver.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/registrar.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/registration_contact.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/view.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/views/zone.py +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_plugin_dns.egg-info/dependency_links.txt +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_plugin_dns.egg-info/requires.txt +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_plugin_dns.egg-info/top_level.txt +0 -0
- {netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: netbox-plugin-dns
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.2
|
|
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
|
|
@@ -8,7 +8,7 @@ Project-URL: Documentation, https://github.com/peteeckel/netbox-plugin-dns/blob/
|
|
|
8
8
|
Project-URL: Repository, https://github.com/peteeckel/netbox-plugin-dns
|
|
9
9
|
Project-URL: Issues, https://github.com/peteeckel/netbox-plugin-dns/issues
|
|
10
10
|
Keywords: netbox,netbox-plugin,dns
|
|
11
|
-
Classifier: Development Status ::
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
@@ -52,6 +52,7 @@ The main focus of the plugin is to ensure the quality of the data stored in it.
|
|
|
52
52
|
* Support for [RFC 2317](https://datatracker.ietf.org/doc/html/rfc2317) delegation of PTR zones for IPv4 subnets longer than 24 bits
|
|
53
53
|
* Templating for zones and records enables faster creations of zones with given boilerplate object relations, such as name servers, tags, tenants or registration information, or records like standard SPF or MX records that are the same for a subset of zones
|
|
54
54
|
* IPAM DNSsync can be used to automatically create address and pointer records for IP addresses by assigning prefixes to DNS views. When an IP address has a DNS name assigned and there are zones with matching names in the DNS views linked to the IP address' prefix, a matching DNS record will be created in these zones
|
|
55
|
+
* DNSSEC support for storing configuration data relevant to DNSSEC operation in NetBox DNS
|
|
55
56
|
|
|
56
57
|
Other main features include:
|
|
57
58
|
|
|
@@ -35,6 +35,7 @@ The main focus of the plugin is to ensure the quality of the data stored in it.
|
|
|
35
35
|
* Support for [RFC 2317](https://datatracker.ietf.org/doc/html/rfc2317) delegation of PTR zones for IPv4 subnets longer than 24 bits
|
|
36
36
|
* Templating for zones and records enables faster creations of zones with given boilerplate object relations, such as name servers, tags, tenants or registration information, or records like standard SPF or MX records that are the same for a subset of zones
|
|
37
37
|
* IPAM DNSsync can be used to automatically create address and pointer records for IP addresses by assigning prefixes to DNS views. When an IP address has a DNS name assigned and there are zones with matching names in the DNS views linked to the IP address' prefix, a matching DNS record will be created in these zones
|
|
38
|
+
* DNSSEC support for storing configuration data relevant to DNSSEC operation in NetBox DNS
|
|
38
39
|
|
|
39
40
|
Other main features include:
|
|
40
41
|
|
|
@@ -4,7 +4,7 @@ from django.core.exceptions import ImproperlyConfigured
|
|
|
4
4
|
from netbox.plugins import PluginConfig
|
|
5
5
|
from netbox.plugins.utils import get_plugin_config
|
|
6
6
|
|
|
7
|
-
__version__ = "1.3
|
|
7
|
+
__version__ = "1.3.2"
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def _check_list(setting):
|
|
@@ -16,7 +16,7 @@ class DNSConfig(PluginConfig):
|
|
|
16
16
|
name = "netbox_dns"
|
|
17
17
|
verbose_name = _("NetBox DNS")
|
|
18
18
|
description = _("NetBox plugin for DNS data")
|
|
19
|
-
min_version = "4.
|
|
19
|
+
min_version = "4.3.0"
|
|
20
20
|
version = __version__
|
|
21
21
|
author = "Peter Eckel"
|
|
22
22
|
author_email = "pete@netbox-dns.org"
|
{netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/api/serializers_/nameserver.py
RENAMED
|
@@ -48,4 +48,8 @@ class NameServerSerializer(NetBoxModelSerializer):
|
|
|
48
48
|
default=None,
|
|
49
49
|
help_text=_("Zones served by the authoritative nameserver"),
|
|
50
50
|
)
|
|
51
|
-
tenant = TenantSerializer(
|
|
51
|
+
tenant = TenantSerializer(
|
|
52
|
+
nested=True,
|
|
53
|
+
required=False,
|
|
54
|
+
allow_null=True,
|
|
55
|
+
)
|
|
@@ -35,7 +35,7 @@ class RecordSerializer(NetBoxModelSerializer):
|
|
|
35
35
|
"managed",
|
|
36
36
|
"disable_ptr",
|
|
37
37
|
"ptr_record",
|
|
38
|
-
"
|
|
38
|
+
"address_records",
|
|
39
39
|
"active",
|
|
40
40
|
"custom_fields",
|
|
41
41
|
"tenant",
|
|
@@ -71,14 +71,14 @@ class RecordSerializer(NetBoxModelSerializer):
|
|
|
71
71
|
read_only=True,
|
|
72
72
|
required=False,
|
|
73
73
|
allow_null=True,
|
|
74
|
-
help_text=_("PTR record
|
|
74
|
+
help_text=_("PTR record related to an address"),
|
|
75
75
|
)
|
|
76
|
-
|
|
77
|
-
many=
|
|
76
|
+
address_records = NestedRecordSerializer(
|
|
77
|
+
many=True,
|
|
78
78
|
read_only=True,
|
|
79
79
|
required=False,
|
|
80
80
|
allow_null=True,
|
|
81
|
-
help_text=_("Address
|
|
81
|
+
help_text=_("Address records related to the PTR"),
|
|
82
82
|
)
|
|
83
83
|
zone = NestedZoneSerializer(
|
|
84
84
|
many=False,
|
|
@@ -63,10 +63,10 @@ class RecordFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
|
|
|
63
63
|
label=_("View the Parent Zone belongs to"),
|
|
64
64
|
)
|
|
65
65
|
address_record_id = django_filters.ModelMultipleChoiceFilter(
|
|
66
|
-
field_name="
|
|
66
|
+
field_name="address_records",
|
|
67
67
|
queryset=Record.objects.all(),
|
|
68
68
|
to_field_name="id",
|
|
69
|
-
label=_("Address
|
|
69
|
+
label=_("Address Records"),
|
|
70
70
|
)
|
|
71
71
|
ptr_record_id = django_filters.ModelMultipleChoiceFilter(
|
|
72
72
|
field_name="ptr_record",
|
|
@@ -534,7 +534,7 @@ class ZoneFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|
|
534
534
|
)
|
|
535
535
|
parental_agents = forms.GenericIPAddressField(
|
|
536
536
|
required=False,
|
|
537
|
-
label=_("Parental
|
|
537
|
+
label=_("Parental Agents"),
|
|
538
538
|
)
|
|
539
539
|
registrar_id = DynamicModelMultipleChoiceField(
|
|
540
540
|
queryset=Registrar.objects.all(),
|
|
@@ -23,7 +23,7 @@ from netbox_dns.models import DNSSECKeyTemplate
|
|
|
23
23
|
__all__ = ("NetBoxDNSDNSSECKeyTemplateFilter",)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
@strawberry_django.
|
|
26
|
+
@strawberry_django.filter_type(DNSSECKeyTemplate, lookups=True)
|
|
27
27
|
class NetBoxDNSDNSSECKeyTemplateFilter(
|
|
28
28
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
29
29
|
):
|
{netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/dnssec_policy.py
RENAMED
|
@@ -21,7 +21,7 @@ from netbox_dns.graphql.filter_lookups import PolicyDigestArrayLookup
|
|
|
21
21
|
__all__ = ("NetBoxDNSDNSSECPolicyFilter", "PolicyDigestArrayLookup")
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
@strawberry_django.
|
|
24
|
+
@strawberry_django.filter_type(DNSSECPolicy, lookups=True)
|
|
25
25
|
class NetBoxDNSDNSSECPolicyFilter(
|
|
26
26
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
27
27
|
):
|
{netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/nameserver.py
RENAMED
|
@@ -16,7 +16,7 @@ from netbox_dns.models import NameServer
|
|
|
16
16
|
__all__ = ("NetBoxDNSNameServerFilter",)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@strawberry_django.
|
|
19
|
+
@strawberry_django.filter_type(NameServer, lookups=True)
|
|
20
20
|
class NetBoxDNSNameServerFilter(
|
|
21
21
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
22
22
|
):
|
|
@@ -24,7 +24,7 @@ from netbox_dns.models import Record
|
|
|
24
24
|
__all__ = ("NetBoxDNSRecordFilter",)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
@strawberry_django.
|
|
27
|
+
@strawberry_django.filter_type(Record, lookups=True)
|
|
28
28
|
class NetBoxDNSRecordFilter(
|
|
29
29
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
30
30
|
):
|
{netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/record_template.py
RENAMED
|
@@ -20,7 +20,7 @@ from netbox_dns.models import RecordTemplate
|
|
|
20
20
|
__all__ = ("NetBoxDNSRecordTemplateFilter",)
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
@strawberry_django.
|
|
23
|
+
@strawberry_django.filter_type(RecordTemplate, lookups=True)
|
|
24
24
|
class NetBoxDNSRecordTemplateFilter(
|
|
25
25
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
26
26
|
):
|
|
@@ -15,7 +15,7 @@ from netbox_dns.models import Registrar
|
|
|
15
15
|
__all__ = ("NetBoxDNSRegistrarFilter",)
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
@strawberry_django.
|
|
18
|
+
@strawberry_django.filter_type(Registrar, lookups=True)
|
|
19
19
|
class NetBoxDNSRegistrarFilter(NetBoxModelFilterMixin):
|
|
20
20
|
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
|
21
21
|
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
|
@@ -9,7 +9,7 @@ from netbox_dns.models import RegistrationContact
|
|
|
9
9
|
__all__ = ("NetBoxDNSRegistrationContactFilter",)
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
@strawberry_django.
|
|
12
|
+
@strawberry_django.filter_type(RegistrationContact, lookups=True)
|
|
13
13
|
class NetBoxDNSRegistrationContactFilter(NetBoxModelFilterMixin):
|
|
14
14
|
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
|
15
15
|
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
|
@@ -16,7 +16,7 @@ from netbox_dns.models import View
|
|
|
16
16
|
__all__ = ("NetBoxDNSViewFilter",)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@strawberry_django.
|
|
19
|
+
@strawberry_django.filter_type(View, lookups=True)
|
|
20
20
|
class NetBoxDNSViewFilter(
|
|
21
21
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
22
22
|
):
|
|
@@ -23,7 +23,7 @@ from netbox_dns.models import Zone
|
|
|
23
23
|
__all__ = ("NetBoxDNSZoneFilter",)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
@strawberry_django.
|
|
26
|
+
@strawberry_django.filter_type(Zone, lookups=True)
|
|
27
27
|
class NetBoxDNSZoneFilter(
|
|
28
28
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
29
29
|
):
|
{netbox_plugin_dns-1.3b2 → netbox_plugin_dns-1.3.2}/netbox_dns/graphql/filters/zone_template.py
RENAMED
|
@@ -21,7 +21,7 @@ from netbox_dns.models import ZoneTemplate
|
|
|
21
21
|
__all__ = ("NetBoxDNSZoneTemplateFilter",)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
@strawberry_django.
|
|
24
|
+
@strawberry_django.filter_type(ZoneTemplate, lookups=True)
|
|
25
25
|
class NetBoxDNSZoneTemplateFilter(
|
|
26
26
|
ContactFilterMixin, TenancyFilterMixin, NetBoxModelFilterMixin
|
|
27
27
|
):
|
|
@@ -165,10 +165,9 @@ class NetBoxDNSRecordType(NetBoxObjectType):
|
|
|
165
165
|
Annotated["NetBoxDNSRecordType", strawberry.lazy("netbox_dns.graphql.types")]
|
|
166
166
|
| None
|
|
167
167
|
)
|
|
168
|
-
|
|
168
|
+
address_records: List[
|
|
169
169
|
Annotated["NetBoxDNSRecordType", strawberry.lazy("netbox_dns.graphql.types")]
|
|
170
|
-
|
|
171
|
-
)
|
|
170
|
+
]
|
|
172
171
|
rfc2317_ptr_records: List[
|
|
173
172
|
Annotated["NetBoxDNSRecordType", strawberry.lazy("netbox_dns.graphql.types")]
|
|
174
173
|
]
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from django.core.management.base import BaseCommand
|
|
2
|
+
|
|
3
|
+
from netbox_dns.models import Record
|
|
4
|
+
from netbox_dns.choices import RecordTypeChoices
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Command(BaseCommand):
|
|
8
|
+
help = "Remove managed PTR records without an address record"
|
|
9
|
+
|
|
10
|
+
def handle(self, *model_names, **options):
|
|
11
|
+
orphaned_ptr_records = Record.objects.filter(
|
|
12
|
+
type=RecordTypeChoices.PTR,
|
|
13
|
+
address_records__isnull=True,
|
|
14
|
+
managed=True,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if not orphaned_ptr_records.exists():
|
|
18
|
+
if options.get("verbosity") >= 1:
|
|
19
|
+
self.stdout.write("No orphaned PTR records found")
|
|
20
|
+
return
|
|
21
|
+
|
|
22
|
+
if options.get("verbosity") >= 1:
|
|
23
|
+
self.stdout.write(
|
|
24
|
+
f"Removing {orphaned_ptr_records.count()} orphaned PTR record(s) ..."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
for record in orphaned_ptr_records:
|
|
28
|
+
if options.get("verbosity") >= 2:
|
|
29
|
+
self.stdout.write(
|
|
30
|
+
f"removing PTR record {record} from zone {record.zone}"
|
|
31
|
+
)
|
|
32
|
+
record.delete()
|
|
33
|
+
|
|
34
|
+
if options.get("verbosity") >= 1:
|
|
35
|
+
self.stdout.write("... done.")
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated by Django 5.2 on 2025-05-13 09:16
|
|
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", "0020_remove_dnssecpolicy_parental_agents_and_more"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterField(
|
|
15
|
+
model_name="record",
|
|
16
|
+
name="ptr_record",
|
|
17
|
+
field=models.ForeignKey(
|
|
18
|
+
blank=True,
|
|
19
|
+
null=True,
|
|
20
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
21
|
+
related_name="address_records",
|
|
22
|
+
to="netbox_dns.record",
|
|
23
|
+
),
|
|
24
|
+
),
|
|
25
|
+
]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Generated by Django 5.2.1 on 2025-05-19 19:34
|
|
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
|
+
("ipam", "0081_remove_service_device_virtual_machine_add_parent_gfk_index"),
|
|
11
|
+
("netbox_dns", "0021_alter_record_ptr_record"),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.AlterField(
|
|
16
|
+
model_name="record",
|
|
17
|
+
name="ipam_ip_address",
|
|
18
|
+
field=models.ForeignKey(
|
|
19
|
+
blank=True,
|
|
20
|
+
null=True,
|
|
21
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
22
|
+
related_name="netbox_dns_records",
|
|
23
|
+
to="ipam.ipaddress",
|
|
24
|
+
),
|
|
25
|
+
),
|
|
26
|
+
]
|
|
@@ -6,7 +6,7 @@ from dns import name as dns_name
|
|
|
6
6
|
from dns import rdata
|
|
7
7
|
|
|
8
8
|
from django.core.exceptions import ValidationError
|
|
9
|
-
from django.db import
|
|
9
|
+
from django.db import models
|
|
10
10
|
from django.db.models import Q, ExpressionWrapper, BooleanField, Min
|
|
11
11
|
from django.conf import settings
|
|
12
12
|
from django.utils.translation import gettext_lazy as _
|
|
@@ -28,7 +28,6 @@ from netbox_dns.choices import (
|
|
|
28
28
|
RecordClassChoices,
|
|
29
29
|
)
|
|
30
30
|
|
|
31
|
-
|
|
32
31
|
__all__ = (
|
|
33
32
|
"Record",
|
|
34
33
|
"RecordIndex",
|
|
@@ -143,6 +142,11 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
143
142
|
"tenant",
|
|
144
143
|
)
|
|
145
144
|
|
|
145
|
+
def __init__(self, *args, **kwargs):
|
|
146
|
+
super().__init__(*args, **kwargs)
|
|
147
|
+
|
|
148
|
+
self._cleanup_ptr_record = None
|
|
149
|
+
|
|
146
150
|
def __str__(self):
|
|
147
151
|
try:
|
|
148
152
|
fqdn = dns_name.from_text(
|
|
@@ -206,11 +210,11 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
206
210
|
null=False,
|
|
207
211
|
default=False,
|
|
208
212
|
)
|
|
209
|
-
ptr_record = models.
|
|
213
|
+
ptr_record = models.ForeignKey(
|
|
210
214
|
verbose_name=_("PTR Record"),
|
|
211
215
|
to="self",
|
|
212
216
|
on_delete=models.SET_NULL,
|
|
213
|
-
related_name="
|
|
217
|
+
related_name="address_records",
|
|
214
218
|
null=True,
|
|
215
219
|
blank=True,
|
|
216
220
|
)
|
|
@@ -241,7 +245,7 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
241
245
|
ipam_ip_address = models.ForeignKey(
|
|
242
246
|
verbose_name=_("IPAM IP Address"),
|
|
243
247
|
to="ipam.IPAddress",
|
|
244
|
-
on_delete=models.
|
|
248
|
+
on_delete=models.SET_NULL,
|
|
245
249
|
related_name="netbox_dns_records",
|
|
246
250
|
blank=True,
|
|
247
251
|
null=True,
|
|
@@ -255,6 +259,14 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
255
259
|
blank=True,
|
|
256
260
|
)
|
|
257
261
|
|
|
262
|
+
@property
|
|
263
|
+
def cleanup_ptr_record(self):
|
|
264
|
+
return self._cleanup_ptr_record
|
|
265
|
+
|
|
266
|
+
@cleanup_ptr_record.setter
|
|
267
|
+
def cleanup_ptr_record(self, ptr_record):
|
|
268
|
+
self._cleanup_ptr_record = ptr_record
|
|
269
|
+
|
|
258
270
|
@property
|
|
259
271
|
def display_name(self):
|
|
260
272
|
return name_to_unicode(self.name)
|
|
@@ -348,21 +360,42 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
348
360
|
def is_delegation_record(self):
|
|
349
361
|
return self in self.zone.delegation_records
|
|
350
362
|
|
|
363
|
+
def refresh_ptr_record(
|
|
364
|
+
self, ptr_record=None, update_rfc2317_cname=True, save_zone_serial=True
|
|
365
|
+
):
|
|
366
|
+
if ptr_record is None:
|
|
367
|
+
return
|
|
368
|
+
|
|
369
|
+
if not ptr_record.address_records.exists():
|
|
370
|
+
if ptr_record.rfc2317_cname_record is not None:
|
|
371
|
+
ptr_record.remove_from_rfc2317_cname_record()
|
|
372
|
+
|
|
373
|
+
ptr_record.delete(save_zone_serial=save_zone_serial)
|
|
374
|
+
|
|
375
|
+
elif update_rfc2317_cname:
|
|
376
|
+
ptr_record.update_rfc2317_cname_record(save_zone_serial=save_zone_serial)
|
|
377
|
+
|
|
351
378
|
def update_ptr_record(self, update_rfc2317_cname=True, save_zone_serial=True):
|
|
352
379
|
ptr_zone = self.ptr_zone
|
|
353
380
|
|
|
381
|
+
# +
|
|
382
|
+
# Check whether a PTR record is optioned for and return if that is not the
|
|
383
|
+
# case.
|
|
384
|
+
# -
|
|
354
385
|
if (
|
|
355
386
|
ptr_zone is None
|
|
356
387
|
or self.disable_ptr
|
|
357
388
|
or not self.is_active
|
|
358
389
|
or self.name.startswith("*")
|
|
359
390
|
):
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
self.ptr_record.delete()
|
|
363
|
-
self.ptr_record = None
|
|
391
|
+
self.cleanup_ptr_record = self.ptr_record
|
|
392
|
+
self.ptr_record = None
|
|
364
393
|
return
|
|
365
394
|
|
|
395
|
+
# +
|
|
396
|
+
# Determine the ptr_name and ptr_value related to the ptr_zone. RFC2317
|
|
397
|
+
# PTR names and zones need to be handled differently.
|
|
398
|
+
# -
|
|
366
399
|
if ptr_zone.is_rfc2317_zone:
|
|
367
400
|
ptr_name = self.rfc2317_ptr_name
|
|
368
401
|
else:
|
|
@@ -371,51 +404,76 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
371
404
|
.relativize(dns_name.from_text(ptr_zone.name))
|
|
372
405
|
.to_text()
|
|
373
406
|
)
|
|
374
|
-
|
|
375
407
|
ptr_value = self.fqdn
|
|
376
|
-
ptr_record = self.ptr_record
|
|
377
408
|
|
|
378
|
-
|
|
409
|
+
# +
|
|
410
|
+
# If there is an existing and matching PTR record there is nothing to be done.
|
|
411
|
+
# -
|
|
412
|
+
if (ptr_record := self.ptr_record) is not None:
|
|
379
413
|
if (
|
|
380
|
-
|
|
381
|
-
and ptr_record.
|
|
414
|
+
ptr_record.zone == ptr_zone
|
|
415
|
+
and ptr_record.name == ptr_name
|
|
416
|
+
and ptr_record.value == ptr_value
|
|
417
|
+
and ptr_record.ttl == self.ttl
|
|
382
418
|
):
|
|
419
|
+
return
|
|
420
|
+
|
|
421
|
+
# +
|
|
422
|
+
# If there is an RFC2317 CNAME for the PTR record and it is either
|
|
423
|
+
# not required or needs to be changed, remove it.
|
|
424
|
+
# -
|
|
425
|
+
if (
|
|
426
|
+
ptr_record.zone.pk != ptr_zone.pk or not ptr_record.zone.is_rfc2317_zone
|
|
427
|
+
) and ptr_record.rfc2317_cname_record is not None:
|
|
383
428
|
ptr_record.rfc2317_cname_record.delete(
|
|
384
429
|
save_zone_serial=save_zone_serial
|
|
385
430
|
)
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
ptr_record.name != ptr_name
|
|
398
|
-
or ptr_record.value != ptr_value
|
|
399
|
-
or ptr_record.ttl != self.ttl
|
|
400
|
-
):
|
|
401
|
-
ptr_record.name = ptr_name
|
|
402
|
-
ptr_record.value = ptr_value
|
|
403
|
-
ptr_record.ttl = self.ttl
|
|
404
|
-
ptr_record.save(save_zone_serial=save_zone_serial)
|
|
405
|
-
|
|
406
|
-
if ptr_record is None:
|
|
407
|
-
ptr_record = Record(
|
|
408
|
-
zone_id=ptr_zone.pk,
|
|
409
|
-
type=RecordTypeChoices.PTR,
|
|
410
|
-
name=ptr_name,
|
|
411
|
-
ttl=self.ttl,
|
|
412
|
-
value=ptr_value,
|
|
413
|
-
managed=True,
|
|
414
|
-
)
|
|
431
|
+
ptr_record.rfc2317_cname_record = None
|
|
432
|
+
|
|
433
|
+
# +
|
|
434
|
+
# If the PTR record is used exclusively by the address record it can be
|
|
435
|
+
# modified to match the new name, zone, value and TTL.
|
|
436
|
+
# -
|
|
437
|
+
if ptr_record.address_records.count() == 1:
|
|
438
|
+
ptr_record.zone = ptr_zone
|
|
439
|
+
ptr_record.name = ptr_name
|
|
440
|
+
ptr_record.value = ptr_value
|
|
441
|
+
ptr_record.ttl = self.ttl
|
|
415
442
|
ptr_record.save(
|
|
416
443
|
update_rfc2317_cname=update_rfc2317_cname,
|
|
417
444
|
save_zone_serial=save_zone_serial,
|
|
418
445
|
)
|
|
446
|
+
return
|
|
447
|
+
|
|
448
|
+
# +
|
|
449
|
+
# Either there was no PTR record or the existing PTR record could not be re-used,
|
|
450
|
+
# so we need to either get find a matching PTR record or create a new one.
|
|
451
|
+
# -
|
|
452
|
+
try:
|
|
453
|
+
ptr_record = Record.objects.get(
|
|
454
|
+
name=ptr_name,
|
|
455
|
+
zone=ptr_zone,
|
|
456
|
+
type=RecordTypeChoices.PTR,
|
|
457
|
+
value=ptr_value,
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
# +
|
|
461
|
+
# If no existing PTR record could be found in the database, create a new
|
|
462
|
+
# one from scratch.
|
|
463
|
+
# -
|
|
464
|
+
except Record.DoesNotExist:
|
|
465
|
+
ptr_record = Record(
|
|
466
|
+
zone_id=ptr_zone.pk,
|
|
467
|
+
type=RecordTypeChoices.PTR,
|
|
468
|
+
name=ptr_name,
|
|
469
|
+
ttl=self.ttl,
|
|
470
|
+
value=ptr_value,
|
|
471
|
+
managed=True,
|
|
472
|
+
)
|
|
473
|
+
ptr_record.save(
|
|
474
|
+
update_rfc2317_cname=update_rfc2317_cname,
|
|
475
|
+
save_zone_serial=save_zone_serial,
|
|
476
|
+
)
|
|
419
477
|
|
|
420
478
|
self.ptr_record = ptr_record
|
|
421
479
|
|
|
@@ -905,13 +963,19 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
905
963
|
save_zone_serial=save_zone_serial,
|
|
906
964
|
)
|
|
907
965
|
elif self.ptr_record is not None:
|
|
908
|
-
self.ptr_record
|
|
966
|
+
self.cleanup_ptr_record = self.ptr_record
|
|
909
967
|
self.ptr_record = None
|
|
910
968
|
|
|
911
969
|
changed_fields = self.changed_fields
|
|
912
970
|
if changed_fields is None or changed_fields:
|
|
913
971
|
super().save(*args, **kwargs)
|
|
914
972
|
|
|
973
|
+
self.refresh_ptr_record(
|
|
974
|
+
self.cleanup_ptr_record,
|
|
975
|
+
update_rfc2317_cname=update_rfc2317_cname,
|
|
976
|
+
save_zone_serial=save_zone_serial,
|
|
977
|
+
)
|
|
978
|
+
|
|
915
979
|
if self.type != RecordTypeChoices.SOA and self.zone.soa_serial_auto:
|
|
916
980
|
self.zone.update_serial(save_zone_serial=save_zone_serial)
|
|
917
981
|
|
|
@@ -919,11 +983,16 @@ class Record(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
919
983
|
if self.rfc2317_cname_record:
|
|
920
984
|
self.remove_from_rfc2317_cname_record(save_zone_serial=save_zone_serial)
|
|
921
985
|
|
|
922
|
-
|
|
923
|
-
self.ptr_record.delete()
|
|
986
|
+
ptr_record = self.ptr_record
|
|
924
987
|
|
|
925
988
|
super().delete(*args, **kwargs)
|
|
926
989
|
|
|
990
|
+
self.refresh_ptr_record(
|
|
991
|
+
ptr_record,
|
|
992
|
+
update_rfc2317_cname=True,
|
|
993
|
+
save_zone_serial=save_zone_serial,
|
|
994
|
+
)
|
|
995
|
+
|
|
927
996
|
_zone = self.zone
|
|
928
997
|
if _zone.soa_serial_auto:
|
|
929
998
|
_zone.update_serial(save_zone_serial=save_zone_serial)
|
|
@@ -1036,7 +1036,7 @@ class Zone(ObjectModificationMixin, ContactsMixin, NetBoxModel):
|
|
|
1036
1036
|
for address_record in address_records:
|
|
1037
1037
|
address_record.ptr_record.delete()
|
|
1038
1038
|
|
|
1039
|
-
ptr_records = self.records.filter(
|
|
1039
|
+
ptr_records = self.records.filter(address_records__isnull=False)
|
|
1040
1040
|
update_records = list(
|
|
1041
1041
|
Record.objects.filter(ptr_record__in=ptr_records).values_list(
|
|
1042
1042
|
"pk", flat=True
|