Skip to content

Commit

Permalink
Fixes #487 by implementing option 5 in the issue.
Browse files Browse the repository at this point in the history
Supports: python3.7+, django 3.2+. Tests included for this range.
Breaking changes: None

This implementation uses django-filter as intended. It sets a default filter backend and uses standard filter_class models where possible.

Exceptions take place in the following views:

HostList. Relies on manipulating the queryset, and said manipulation is also used in the filter-less HostDetail.
*Zone*List. The abstraction model for these views is based around propagating a filterset into the parent class.
Concerns:

This patch creates explicit mapping filters for JSONField and CIDRField. It is unclear how well-tested these are.
  • Loading branch information
terjekv committed Mar 30, 2023
1 parent 01e0b40 commit ae7fc74
Show file tree
Hide file tree
Showing 13 changed files with 382 additions and 263 deletions.
21 changes: 0 additions & 21 deletions .coveragerc

This file was deleted.

37 changes: 19 additions & 18 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
on:
push:
paths-ignore:
- 'ci/**'
- 'README.md'
- "ci/**"
- "README.md"

pull_request:

Expand Down Expand Up @@ -30,11 +30,11 @@ jobs:
matrix:
os: [ubuntu-latest]
python-version:
- '3.7'
- '3.8'
- '3.9'
- '3.10'
- '3.11'
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
steps:
- name: Checkout
uses: actions/checkout@v3
Expand All @@ -56,16 +56,17 @@ jobs:
# Needed to build the native python-ldap extension.
sudo apt-get update
sudo apt-get -y install libsasl2-dev libldap2-dev
pip install -r requirements.txt
pip install -r requirements-dev.txt
python -m pip install --upgrade pip
python -m pip install tox tox-gh-actions
python -m pip install -r requirements-test.txt
- name: Test with tox
run: tox -r
env:
MREG_DB_PASSWORD: postgres
- name: Check migrations
run: python manage.py makemigrations --check
- name: Export OpenAPI schema
run: python manage.py generateschema > openapi.yml
- name: Test
run: coverage run manage.py test -v2
env:
MREG_DB_PASSWORD: postgres
- name: Upload OpenAPI schema
if: matrix.python-version == '3.10'
uses: actions/upload-artifact@v3
Expand All @@ -87,11 +88,11 @@ jobs:
matrix:
os: [ubuntu-latest]
python-version:
- '3.7'
- '3.8'
- '3.9'
- '3.10'
- '3.11'
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
18 changes: 7 additions & 11 deletions hostpolicy/api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from rest_framework import status
from rest_framework.response import Response

from url_filter.filtersets import ModelFilterSet
from django_filters import rest_framework as filters

from hostpolicy.models import HostPolicyAtom, HostPolicyRole
from hostpolicy.api.permissions import IsSuperOrHostPolicyAdminOrReadOnly
Expand All @@ -20,14 +20,16 @@
from . import serializers


class HostPolicyAtomFilterSet(ModelFilterSet):
class HostPolicyAtomFilterSet(filters.FilterSet):
class Meta:
model = HostPolicyAtom
fields = '__all__'


class HostPolicyRoleFilterSet(ModelFilterSet):
class HostPolicyRoleFilterSet(filters.FilterSet):
class Meta:
model = HostPolicyRole
fields = '__all__'


class HostPolicyAtomLogMixin(HistoryLog):
Expand Down Expand Up @@ -61,10 +63,7 @@ class HostPolicyAtomList(HostPolicyAtomLogMixin, MregListCreateAPIView):
serializer_class = serializers.HostPolicyAtomSerializer
permission_classes = (IsSuperOrHostPolicyAdminOrReadOnly, )
lookup_field = 'name'

def get_queryset(self):
qs = super().get_queryset()
return HostPolicyRoleFilterSet(data=self.request.GET, queryset=qs).filter()
filter_class = HostPolicyRoleFilterSet

def post(self, request, *args, **kwargs):
if "name" in request.data:
Expand Down Expand Up @@ -96,10 +95,7 @@ class HostPolicyRoleList(HostPolicyRoleLogMixin, MregListCreateAPIView):
serializer_class = serializers.HostPolicyRoleSerializer
permission_classes = (IsSuperOrHostPolicyAdminOrReadOnly, )
lookup_field = 'name'

def get_queryset(self):
qs = _role_prefetcher(super().get_queryset())
return HostPolicyRoleFilterSet(data=self.request.GET, queryset=qs).filter()
filter_class = HostPolicyRoleFilterSet

def post(self, request, *args, **kwargs):
if "name" in request.data:
Expand Down
181 changes: 181 additions & 0 deletions mreg/api/v1/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
from django_filters import rest_framework as filters

from mreg.models import (
BACnetID,
Cname,
ForwardZone,
ForwardZoneDelegation,
Hinfo,
History,
Host,
HostGroup,
Ipaddress,
Label,
Loc,
Mx,
NameServer,
Naptr,
NetGroupRegexPermission,
Network,
NetworkExcludedRange,
PtrOverride,
ReverseZone,
ReverseZoneDelegation,
Srv,
Sshfp,
Txt,
)


class JSONFieldExactFilter(filters.BaseCSVFilter, filters.CharFilter):
pass


class CIDRFieldExactFilter(filters.BaseCSVFilter, filters.CharFilter):
pass


class BACnetIDFilterSet(filters.FilterSet):
class Meta:
model = BACnetID
fields = "__all__"


class CnameFilterSet(filters.FilterSet):
class Meta:
model = Cname
fields = "__all__"


class ForwardZoneFilterSet(filters.FilterSet):
class Meta:
model = ForwardZone
fields = "__all__"


class ForwardZoneDelegationFilterSet(filters.FilterSet):
class Meta:
model = ForwardZoneDelegation
fields = "__all__"


class HinfoFilterSet(filters.FilterSet):
class Meta:
model = Hinfo
fields = "__all__"


class HistoryFilterSet(filters.FilterSet):
data = JSONFieldExactFilter(field_name="data")

class Meta:
model = History
fields = "__all__"


class HostFilterSet(filters.FilterSet):
class Meta:
model = Host
fields = "__all__"


class HostGroupFilterSet(filters.FilterSet):
class Meta:
model = HostGroup
fields = "__all__"


class IpaddressFilterSet(filters.FilterSet):
class Meta:
model = Ipaddress
fields = "__all__"


class LabelFilterSet(filters.FilterSet):
class Meta:
model = Label
fields = "__all__"


class LocFilterSet(filters.FilterSet):
class Meta:
model = Loc
fields = "__all__"


class MxFilterSet(filters.FilterSet):
class Meta:
model = Mx
fields = "__all__"


class NameServerFilterSet(filters.FilterSet):
class Meta:
model = NameServer
fields = "__all__"


class NaptrFilterSet(filters.FilterSet):
class Meta:
model = Naptr
fields = "__all__"


class NetGroupRegexPermissionFilterSet(filters.FilterSet):
range = CIDRFieldExactFilter(field_name="range")

class Meta:
model = NetGroupRegexPermission
fields = "__all__"


class NetworkFilterSet(filters.FilterSet):
network = CIDRFieldExactFilter(field_name="network")

class Meta:
model = Network
fields = "__all__"


class NetworkExcludedRangeFilterSet(filters.FilterSet):
class Meta:
model = NetworkExcludedRange
fields = "__all__"


class PtrOverrideFilterSet(filters.FilterSet):
class Meta:
model = PtrOverride
fields = "__all__"


class ReverseZoneFilterSet(filters.FilterSet):
network = CIDRFieldExactFilter(field_name="network")

class Meta:
model = ReverseZone
fields = "__all__"


class ReverseZoneDelegationFilterSet(filters.FilterSet):
class Meta:
model = ReverseZoneDelegation
fields = "__all__"


class SrvFilterSet(filters.FilterSet):
class Meta:
model = Srv
fields = "__all__"


class SshfpFilterSet(filters.FilterSet):
class Meta:
model = Sshfp
fields = "__all__"


class TxtFilterSet(filters.FilterSet):
class Meta:
model = Txt
fields = "__all__"
Loading

0 comments on commit ae7fc74

Please sign in to comment.