netbox-plugin-dns 0.21.4__py3-none-any.whl → 1.4.7__py3-none-any.whl
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.
- netbox_dns/__init__.py +106 -41
- netbox_dns/api/field_serializers.py +25 -0
- netbox_dns/api/nested_serializers.py +95 -52
- netbox_dns/api/serializers.py +14 -296
- netbox_dns/api/serializers_/__init__.py +0 -0
- netbox_dns/api/serializers_/dnssec_key_template.py +69 -0
- netbox_dns/api/serializers_/dnssec_policy.py +165 -0
- netbox_dns/api/serializers_/nameserver.py +56 -0
- netbox_dns/api/serializers_/prefix.py +18 -0
- netbox_dns/api/serializers_/record.py +105 -0
- netbox_dns/api/serializers_/record_template.py +71 -0
- netbox_dns/api/serializers_/registrar.py +45 -0
- netbox_dns/api/serializers_/registration_contact.py +50 -0
- netbox_dns/api/serializers_/view.py +81 -0
- netbox_dns/api/serializers_/zone.py +247 -0
- netbox_dns/api/serializers_/zone_template.py +157 -0
- netbox_dns/api/urls.py +13 -2
- netbox_dns/api/views.py +96 -58
- netbox_dns/choices/__init__.py +4 -0
- netbox_dns/choices/dnssec_key_template.py +67 -0
- netbox_dns/choices/dnssec_policy.py +40 -0
- netbox_dns/choices/record.py +104 -0
- netbox_dns/choices/utilities.py +4 -0
- netbox_dns/choices/zone.py +119 -0
- netbox_dns/fields/__init__.py +4 -0
- netbox_dns/fields/address.py +22 -16
- netbox_dns/fields/choice_array.py +33 -0
- netbox_dns/fields/ipam.py +15 -0
- netbox_dns/fields/network.py +42 -18
- netbox_dns/fields/rfc2317.py +97 -0
- netbox_dns/fields/timeperiod.py +33 -0
- netbox_dns/filters.py +7 -0
- netbox_dns/filtersets/__init__.py +12 -0
- netbox_dns/filtersets/dnssec_key_template.py +57 -0
- netbox_dns/filtersets/dnssec_policy.py +101 -0
- netbox_dns/filtersets/nameserver.py +46 -0
- netbox_dns/filtersets/record.py +135 -0
- netbox_dns/filtersets/record_template.py +59 -0
- netbox_dns/{filters → filtersets}/registrar.py +8 -1
- netbox_dns/{filters/contact.py → filtersets/registration_contact.py} +9 -3
- netbox_dns/filtersets/view.py +45 -0
- netbox_dns/filtersets/zone.py +254 -0
- netbox_dns/filtersets/zone_template.py +165 -0
- netbox_dns/forms/__init__.py +5 -1
- netbox_dns/forms/dnssec_key_template.py +250 -0
- netbox_dns/forms/dnssec_policy.py +654 -0
- netbox_dns/forms/nameserver.py +121 -27
- netbox_dns/forms/record.py +215 -104
- netbox_dns/forms/record_template.py +285 -0
- netbox_dns/forms/registrar.py +108 -31
- netbox_dns/forms/registration_contact.py +282 -0
- netbox_dns/forms/view.py +331 -20
- netbox_dns/forms/zone.py +769 -373
- netbox_dns/forms/zone_template.py +463 -0
- netbox_dns/graphql/__init__.py +25 -22
- netbox_dns/graphql/enums.py +41 -0
- netbox_dns/graphql/filter_lookups.py +13 -0
- netbox_dns/graphql/filters/__init__.py +12 -0
- netbox_dns/graphql/filters/dnssec_key_template.py +63 -0
- netbox_dns/graphql/filters/dnssec_policy.py +124 -0
- netbox_dns/graphql/filters/nameserver.py +32 -0
- netbox_dns/graphql/filters/record.py +89 -0
- netbox_dns/graphql/filters/record_template.py +55 -0
- netbox_dns/graphql/filters/registrar.py +30 -0
- netbox_dns/graphql/filters/registration_contact.py +27 -0
- netbox_dns/graphql/filters/view.py +28 -0
- netbox_dns/graphql/filters/zone.py +147 -0
- netbox_dns/graphql/filters/zone_template.py +97 -0
- netbox_dns/graphql/schema.py +89 -7
- netbox_dns/graphql/types.py +355 -0
- netbox_dns/locale/de/LC_MESSAGES/django.mo +0 -0
- netbox_dns/locale/en/LC_MESSAGES/django.mo +0 -0
- netbox_dns/locale/fr/LC_MESSAGES/django.mo +0 -0
- netbox_dns/management/commands/cleanup_database.py +175 -156
- netbox_dns/management/commands/cleanup_rrset_ttl.py +64 -0
- netbox_dns/management/commands/rebuild_dnssync.py +23 -0
- netbox_dns/management/commands/setup_dnssync.py +140 -0
- netbox_dns/migrations/0001_squashed_netbox_dns_0_15.py +0 -27
- netbox_dns/migrations/0001_squashed_netbox_dns_0_22.py +557 -0
- netbox_dns/migrations/{0013_add_nameserver_zone_record_description.py → 0002_contact_description_registrar_description.py} +4 -9
- netbox_dns/migrations/0003_default_view.py +15 -0
- netbox_dns/migrations/0004_create_and_assign_default_view.py +26 -0
- netbox_dns/migrations/0005_alter_zone_view_not_null.py +18 -0
- netbox_dns/migrations/0006_templating.py +172 -0
- netbox_dns/migrations/0007_alter_ordering_options.py +25 -0
- netbox_dns/migrations/0008_view_prefixes.py +18 -0
- netbox_dns/migrations/0009_rename_contact_registrationcontact.py +36 -0
- netbox_dns/migrations/0010_view_ip_address_filter.py +18 -0
- netbox_dns/migrations/0011_rename_related_fields.py +63 -0
- netbox_dns/migrations/0012_natural_ordering.py +88 -0
- netbox_dns/migrations/0013_zonetemplate_soa_mname_zonetemplate_soa_rname.py +30 -0
- netbox_dns/migrations/0014_alter_unique_constraints_lowercase.py +42 -0
- netbox_dns/migrations/0015_dnssec.py +168 -0
- netbox_dns/migrations/{0015_add_record_status.py → 0016_dnssec_policy_status.py} +5 -4
- netbox_dns/migrations/0017_dnssec_policy_zone_zone_template.py +41 -0
- netbox_dns/migrations/0018_zone_domain_status_zone_expiration_date.py +23 -0
- netbox_dns/migrations/0019_dnssecpolicy_parental_agents.py +25 -0
- netbox_dns/migrations/0020_netbox_3_4.py +1 -1
- netbox_dns/migrations/0020_remove_dnssecpolicy_parental_agents_and_more.py +29 -0
- netbox_dns/migrations/0021_alter_record_ptr_record.py +25 -0
- netbox_dns/migrations/0021_record_ip_address.py +1 -1
- netbox_dns/migrations/0022_alter_record_ipam_ip_address.py +26 -0
- netbox_dns/migrations/0023_disable_ptr_false.py +27 -0
- netbox_dns/migrations/0024_zonetemplate_parental_agents.py +25 -0
- netbox_dns/migrations/0025_remove_zone_inline_signing_and_more.py +22 -0
- netbox_dns/migrations/0026_alter_dnssecpolicy_nsec3_opt_out.py +18 -0
- netbox_dns/migrations/0026_domain_registration.py +1 -1
- netbox_dns/migrations/0027_zone_comments.py +18 -0
- netbox_dns/migrations/0028_alter_zone_default_ttl_alter_zone_soa_minimum_and_more.py +54 -0
- netbox_dns/migrations/0028_rfc2317_fields.py +44 -0
- netbox_dns/migrations/0029_alter_registrationcontact_street.py +18 -0
- netbox_dns/migrations/0029_record_fqdn.py +30 -0
- netbox_dns/mixins/__init__.py +1 -0
- netbox_dns/mixins/object_modification.py +57 -0
- netbox_dns/models/__init__.py +5 -1
- netbox_dns/models/dnssec_key_template.py +114 -0
- netbox_dns/models/dnssec_policy.py +203 -0
- netbox_dns/models/nameserver.py +61 -30
- netbox_dns/models/record.py +781 -234
- netbox_dns/models/record_template.py +198 -0
- netbox_dns/models/registrar.py +34 -15
- netbox_dns/models/{contact.py → registration_contact.py} +72 -43
- netbox_dns/models/view.py +129 -9
- netbox_dns/models/zone.py +806 -242
- netbox_dns/models/zone_template.py +209 -0
- netbox_dns/navigation.py +176 -76
- netbox_dns/signals/__init__.py +0 -0
- netbox_dns/signals/dnssec.py +32 -0
- netbox_dns/signals/ipam_dnssync.py +216 -0
- netbox_dns/tables/__init__.py +5 -1
- netbox_dns/tables/dnssec_key_template.py +49 -0
- netbox_dns/tables/dnssec_policy.py +140 -0
- netbox_dns/tables/ipam_dnssync.py +12 -0
- netbox_dns/tables/nameserver.py +14 -17
- netbox_dns/tables/record.py +117 -59
- netbox_dns/tables/record_template.py +91 -0
- netbox_dns/tables/registrar.py +20 -10
- netbox_dns/tables/{contact.py → registration_contact.py} +22 -11
- netbox_dns/tables/view.py +47 -3
- netbox_dns/tables/zone.py +62 -31
- netbox_dns/tables/zone_template.py +78 -0
- netbox_dns/template_content.py +124 -38
- netbox_dns/templates/netbox_dns/dnsseckeytemplate.html +70 -0
- netbox_dns/templates/netbox_dns/dnssecpolicy.html +163 -0
- netbox_dns/templates/netbox_dns/nameserver.html +31 -28
- netbox_dns/templates/netbox_dns/record/managed.html +2 -1
- netbox_dns/templates/netbox_dns/record/related.html +17 -6
- netbox_dns/templates/netbox_dns/record.html +140 -93
- netbox_dns/templates/netbox_dns/recordtemplate.html +96 -0
- netbox_dns/templates/netbox_dns/registrar.html +41 -34
- netbox_dns/templates/netbox_dns/registrationcontact.html +76 -0
- netbox_dns/templates/netbox_dns/view/button.html +10 -0
- netbox_dns/templates/netbox_dns/view/prefix.html +44 -0
- netbox_dns/templates/netbox_dns/view/related.html +33 -0
- netbox_dns/templates/netbox_dns/view.html +62 -18
- netbox_dns/templates/netbox_dns/zone/base.html +6 -3
- netbox_dns/templates/netbox_dns/zone/child.html +6 -5
- netbox_dns/templates/netbox_dns/zone/child_zone.html +18 -0
- netbox_dns/templates/netbox_dns/zone/delegation_record.html +18 -0
- netbox_dns/templates/netbox_dns/zone/managed_record.html +1 -1
- netbox_dns/templates/netbox_dns/zone/record.html +6 -5
- netbox_dns/templates/netbox_dns/zone/registration.html +43 -24
- netbox_dns/templates/netbox_dns/zone/rfc2317_child_zone.html +18 -0
- netbox_dns/templates/netbox_dns/zone.html +178 -119
- netbox_dns/templates/netbox_dns/zonetemplate/child.html +46 -0
- netbox_dns/templates/netbox_dns/zonetemplate.html +124 -0
- netbox_dns/templatetags/netbox_dns.py +10 -0
- netbox_dns/urls.py +50 -210
- netbox_dns/utilities/__init__.py +3 -0
- netbox_dns/{utilities.py → utilities/conversions.py} +55 -7
- netbox_dns/utilities/dns.py +11 -0
- netbox_dns/utilities/ipam_dnssync.py +370 -0
- netbox_dns/validators/__init__.py +4 -0
- netbox_dns/validators/dns_name.py +116 -0
- netbox_dns/validators/dns_value.py +147 -0
- netbox_dns/validators/dnssec.py +148 -0
- netbox_dns/validators/rfc2317.py +28 -0
- netbox_dns/views/__init__.py +5 -1
- netbox_dns/views/dnssec_key_template.py +78 -0
- netbox_dns/views/dnssec_policy.py +146 -0
- netbox_dns/views/nameserver.py +34 -15
- netbox_dns/views/record.py +156 -15
- netbox_dns/views/record_template.py +93 -0
- netbox_dns/views/registrar.py +32 -13
- netbox_dns/views/registration_contact.py +101 -0
- netbox_dns/views/view.py +58 -14
- netbox_dns/views/zone.py +130 -33
- netbox_dns/views/zone_template.py +82 -0
- netbox_plugin_dns-1.4.7.dist-info/METADATA +132 -0
- netbox_plugin_dns-1.4.7.dist-info/RECORD +201 -0
- {netbox_plugin_dns-0.21.4.dist-info → netbox_plugin_dns-1.4.7.dist-info}/WHEEL +2 -1
- {netbox_plugin_dns-0.21.4.dist-info → netbox_plugin_dns-1.4.7.dist-info/licenses}/LICENSE +2 -1
- netbox_plugin_dns-1.4.7.dist-info/top_level.txt +1 -0
- netbox_dns/filters/__init__.py +0 -6
- netbox_dns/filters/nameserver.py +0 -18
- netbox_dns/filters/record.py +0 -53
- netbox_dns/filters/view.py +0 -18
- netbox_dns/filters/zone.py +0 -112
- netbox_dns/forms/contact.py +0 -211
- netbox_dns/graphql/contact.py +0 -19
- netbox_dns/graphql/nameserver.py +0 -19
- netbox_dns/graphql/record.py +0 -19
- netbox_dns/graphql/registrar.py +0 -19
- netbox_dns/graphql/view.py +0 -19
- netbox_dns/graphql/zone.py +0 -19
- netbox_dns/management/commands/setup_coupling.py +0 -75
- netbox_dns/management/commands/update_soa.py +0 -22
- netbox_dns/middleware.py +0 -226
- netbox_dns/migrations/0001_initial.py +0 -115
- netbox_dns/migrations/0002_zone_default_ttl.py +0 -18
- netbox_dns/migrations/0003_soa_managed_records.py +0 -112
- netbox_dns/migrations/0004_create_ptr_for_a_aaaa_records.py +0 -80
- netbox_dns/migrations/0005_update_ns_records.py +0 -41
- netbox_dns/migrations/0006_zone_soa_serial_auto.py +0 -29
- netbox_dns/migrations/0007_alter_zone_soa_serial_auto.py +0 -17
- netbox_dns/migrations/0008_zone_status_names.py +0 -21
- netbox_dns/migrations/0009_netbox32.py +0 -71
- netbox_dns/migrations/0010_update_soa_records.py +0 -58
- netbox_dns/migrations/0011_add_view_model.py +0 -70
- netbox_dns/migrations/0012_adjust_zone_and_record.py +0 -17
- netbox_dns/migrations/0014_add_view_description.py +0 -16
- netbox_dns/migrations/0016_cleanup_ptr_records.py +0 -38
- netbox_dns/migrations/0017_alter_record_ttl.py +0 -17
- netbox_dns/migrations/0018_zone_arpa_network.py +0 -51
- netbox_dns/migrations/0019_update_ns_ttl.py +0 -19
- netbox_dns/templates/netbox_dns/contact.html +0 -71
- netbox_dns/templates/netbox_dns/related_dns_objects.html +0 -21
- netbox_dns/templatetags/view_helpers.py +0 -15
- netbox_dns/validators.py +0 -57
- netbox_dns/views/contact.py +0 -83
- netbox_plugin_dns-0.21.4.dist-info/METADATA +0 -101
- netbox_plugin_dns-0.21.4.dist-info/RECORD +0 -110
netbox_dns/graphql/nameserver.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from graphene import ObjectType
|
|
2
|
-
|
|
3
|
-
from netbox.graphql.fields import ObjectField, ObjectListField
|
|
4
|
-
from netbox.graphql.types import NetBoxObjectType
|
|
5
|
-
|
|
6
|
-
from netbox_dns.models import NameServer
|
|
7
|
-
from netbox_dns.filters import NameServerFilter
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class NameServerType(NetBoxObjectType):
|
|
11
|
-
class Meta:
|
|
12
|
-
model = NameServer
|
|
13
|
-
fields = "__all__"
|
|
14
|
-
filterset_class = NameServerFilter
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class NameServerQuery(ObjectType):
|
|
18
|
-
nameserver = ObjectField(NameServerType)
|
|
19
|
-
nameserver_list = ObjectListField(NameServerType)
|
netbox_dns/graphql/record.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from graphene import ObjectType
|
|
2
|
-
|
|
3
|
-
from netbox.graphql.fields import ObjectField, ObjectListField
|
|
4
|
-
from netbox.graphql.types import NetBoxObjectType
|
|
5
|
-
|
|
6
|
-
from netbox_dns.models import Record
|
|
7
|
-
from netbox_dns.filters import RecordFilter
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class RecordType(NetBoxObjectType):
|
|
11
|
-
class Meta:
|
|
12
|
-
model = Record
|
|
13
|
-
fields = "__all__"
|
|
14
|
-
filterset_class = RecordFilter
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class RecordQuery(ObjectType):
|
|
18
|
-
record = ObjectField(RecordType)
|
|
19
|
-
record_list = ObjectListField(RecordType)
|
netbox_dns/graphql/registrar.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from graphene import ObjectType
|
|
2
|
-
|
|
3
|
-
from netbox.graphql.fields import ObjectField, ObjectListField
|
|
4
|
-
from netbox.graphql.types import NetBoxObjectType
|
|
5
|
-
|
|
6
|
-
from netbox_dns.models import Registrar
|
|
7
|
-
from netbox_dns.filters import RegistrarFilter
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class RegistrarType(NetBoxObjectType):
|
|
11
|
-
class Meta:
|
|
12
|
-
model = Registrar
|
|
13
|
-
fields = "__all__"
|
|
14
|
-
filterset_class = RegistrarFilter
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class RegistrarQuery(ObjectType):
|
|
18
|
-
registrar = ObjectField(RegistrarType)
|
|
19
|
-
registrar_list = ObjectListField(RegistrarType)
|
netbox_dns/graphql/view.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from graphene import ObjectType
|
|
2
|
-
|
|
3
|
-
from netbox.graphql.fields import ObjectField, ObjectListField
|
|
4
|
-
from netbox.graphql.types import NetBoxObjectType
|
|
5
|
-
|
|
6
|
-
from netbox_dns.models import View
|
|
7
|
-
from netbox_dns.filters import ViewFilter
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ViewType(NetBoxObjectType):
|
|
11
|
-
class Meta:
|
|
12
|
-
model = View
|
|
13
|
-
fields = "__all__"
|
|
14
|
-
filterset_class = ViewFilter
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class ViewQuery(ObjectType):
|
|
18
|
-
view = ObjectField(ViewType)
|
|
19
|
-
view_list = ObjectListField(ViewType)
|
netbox_dns/graphql/zone.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from graphene import ObjectType
|
|
2
|
-
|
|
3
|
-
from netbox.graphql.fields import ObjectField, ObjectListField
|
|
4
|
-
from netbox.graphql.types import NetBoxObjectType
|
|
5
|
-
|
|
6
|
-
from netbox_dns.models import Zone
|
|
7
|
-
from netbox_dns.filters import ZoneFilter
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ZoneType(NetBoxObjectType):
|
|
11
|
-
class Meta:
|
|
12
|
-
model = Zone
|
|
13
|
-
fields = "__all__"
|
|
14
|
-
filterset_class = ZoneFilter
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class ZoneQuery(ObjectType):
|
|
18
|
-
zone = ObjectField(ZoneType)
|
|
19
|
-
zone_list = ObjectListField(ZoneType)
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
from django.core.management.base import BaseCommand, CommandError
|
|
2
|
-
|
|
3
|
-
from django.contrib.contenttypes.models import ContentType
|
|
4
|
-
from extras.models import CustomField
|
|
5
|
-
from extras.choices import CustomFieldTypeChoices
|
|
6
|
-
from ipam.models import IPAddress
|
|
7
|
-
from netbox_dns.models import Record, Zone
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Command(BaseCommand):
|
|
11
|
-
help = "Setup IPAddress custom fields needed for IPAM-DNS coupling"
|
|
12
|
-
|
|
13
|
-
def add_arguments(self, parser):
|
|
14
|
-
parser.add_argument(
|
|
15
|
-
"--remove", action="store_true", help="Remove custom fields"
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
def handle(self, *model_names, **options):
|
|
19
|
-
ipaddress_object_type = ContentType.objects.get_for_model(IPAddress)
|
|
20
|
-
zone_object_type = ContentType.objects.get_for_model(Zone)
|
|
21
|
-
record_object_type = ContentType.objects.get_for_model(Record)
|
|
22
|
-
customfields = ("ipaddress_dns_record_name", "ipaddress_dns_zone_id")
|
|
23
|
-
|
|
24
|
-
if options["remove"]:
|
|
25
|
-
for cf in customfields:
|
|
26
|
-
try:
|
|
27
|
-
CustomField.objects.get(
|
|
28
|
-
name=cf, content_types=ipaddress_object_type
|
|
29
|
-
).delete()
|
|
30
|
-
except:
|
|
31
|
-
self.stderr.write(f"Custom field '{cf}' does not exist!")
|
|
32
|
-
else:
|
|
33
|
-
self.stdout.write(f"Custom field '{cf}' removed")
|
|
34
|
-
|
|
35
|
-
else:
|
|
36
|
-
msg = ""
|
|
37
|
-
for cf in customfields:
|
|
38
|
-
try:
|
|
39
|
-
CustomField.objects.get(
|
|
40
|
-
name=cf, content_types=ipaddress_object_type
|
|
41
|
-
)
|
|
42
|
-
except:
|
|
43
|
-
pass
|
|
44
|
-
else:
|
|
45
|
-
msg += f"custom fields '{cf}' already exists, "
|
|
46
|
-
if msg != "":
|
|
47
|
-
raise CommandError(
|
|
48
|
-
"\n".join(
|
|
49
|
-
(
|
|
50
|
-
"Can't setup IPAM-DNS coupling:",
|
|
51
|
-
msg,
|
|
52
|
-
"Remove them with NetBox command:",
|
|
53
|
-
"python manage.py setup_coupling --remove",
|
|
54
|
-
)
|
|
55
|
-
)
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
cf_name = CustomField.objects.create(
|
|
59
|
-
name="ipaddress_dns_record_name",
|
|
60
|
-
label="Name",
|
|
61
|
-
type=CustomFieldTypeChoices.TYPE_TEXT,
|
|
62
|
-
required=False,
|
|
63
|
-
group_name="DNS",
|
|
64
|
-
)
|
|
65
|
-
cf_name.content_types.set([ipaddress_object_type])
|
|
66
|
-
cf_zone = CustomField.objects.create(
|
|
67
|
-
name="ipaddress_dns_zone_id",
|
|
68
|
-
label="Zone",
|
|
69
|
-
type=CustomFieldTypeChoices.TYPE_OBJECT,
|
|
70
|
-
object_type=zone_object_type,
|
|
71
|
-
required=False,
|
|
72
|
-
group_name="DNS",
|
|
73
|
-
)
|
|
74
|
-
cf_zone.content_types.set([ipaddress_object_type])
|
|
75
|
-
self.stdout.write(f"Custom fields for IPAM-DNS coupling added")
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
from django.core.management.base import BaseCommand
|
|
2
|
-
|
|
3
|
-
from netbox_dns.models import Zone
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class Command(BaseCommand):
|
|
7
|
-
help = "Create or update SOA records for all zones"
|
|
8
|
-
|
|
9
|
-
def add_arguments(self, parser):
|
|
10
|
-
parser.add_argument(
|
|
11
|
-
"--verbose", action="store_true", help="Increase output verbosity"
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
def handle(self, *model_names, **options):
|
|
15
|
-
zones = Zone.objects.all()
|
|
16
|
-
|
|
17
|
-
for zone in zones:
|
|
18
|
-
if options["verbose"]:
|
|
19
|
-
self.stdout.write(f"Updating the SOA record for zone {zone.name}")
|
|
20
|
-
zone.update_soa_record()
|
|
21
|
-
|
|
22
|
-
self.stdout.write(f"All SOA records have been updated")
|
netbox_dns/middleware.py
DELETED
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
from django.db import transaction
|
|
2
|
-
from django.db.models import signals
|
|
3
|
-
from django.core.exceptions import MiddlewareNotUsed, PermissionDenied, ValidationError
|
|
4
|
-
|
|
5
|
-
from ipam.models import IPAddress
|
|
6
|
-
from ipam.choices import IPAddressStatusChoices
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
# NetBox 3.5.0 - 3.5.7, 3.5.9+
|
|
10
|
-
from extras.plugins import get_plugin_config
|
|
11
|
-
except ImportError:
|
|
12
|
-
# NetBox 3.5.8
|
|
13
|
-
from extras.plugins.utils import get_plugin_config
|
|
14
|
-
from netbox.signals import post_clean
|
|
15
|
-
from utilities.permissions import resolve_permission
|
|
16
|
-
|
|
17
|
-
from netbox_dns.models import Zone, Record, RecordTypeChoices, RecordStatusChoices
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def address_record_cf_data(ip_address):
|
|
21
|
-
name = ip_address.custom_field_data.get("ipaddress_dns_record_name")
|
|
22
|
-
zone_id = ip_address.custom_field_data.get("ipaddress_dns_zone_id")
|
|
23
|
-
|
|
24
|
-
if name is None or zone_id is None:
|
|
25
|
-
return None, None
|
|
26
|
-
|
|
27
|
-
return name, zone_id
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def address_record_type(ip_address):
|
|
31
|
-
return RecordTypeChoices.AAAA if ip_address.family == 6 else RecordTypeChoices.A
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def address_record_status(ip_address):
|
|
35
|
-
return (
|
|
36
|
-
RecordStatusChoices.STATUS_ACTIVE
|
|
37
|
-
if ip_address.status == IPAddressStatusChoices.STATUS_ACTIVE
|
|
38
|
-
else RecordStatusChoices.STATUS_INACTIVE
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def new_address_record(ip_address):
|
|
43
|
-
name, zone_id = address_record_cf_data(ip_address)
|
|
44
|
-
|
|
45
|
-
if zone_id is None:
|
|
46
|
-
return None
|
|
47
|
-
|
|
48
|
-
return Record(
|
|
49
|
-
name=name,
|
|
50
|
-
zone_id=zone_id,
|
|
51
|
-
status=address_record_status(ip_address),
|
|
52
|
-
type=address_record_type(ip_address),
|
|
53
|
-
value=str(ip_address.address.ip),
|
|
54
|
-
ipam_ip_address_id=ip_address.id,
|
|
55
|
-
managed=True,
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def get_address_record(ip_address):
|
|
60
|
-
return ip_address.netbox_dns_records.first()
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def update_address_record(record, ip_address):
|
|
64
|
-
name, zone_id = address_record_cf_data(ip_address)
|
|
65
|
-
|
|
66
|
-
record.name = name
|
|
67
|
-
record.zone_id = zone_id
|
|
68
|
-
record.status = address_record_status(ip_address)
|
|
69
|
-
record.value = str(ip_address.address.ip)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def check_address_record(user, record, permission):
|
|
73
|
-
action = resolve_permission(permission)[1]
|
|
74
|
-
|
|
75
|
-
if not user.has_perm(permission):
|
|
76
|
-
raise PermissionDenied()
|
|
77
|
-
|
|
78
|
-
with transaction.atomic():
|
|
79
|
-
if action in {"add", "change"}:
|
|
80
|
-
record.save()
|
|
81
|
-
|
|
82
|
-
queryset = Record.objects.restrict(user=user, action=action)
|
|
83
|
-
if not queryset.filter(pk=record.pk).exists():
|
|
84
|
-
raise PermissionDenied()
|
|
85
|
-
|
|
86
|
-
transaction.set_rollback(True)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
class Action:
|
|
90
|
-
def __init__(self, request):
|
|
91
|
-
self.request = request
|
|
92
|
-
|
|
93
|
-
def post_clean(self, sender, **kwargs):
|
|
94
|
-
ip_address = kwargs.get("instance")
|
|
95
|
-
user = self.request.user
|
|
96
|
-
|
|
97
|
-
try:
|
|
98
|
-
if ip_address.id is None:
|
|
99
|
-
#
|
|
100
|
-
# Handle new IP addresses
|
|
101
|
-
#
|
|
102
|
-
record = new_address_record(ip_address)
|
|
103
|
-
if record is not None:
|
|
104
|
-
check_address_record(user, record, "netbox_dns.add_record")
|
|
105
|
-
else:
|
|
106
|
-
#
|
|
107
|
-
# Handle updates to existing IP addresses
|
|
108
|
-
#
|
|
109
|
-
record = get_address_record(ip_address)
|
|
110
|
-
if record is not None:
|
|
111
|
-
#
|
|
112
|
-
# Update or delete the existing address record
|
|
113
|
-
#
|
|
114
|
-
name, zone_id = address_record_cf_data(ip_address)
|
|
115
|
-
if zone_id is not None:
|
|
116
|
-
#
|
|
117
|
-
# Update the address record
|
|
118
|
-
#
|
|
119
|
-
update_address_record(record, ip_address)
|
|
120
|
-
check_address_record(user, record, "netbox_dns.change_record")
|
|
121
|
-
else:
|
|
122
|
-
#
|
|
123
|
-
# Delete the address record
|
|
124
|
-
#
|
|
125
|
-
check_address_record(user, record, "netbox_dns.delete_record")
|
|
126
|
-
else:
|
|
127
|
-
#
|
|
128
|
-
# Create a new address record
|
|
129
|
-
#
|
|
130
|
-
record = new_address_record(ip_address)
|
|
131
|
-
if record is not None:
|
|
132
|
-
check_address_record(user, record, "netbox_dns.add_record")
|
|
133
|
-
|
|
134
|
-
except ValidationError as exc:
|
|
135
|
-
value = exc.error_dict.pop("name", None)
|
|
136
|
-
if value is not None:
|
|
137
|
-
exc.error_dict["cf_ipaddress_dns_record_name"] = value
|
|
138
|
-
|
|
139
|
-
value = exc.error_dict.pop("value", None)
|
|
140
|
-
if value is not None:
|
|
141
|
-
exc.error_dict["cf_ipaddress_dns_record_name"] = value
|
|
142
|
-
|
|
143
|
-
raise ValidationError(exc)
|
|
144
|
-
|
|
145
|
-
#
|
|
146
|
-
# Update DNS related fields according to the contents of the IPAM-DNS
|
|
147
|
-
# coupling custom fields.
|
|
148
|
-
#
|
|
149
|
-
def pre_save(self, sender, **kwargs):
|
|
150
|
-
ip_address = kwargs.get("instance")
|
|
151
|
-
name, zone_id = address_record_cf_data(ip_address)
|
|
152
|
-
|
|
153
|
-
if zone_id is not None:
|
|
154
|
-
ip_address.dns_name = f"{name}.{Zone.objects.get(pk=zone_id).name}"
|
|
155
|
-
else:
|
|
156
|
-
ip_address.dns_name = ""
|
|
157
|
-
ip_address.custom_field_data["ipaddress_dns_record_name"] = None
|
|
158
|
-
ip_address.custom_field_data["ipaddress_dns_zone_id"] = None
|
|
159
|
-
|
|
160
|
-
#
|
|
161
|
-
# Handle DNS record operation after IPAddress has been created or modified
|
|
162
|
-
#
|
|
163
|
-
def post_save(self, sender, **kwargs):
|
|
164
|
-
ip_address = kwargs.get("instance")
|
|
165
|
-
name, zone_id = address_record_cf_data(ip_address)
|
|
166
|
-
|
|
167
|
-
if zone_id is None:
|
|
168
|
-
#
|
|
169
|
-
# Name/Zone CF data has been removed: Remove the DNS address record
|
|
170
|
-
#
|
|
171
|
-
for record in ip_address.netbox_dns_records.all():
|
|
172
|
-
record.delete()
|
|
173
|
-
|
|
174
|
-
else:
|
|
175
|
-
#
|
|
176
|
-
# Name/Zone CF data is present: Check for a DNS address record
|
|
177
|
-
# and add or modify it as necessary
|
|
178
|
-
#
|
|
179
|
-
record = get_address_record(ip_address)
|
|
180
|
-
if record is None:
|
|
181
|
-
record = new_address_record(ip_address)
|
|
182
|
-
else:
|
|
183
|
-
update_address_record(record, ip_address)
|
|
184
|
-
|
|
185
|
-
record.save()
|
|
186
|
-
|
|
187
|
-
#
|
|
188
|
-
# Delete DNS record before deleting IP address
|
|
189
|
-
#
|
|
190
|
-
def pre_delete(self, sender, **kwargs):
|
|
191
|
-
ip_address = kwargs.get("instance")
|
|
192
|
-
|
|
193
|
-
for record in ip_address.netbox_dns_records.all():
|
|
194
|
-
user = self.request.user
|
|
195
|
-
check_address_record(user, record, "netbox_dns.delete_record")
|
|
196
|
-
|
|
197
|
-
record.delete()
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
class IpamCouplingMiddleware:
|
|
201
|
-
def __init__(self, get_response):
|
|
202
|
-
if not get_plugin_config("netbox_dns", "feature_ipam_coupling"):
|
|
203
|
-
raise MiddlewareNotUsed
|
|
204
|
-
|
|
205
|
-
self.get_response = get_response
|
|
206
|
-
|
|
207
|
-
def __call__(self, request):
|
|
208
|
-
#
|
|
209
|
-
# Connect signals to actions
|
|
210
|
-
#
|
|
211
|
-
action = Action(request)
|
|
212
|
-
connections = [
|
|
213
|
-
(post_clean, action.post_clean),
|
|
214
|
-
(signals.pre_save, action.pre_save),
|
|
215
|
-
(signals.post_save, action.post_save),
|
|
216
|
-
(signals.pre_delete, action.pre_delete),
|
|
217
|
-
]
|
|
218
|
-
for signal, receiver in connections:
|
|
219
|
-
signal.connect(receiver, sender=IPAddress)
|
|
220
|
-
|
|
221
|
-
response = self.get_response(request)
|
|
222
|
-
|
|
223
|
-
for signal, receiver in connections:
|
|
224
|
-
signal.disconnect(receiver)
|
|
225
|
-
|
|
226
|
-
return response
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
# Generated by Django 3.2.5 on 2021-08-13 14:44
|
|
2
|
-
|
|
3
|
-
import django.core.serializers.json
|
|
4
|
-
from django.db import migrations, models
|
|
5
|
-
import django.db.models.deletion
|
|
6
|
-
import taggit.managers
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class Migration(migrations.Migration):
|
|
10
|
-
initial = True
|
|
11
|
-
|
|
12
|
-
dependencies = [
|
|
13
|
-
("extras", "0059_exporttemplate_as_attachment"),
|
|
14
|
-
]
|
|
15
|
-
|
|
16
|
-
operations = [
|
|
17
|
-
migrations.CreateModel(
|
|
18
|
-
name="NameServer",
|
|
19
|
-
fields=[
|
|
20
|
-
("created", models.DateField(auto_now_add=True, null=True)),
|
|
21
|
-
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
|
22
|
-
(
|
|
23
|
-
"custom_field_data",
|
|
24
|
-
models.JSONField(
|
|
25
|
-
blank=True,
|
|
26
|
-
default=dict,
|
|
27
|
-
encoder=django.core.serializers.json.DjangoJSONEncoder,
|
|
28
|
-
),
|
|
29
|
-
),
|
|
30
|
-
("id", models.BigAutoField(primary_key=True, serialize=False)),
|
|
31
|
-
("name", models.CharField(max_length=255, unique=True)),
|
|
32
|
-
(
|
|
33
|
-
"tags",
|
|
34
|
-
taggit.managers.TaggableManager(
|
|
35
|
-
through="extras.TaggedItem", to="extras.Tag"
|
|
36
|
-
),
|
|
37
|
-
),
|
|
38
|
-
],
|
|
39
|
-
options={
|
|
40
|
-
"ordering": ("name", "id"),
|
|
41
|
-
},
|
|
42
|
-
),
|
|
43
|
-
migrations.CreateModel(
|
|
44
|
-
name="Zone",
|
|
45
|
-
fields=[
|
|
46
|
-
("created", models.DateField(auto_now_add=True, null=True)),
|
|
47
|
-
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
|
48
|
-
(
|
|
49
|
-
"custom_field_data",
|
|
50
|
-
models.JSONField(
|
|
51
|
-
blank=True,
|
|
52
|
-
default=dict,
|
|
53
|
-
encoder=django.core.serializers.json.DjangoJSONEncoder,
|
|
54
|
-
),
|
|
55
|
-
),
|
|
56
|
-
("id", models.BigAutoField(primary_key=True, serialize=False)),
|
|
57
|
-
("name", models.CharField(max_length=255, unique=True)),
|
|
58
|
-
(
|
|
59
|
-
"status",
|
|
60
|
-
models.CharField(blank=True, default="active", max_length=50),
|
|
61
|
-
),
|
|
62
|
-
(
|
|
63
|
-
"nameservers",
|
|
64
|
-
models.ManyToManyField(
|
|
65
|
-
blank=True, related_name="zones", to="netbox_dns.NameServer"
|
|
66
|
-
),
|
|
67
|
-
),
|
|
68
|
-
(
|
|
69
|
-
"tags",
|
|
70
|
-
taggit.managers.TaggableManager(
|
|
71
|
-
blank=True, through="extras.TaggedItem", to="extras.Tag"
|
|
72
|
-
),
|
|
73
|
-
),
|
|
74
|
-
],
|
|
75
|
-
options={
|
|
76
|
-
"ordering": ("name", "id"),
|
|
77
|
-
},
|
|
78
|
-
),
|
|
79
|
-
migrations.CreateModel(
|
|
80
|
-
name="Record",
|
|
81
|
-
fields=[
|
|
82
|
-
("created", models.DateField(auto_now_add=True, null=True)),
|
|
83
|
-
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
|
84
|
-
(
|
|
85
|
-
"custom_field_data",
|
|
86
|
-
models.JSONField(
|
|
87
|
-
blank=True,
|
|
88
|
-
default=dict,
|
|
89
|
-
encoder=django.core.serializers.json.DjangoJSONEncoder,
|
|
90
|
-
),
|
|
91
|
-
),
|
|
92
|
-
("id", models.BigAutoField(primary_key=True, serialize=False)),
|
|
93
|
-
("type", models.CharField(max_length=10)),
|
|
94
|
-
("name", models.CharField(max_length=255)),
|
|
95
|
-
("value", models.CharField(max_length=1000)),
|
|
96
|
-
("ttl", models.PositiveIntegerField()),
|
|
97
|
-
(
|
|
98
|
-
"tags",
|
|
99
|
-
taggit.managers.TaggableManager(
|
|
100
|
-
through="extras.TaggedItem", to="extras.Tag"
|
|
101
|
-
),
|
|
102
|
-
),
|
|
103
|
-
(
|
|
104
|
-
"zone",
|
|
105
|
-
models.ForeignKey(
|
|
106
|
-
on_delete=django.db.models.deletion.CASCADE,
|
|
107
|
-
to="netbox_dns.zone",
|
|
108
|
-
),
|
|
109
|
-
),
|
|
110
|
-
],
|
|
111
|
-
options={
|
|
112
|
-
"ordering": ("name", "id"),
|
|
113
|
-
},
|
|
114
|
-
),
|
|
115
|
-
]
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# Generated by Django 3.2.8 on 2021-10-20 11:06
|
|
2
|
-
|
|
3
|
-
from django.db import migrations, models
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class Migration(migrations.Migration):
|
|
7
|
-
dependencies = [
|
|
8
|
-
("netbox_dns", "0001_initial"),
|
|
9
|
-
]
|
|
10
|
-
|
|
11
|
-
operations = [
|
|
12
|
-
migrations.AddField(
|
|
13
|
-
model_name="zone",
|
|
14
|
-
name="default_ttl",
|
|
15
|
-
field=models.PositiveIntegerField(blank=True, default=86400),
|
|
16
|
-
preserve_default=False,
|
|
17
|
-
),
|
|
18
|
-
]
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
# Generated by Django 3.2.9 on 2021-11-04 20:48
|
|
2
|
-
|
|
3
|
-
import django.core.validators
|
|
4
|
-
from django.db import migrations, models
|
|
5
|
-
import django.db.models.deletion
|
|
6
|
-
import taggit.managers
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class Migration(migrations.Migration):
|
|
10
|
-
dependencies = [
|
|
11
|
-
("extras", "0062_clear_secrets_changelog"),
|
|
12
|
-
("netbox_dns", "0002_zone_default_ttl"),
|
|
13
|
-
]
|
|
14
|
-
|
|
15
|
-
operations = [
|
|
16
|
-
migrations.AddField(
|
|
17
|
-
model_name="record",
|
|
18
|
-
name="managed",
|
|
19
|
-
field=models.BooleanField(default=False),
|
|
20
|
-
),
|
|
21
|
-
migrations.AddField(
|
|
22
|
-
model_name="zone",
|
|
23
|
-
name="soa_expire",
|
|
24
|
-
field=models.PositiveIntegerField(
|
|
25
|
-
default=2592000,
|
|
26
|
-
validators=[django.core.validators.MinValueValidator(1)],
|
|
27
|
-
),
|
|
28
|
-
preserve_default=False,
|
|
29
|
-
),
|
|
30
|
-
migrations.AddField(
|
|
31
|
-
model_name="zone",
|
|
32
|
-
name="soa_minimum",
|
|
33
|
-
field=models.PositiveIntegerField(
|
|
34
|
-
default=3600, validators=[django.core.validators.MinValueValidator(1)]
|
|
35
|
-
),
|
|
36
|
-
preserve_default=False,
|
|
37
|
-
),
|
|
38
|
-
migrations.AddField(
|
|
39
|
-
model_name="zone",
|
|
40
|
-
name="soa_mname",
|
|
41
|
-
field=models.ForeignKey(
|
|
42
|
-
default=1,
|
|
43
|
-
on_delete=django.db.models.deletion.PROTECT,
|
|
44
|
-
related_name="zones_soa",
|
|
45
|
-
to="netbox_dns.nameserver",
|
|
46
|
-
),
|
|
47
|
-
preserve_default=False,
|
|
48
|
-
),
|
|
49
|
-
migrations.AddField(
|
|
50
|
-
model_name="zone",
|
|
51
|
-
name="soa_refresh",
|
|
52
|
-
field=models.PositiveIntegerField(
|
|
53
|
-
default=172800, validators=[django.core.validators.MinValueValidator(1)]
|
|
54
|
-
),
|
|
55
|
-
preserve_default=False,
|
|
56
|
-
),
|
|
57
|
-
migrations.AddField(
|
|
58
|
-
model_name="zone",
|
|
59
|
-
name="soa_retry",
|
|
60
|
-
field=models.PositiveIntegerField(
|
|
61
|
-
default=7200, validators=[django.core.validators.MinValueValidator(1)]
|
|
62
|
-
),
|
|
63
|
-
preserve_default=False,
|
|
64
|
-
),
|
|
65
|
-
migrations.AddField(
|
|
66
|
-
model_name="zone",
|
|
67
|
-
name="soa_rname",
|
|
68
|
-
field=models.CharField(default="hostmaster.example.com", max_length=255),
|
|
69
|
-
preserve_default=False,
|
|
70
|
-
),
|
|
71
|
-
migrations.AddField(
|
|
72
|
-
model_name="zone",
|
|
73
|
-
name="soa_serial",
|
|
74
|
-
field=models.PositiveIntegerField(
|
|
75
|
-
default=1,
|
|
76
|
-
validators=[
|
|
77
|
-
django.core.validators.MinValueValidator(1),
|
|
78
|
-
django.core.validators.MaxValueValidator(2147483647),
|
|
79
|
-
],
|
|
80
|
-
),
|
|
81
|
-
preserve_default=False,
|
|
82
|
-
),
|
|
83
|
-
migrations.AddField(
|
|
84
|
-
model_name="zone",
|
|
85
|
-
name="soa_ttl",
|
|
86
|
-
field=models.PositiveIntegerField(
|
|
87
|
-
default=86400, validators=[django.core.validators.MinValueValidator(1)]
|
|
88
|
-
),
|
|
89
|
-
preserve_default=False,
|
|
90
|
-
),
|
|
91
|
-
migrations.AlterField(
|
|
92
|
-
model_name="nameserver",
|
|
93
|
-
name="tags",
|
|
94
|
-
field=taggit.managers.TaggableManager(
|
|
95
|
-
blank=True, through="extras.TaggedItem", to="extras.Tag"
|
|
96
|
-
),
|
|
97
|
-
),
|
|
98
|
-
migrations.AlterField(
|
|
99
|
-
model_name="record",
|
|
100
|
-
name="tags",
|
|
101
|
-
field=taggit.managers.TaggableManager(
|
|
102
|
-
blank=True, through="extras.TaggedItem", to="extras.Tag"
|
|
103
|
-
),
|
|
104
|
-
),
|
|
105
|
-
migrations.AlterField(
|
|
106
|
-
model_name="zone",
|
|
107
|
-
name="default_ttl",
|
|
108
|
-
field=models.PositiveIntegerField(
|
|
109
|
-
blank=True, validators=[django.core.validators.MinValueValidator(1)]
|
|
110
|
-
),
|
|
111
|
-
),
|
|
112
|
-
]
|