Skip to content

Commit

Permalink
[feature] REST API for main controller features #379
Browse files Browse the repository at this point in the history
Closes #379
  • Loading branch information
ManishShah120 committed Feb 28, 2021
1 parent a627b61 commit fab61ba
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 2 deletions.
Empty file.
80 changes: 80 additions & 0 deletions openwisp_controller/api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from rest_framework import serializers
from swapper import load_model

from openwisp_users.api.mixins import FilterSerializerByOrgOwned
from openwisp_utils.api.serializers import ValidatedModelSerializer

Template = load_model('config', 'Template')
Vpn = load_model('config', 'Vpn')
Device = load_model('config', 'Device')
Config = load_model('config', 'Config')


class BaseMeta:
read_only_fields = ['created', 'modified']


class TemplateSerializer(FilterSerializerByOrgOwned, ValidatedModelSerializer):
config = serializers.JSONField()
default_values = serializers.JSONField()

class Meta(BaseMeta):
model = Template
fields = '__all__'


class TemplateForConfigSerializer(serializers.RelatedField):
def get_queryset(self):
return Template.objects.all()

def to_representation(self, instance):
return {'id': instance.id, 'name': instance.name}


class ConfigSerializer(ValidatedModelSerializer):
templates = TemplateForConfigSerializer(many=True, read_only=True)
context = serializers.JSONField()
config = serializers.JSONField()

class Meta(BaseMeta):
model = Config
# depth = 1
exclude = ('device',)


class VpnSerializer(FilterSerializerByOrgOwned, ValidatedModelSerializer):
config = serializers.JSONField()

class Meta(BaseMeta):
model = Vpn
fields = '__all__'


class DeviceListSerializer(ValidatedModelSerializer):
class Meta(BaseMeta):
model = Device
fields = [
'id',
'name',
'organization',
'mac_address',
'key',
'last_ip',
'management_ip',
'model',
'os',
'system',
'notes',
]


class DeviceDetailSerializer(ValidatedModelSerializer):
configuration = ConfigSerializer(read_only=False, source='config')

class Meta(BaseMeta):
model = Device
fields = DeviceListSerializer.Meta.fields + [
'created',
'modified',
'configuration',
]
40 changes: 40 additions & 0 deletions openwisp_controller/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from django.urls import include, path

from . import views as api_views

urlpatterns = [
path(
'controller/',
include(
[
path('template/', api_views.template_list, name='template_list',),
path(
'template/<str:pk>/',
api_views.template_detail,
name='template_detail',
),
path(
'template/<str:pk>/configuration/',
api_views.download_template_config,
name='download_template_config',
),
path('vpn/', api_views.vpn_list, name='vpn_list',),
path('vpn/<str:pk>/', api_views.vpn_detail, name='vpn_detail',),
path(
'vpn/<str:pk>/configuration/',
api_views.download_vpn_config,
name='download_vpn_config',
),
path('device/', api_views.device_list, name='device_list',),
path(
'device/<str:pk>/', api_views.device_detail, name='device_detail',
),
path(
'device/<str:pk>/configuration/',
api_views.download_device_config,
name='download_device_config',
),
]
),
),
]
111 changes: 111 additions & 0 deletions openwisp_controller/api/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
from rest_framework import pagination
from rest_framework.authentication import SessionAuthentication
from rest_framework.generics import (
ListCreateAPIView,
RetrieveAPIView,
RetrieveUpdateDestroyAPIView,
)
from rest_framework.permissions import DjangoModelPermissions, IsAuthenticated
from swapper import load_model

from openwisp_users.api.authentication import BearerAuthentication
from openwisp_users.api.mixins import FilterByOrganizationManaged
from openwisp_users.api.permissions import IsOrganizationManager

from ..config.admin import BaseConfigAdmin
from .serializers import (
DeviceDetailSerializer,
DeviceListSerializer,
TemplateSerializer,
VpnSerializer,
)

Template = load_model('config', 'Template')
Vpn = load_model('config', 'Vpn')
Device = load_model('config', 'Device')


class ListViewPagination(pagination.PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100


class ProtectedAPIMixin(FilterByOrganizationManaged):
authentication_classes = [BearerAuthentication, SessionAuthentication]
permission_classes = [
IsAuthenticated,
IsOrganizationManager,
DjangoModelPermissions,
]


class TemplateListCreateView(ProtectedAPIMixin, ListCreateAPIView):
serializer_class = TemplateSerializer
queryset = Template.objects.all()
pagination_class = ListViewPagination


class TemplateDetailView(ProtectedAPIMixin, RetrieveUpdateDestroyAPIView):
serializer_class = TemplateSerializer
queryset = Template.objects.all()


class DownloadTemplateconfiguration(ProtectedAPIMixin, RetrieveAPIView):
serializer_class = TemplateSerializer
queryset = Template.objects.none()
model = Template

def retrieve(self, request, *args, **kwargs):
return BaseConfigAdmin.download_view(self, request, pk=kwargs['pk'])


class VpnListCreateView(ProtectedAPIMixin, ListCreateAPIView):
serializer_class = VpnSerializer
queryset = Vpn.objects.all()
pagination_class = ListViewPagination


class VpnDetailView(ProtectedAPIMixin, RetrieveUpdateDestroyAPIView):
serializer_class = VpnSerializer
queryset = Vpn.objects.all()


class DownloadVpnView(ProtectedAPIMixin, RetrieveAPIView):
serializer_class = VpnSerializer
queryset = Vpn.objects.none()
model = Vpn

def retrieve(self, request, *args, **kwargs):
return BaseConfigAdmin.download_view(self, request, pk=kwargs['pk'])


class DeviceListCreateView(ProtectedAPIMixin, ListCreateAPIView):
serializer_class = DeviceListSerializer
queryset = Device.objects.all()
pagination_class = ListViewPagination


class DeviceDetailView(ProtectedAPIMixin, RetrieveUpdateDestroyAPIView):
serializer_class = DeviceDetailSerializer
queryset = Device.objects.all()


class DownloadDeviceView(ProtectedAPIMixin, RetrieveAPIView):
serializer_class = DeviceListSerializer
queryset = Device.objects.none()
model = Device

def retrieve(self, request, *args, **kwargs):
return BaseConfigAdmin.download_view(self, request, pk=kwargs['pk'])


template_list = TemplateListCreateView.as_view()
template_detail = TemplateDetailView.as_view()
download_template_config = DownloadTemplateconfiguration.as_view()
vpn_list = VpnListCreateView.as_view()
vpn_detail = VpnDetailView.as_view()
download_vpn_config = DownloadVpnView.as_view()
device_list = DeviceListCreateView.as_view()
device_detail = DeviceDetailView.as_view()
download_device_config = DownloadDeviceView().as_view()
Empty file.
3 changes: 3 additions & 0 deletions tests/openwisp2/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@
'flat_json_widget',
# rest framework
'rest_framework',
'rest_framework.authtoken',
'rest_framework_gis',
'django_filters',
'drf_yasg',
# channels
'channels',
# 'debug_toolbar',
Expand Down
6 changes: 4 additions & 2 deletions tests/openwisp2/urls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import os

from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls import url
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.urls import reverse_lazy
from django.urls import include, path, reverse_lazy
from django.views.generic import RedirectView

from openwisp_controller.config.utils import get_controller_urls
Expand Down Expand Up @@ -38,6 +38,8 @@
url(r'^$', redirect_view, name='index'),
url(r'^admin/', admin.site.urls),
url(r'', include('openwisp_controller.urls')),
path('api/v1/', include('openwisp_utils.api.urls')),
path('api/v1/', include('openwisp_controller.api.urls')),
]

urlpatterns += staticfiles_urlpatterns()
Expand Down

0 comments on commit fab61ba

Please sign in to comment.