Skip to content

Commit

Permalink
Merge pull request #59 from peteeckel/feature/tenancy
Browse files Browse the repository at this point in the history
Add tenancy to the NetBox DNS models
  • Loading branch information
peteeckel authored Sep 17, 2023
2 parents ace61da + 61e5108 commit 166f890
Show file tree
Hide file tree
Showing 24 changed files with 708 additions and 71 deletions.
9 changes: 9 additions & 0 deletions netbox_dns/api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from rest_framework import serializers

from netbox.api.serializers import NetBoxModelSerializer
from tenancy.api.nested_serializers import NestedTenantSerializer

from netbox_dns.api.nested_serializers import (
NestedViewSerializer,
Expand All @@ -15,6 +16,7 @@ class ViewSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name="plugins-api:netbox_dns-api:view-detail"
)
tenant = NestedTenantSerializer(required=False, allow_null=True)

class Meta:
model = View
Expand All @@ -28,6 +30,7 @@ class Meta:
"created",
"last_updated",
"custom_fields",
"tenant",
)


Expand Down Expand Up @@ -56,6 +59,7 @@ class ZoneSerializer(NetBoxModelSerializer):
read_only=True,
allow_null=True,
)
tenant = NestedTenantSerializer(required=False, allow_null=True)

def create(self, validated_data):
nameservers = validated_data.pop("nameservers", None)
Expand Down Expand Up @@ -103,6 +107,7 @@ class Meta:
"soa_minimum",
"active",
"custom_fields",
"tenant",
)


Expand All @@ -117,6 +122,7 @@ class NameServerSerializer(NetBoxModelSerializer):
default=None,
help_text="Zones served by the authoritative nameserver",
)
tenant = NestedTenantSerializer(required=False, allow_null=True)

class Meta:
model = NameServer
Expand All @@ -131,6 +137,7 @@ class Meta:
"created",
"last_updated",
"custom_fields",
"tenant",
)


Expand Down Expand Up @@ -161,6 +168,7 @@ class RecordSerializer(NetBoxModelSerializer):
required=False,
read_only=True,
)
tenant = NestedTenantSerializer(required=False, allow_null=True)

class Meta:
model = Record
Expand All @@ -184,4 +192,5 @@ class Meta:
"address_record",
"active",
"custom_fields",
"tenant",
)
13 changes: 9 additions & 4 deletions netbox_dns/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ def views(self, request, pk=None):


class ZoneViewSet(NetBoxModelViewSet):
queryset = Zone.objects.all().prefetch_related(
"view", "nameservers", "tags", "soa_mname", "record_set"
queryset = Zone.objects.prefetch_related(
"view",
"nameservers",
"tags",
"soa_mname",
"record_set",
"tenant",
)
serializer_class = ZoneSerializer
filterset_class = ZoneFilter
Expand All @@ -55,7 +60,7 @@ def nameservers(self, request, pk=None):


class NameServerViewSet(NetBoxModelViewSet):
queryset = NameServer.objects.all().prefetch_related("zones")
queryset = NameServer.objects.prefetch_related("zones", "tenant")
serializer_class = NameServerSerializer
filterset_class = NameServerFilter

Expand All @@ -67,7 +72,7 @@ def zones(self, request, pk=None):


class RecordViewSet(NetBoxModelViewSet):
queryset = Record.objects.all().prefetch_related("zone", "zone__view")
queryset = Record.objects.all().prefetch_related("zone", "zone__view", "tenant")
serializer_class = RecordSerializer
filterset_class = RecordFilter

Expand Down
10 changes: 3 additions & 7 deletions netbox_dns/filters/nameserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,17 @@
from django.db.models import Q

from netbox.filtersets import NetBoxModelFilterSet
from tenancy.filtersets import TenancyFilterSet

from netbox_dns.models import NameServer


class NameServerFilter(NetBoxModelFilterSet):
"""Filter capabilities for NameServer instances."""

name = django_filters.CharFilter()

class NameServerFilter(TenancyFilterSet, NetBoxModelFilterSet):
class Meta:
model = NameServer
fields = ("id", "name")
fields = ("id", "name", "tenant")

def search(self, queryset, name, value):
"""Perform the filtered search."""
if not value.strip():
return queryset
qs_filter = Q(name__icontains=value)
Expand Down
5 changes: 3 additions & 2 deletions netbox_dns/filters/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
from django.db.models import Q

from netbox.filtersets import NetBoxModelFilterSet
from tenancy.filtersets import TenancyFilterSet

from netbox_dns.models import View, Zone, Record, RecordTypeChoices


class RecordFilter(NetBoxModelFilterSet):
class RecordFilter(TenancyFilterSet, NetBoxModelFilterSet):
"""Filter capabilities for Record instances."""

type = django_filters.MultipleChoiceFilter(
Expand Down Expand Up @@ -38,7 +39,7 @@ class RecordFilter(NetBoxModelFilterSet):

class Meta:
model = Record
fields = ("id", "type", "name", "value", "status", "zone", "managed")
fields = ("id", "type", "name", "value", "status", "zone", "managed", "tenant")

def search(self, queryset, name, value):
"""Perform the filtered search."""
Expand Down
10 changes: 3 additions & 7 deletions netbox_dns/filters/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,17 @@
from django.db.models import Q

from netbox.filtersets import NetBoxModelFilterSet
from tenancy.filtersets import TenancyFilterSet

from netbox_dns.models import View


class ViewFilter(NetBoxModelFilterSet):
"""Filter capabilities for View instances."""

name = django_filters.CharFilter()

class ViewFilter(NetBoxModelFilterSet, TenancyFilterSet):
class Meta:
model = View
fields = ("id", "name")
fields = ("id", "name", "tenant")

def search(self, queryset, name, value):
"""Perform the filtered search."""
if not value.strip():
return queryset
qs_filter = Q(name__icontains=value)
Expand Down
7 changes: 3 additions & 4 deletions netbox_dns/filters/zone.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
from django.db.models import Q

from netbox.filtersets import NetBoxModelFilterSet
from tenancy.filtersets import TenancyFilterSet

from netbox_dns.models import View, Zone, ZoneStatusChoices


class ZoneFilter(NetBoxModelFilterSet):
"""Filter capabilities for Zone instances."""

class ZoneFilter(TenancyFilterSet, NetBoxModelFilterSet):
status = django_filters.ChoiceFilter(
choices=ZoneStatusChoices,
)
Expand All @@ -28,7 +27,7 @@ class ZoneFilter(NetBoxModelFilterSet):

class Meta:
model = Zone
fields = ("id", "name", "view", "status", "nameservers", "active")
fields = ("id", "name", "view", "status", "nameservers", "active", "tenant")

def search(self, queryset, name, value):
"""Perform the filtered search."""
Expand Down
45 changes: 35 additions & 10 deletions netbox_dns/forms/nameserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,37 @@
NetBoxModelForm,
)

from utilities.forms.fields import TagFilterField
from utilities.forms.fields import (
TagFilterField,
CSVModelChoiceField,
DynamicModelChoiceField,
)
from tenancy.models import Tenant
from tenancy.forms import TenancyForm, TenancyFilterForm

from netbox_dns.models import NameServer
from netbox_dns.utilities import name_to_unicode


class NameServerForm(NetBoxModelForm):
"""Form for creating a new NameServer object."""

class NameServerForm(TenancyForm, NetBoxModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

initial_name = self.initial.get("name")
if initial_name:
self.initial["name"] = name_to_unicode(initial_name)

fieldsets = (
("Nameserver", ("name", "description", "tags")),
("Tenancy", ("tenant_group", "tenant")),
)

class Meta:
model = NameServer
fields = ("name", "description", "tags")

fields = ("name", "description", "tags", "tenant")

class NameServerFilterForm(NetBoxModelFilterSetForm):
"""Form for filtering NameServer instances."""

class NameServerFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = NameServer

name = forms.CharField(
Expand All @@ -39,18 +46,36 @@ class NameServerFilterForm(NetBoxModelFilterSetForm):
)
tag = TagFilterField(NameServer)

fieldsets = (
(None, ("q", "filter_id", "tag")),
("Attributes", ("name",)),
("Tenant", ("tenant_group_id", "tenant_id")),
)


class NameServerImportForm(NetBoxModelImportForm):
tenant = CSVModelChoiceField(
queryset=Tenant.objects.all(),
to_field_name="name",
required=False,
help_text="Assigned tenant",
)

class Meta:
model = NameServer

fields = ("name", "description")
fields = (
"name",
"description",
"tenant",
)


class NameServerBulkEditForm(NetBoxModelBulkEditForm):
model = NameServer

description = forms.CharField(max_length=200, required=False)
tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False)

class Meta:
nullable_fields = ("description",)
nullable_fields = ("description", "tenant")
55 changes: 47 additions & 8 deletions netbox_dns/forms/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
)
from utilities.forms.widgets import BulkEditNullBooleanSelect, APISelect
from utilities.forms import add_blank_choice
from tenancy.models import Tenant
from tenancy.forms import TenancyForm, TenancyFilterForm

from netbox_dns.models import View, Zone, Record, RecordTypeChoices, RecordStatusChoices
from netbox_dns.utilities import name_to_unicode


class RecordForm(NetBoxModelForm):
"""Form for creating a new Record object."""

class RecordForm(TenancyForm, NetBoxModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

Expand All @@ -40,6 +40,24 @@ def __init__(self, *args, **kwargs):
label="TTL",
)

fieldsets = (
(
"Record",
(
"name",
"zone",
"type",
"value",
"status",
"ttl",
"disable_ptr",
"description",
"tags",
),
),
("Tenancy", ("tenant_group", "tenant")),
)

class Meta:
model = Record

Expand All @@ -53,13 +71,17 @@ class Meta:
"disable_ptr",
"description",
"tags",
"tenant",
)


class RecordFilterForm(NetBoxModelFilterSetForm):
"""Form for filtering Record instances."""

class RecordFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = Record
fieldsets = (
(None, ("q", "filter_id", "tag")),
("Attributes", ("view_id", "zone_id", "name", "value", "status")),
("Tenant", ("tenant_group_id", "tenant_id")),
)

type = forms.MultipleChoiceField(
choices=add_blank_choice(RecordTypeChoices),
Expand Down Expand Up @@ -137,6 +159,12 @@ def __init__(self, *args, **kwargs):
label="Disable PTR",
help_text="Disable generation of a PTR record",
)
tenant = CSVModelChoiceField(
queryset=Tenant.objects.all(),
to_field_name="name",
required=False,
help_text="Assigned tenant",
)

def is_valid(self):
try:
Expand All @@ -158,6 +186,7 @@ class Meta:
"ttl",
"disable_ptr",
"description",
"tenant",
)


Expand Down Expand Up @@ -191,11 +220,21 @@ class RecordBulkEditForm(NetBoxModelBulkEditForm):
required=False, widget=BulkEditNullBooleanSelect(), label="Disable PTR"
)
description = forms.CharField(max_length=200, required=False)
tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False)

fieldsets = (
(
None,
("zone", "type", "value", "status", "ttl", "disable_ptr", "description"),
(
"zone",
"type",
"value",
"status",
"ttl",
"disable_ptr",
"description",
"tenant",
),
),
)
nullable_fields = ("description", "ttl")
nullable_fields = ("description", "ttl", "tenant")
Loading

0 comments on commit 166f890

Please sign in to comment.