# -*- coding: utf-8 -*- # import random from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from rest_framework.generics import RetrieveAPIView from django.shortcuts import get_object_or_404 from common.utils import get_logger, get_object_or_none from common.permissions import IsOrgAdmin, IsOrgAdminOrAppUser, IsSuperUser from orgs.mixins.api import OrgBulkModelViewSet from orgs.mixins import generics from ..models import Asset, Node, Platform from .. import serializers from ..tasks import ( update_asset_hardware_info_manual, test_asset_connectivity_manual ) from ..filters import AssetByNodeFilterBackend, LabelFilterBackend logger = get_logger(__file__) __all__ = [ 'AssetViewSet', 'AssetPlatformRetrieveApi', 'AssetRefreshHardwareApi', 'AssetAdminUserTestApi', 'AssetGatewayApi', 'AssetPlatformViewSet', ] class AssetViewSet(OrgBulkModelViewSet): """ API endpoint that allows Asset to be viewed or edited. """ model = Asset filter_fields = ("hostname", "ip", "systemuser__id", "admin_user__id") search_fields = ("hostname", "ip") ordering_fields = ("hostname", "ip", "port", "cpu_cores") serializer_class = serializers.AssetSerializer permission_classes = (IsOrgAdminOrAppUser,) extra_filter_backends = [AssetByNodeFilterBackend, LabelFilterBackend] def set_assets_node(self, assets): if not isinstance(assets, list): assets = [assets] node_id = self.request.query_params.get('node_id') if not node_id: return node = get_object_or_none(Node, pk=node_id) if not node: return node.assets.add(*assets) def perform_create(self, serializer): assets = serializer.save() self.set_assets_node(assets) class AssetPlatformRetrieveApi(RetrieveAPIView): queryset = Platform.objects.all() permission_classes = (IsOrgAdminOrAppUser,) serializer_class = serializers.PlatformSerializer def get_object(self): asset_pk = self.kwargs.get('pk') asset = get_object_or_404(Asset, pk=asset_pk) return asset.platform class AssetPlatformViewSet(ModelViewSet): queryset = Platform.objects.all() permission_classes = (IsSuperUser,) serializer_class = serializers.PlatformSerializer filterset_fields = ['name', 'base'] search_fields = ['name'] def check_object_permissions(self, request, obj): if request.method.lower() in ['delete', 'put', 'patch'] and \ obj.internal: self.permission_denied( request, message={"detail": "Internal platform"} ) return super().check_object_permissions(request, obj) class AssetRefreshHardwareApi(generics.RetrieveAPIView): """ Refresh asset hardware info """ model = Asset serializer_class = serializers.AssetSerializer permission_classes = (IsOrgAdmin,) def retrieve(self, request, *args, **kwargs): asset_id = kwargs.get('pk') asset = get_object_or_404(Asset, pk=asset_id) task = update_asset_hardware_info_manual.delay(asset) return Response({"task": task.id}) class AssetAdminUserTestApi(generics.RetrieveAPIView): """ Test asset admin user assets_connectivity """ model = Asset permission_classes = (IsOrgAdmin,) serializer_class = serializers.TaskIDSerializer def retrieve(self, request, *args, **kwargs): asset_id = kwargs.get('pk') asset = get_object_or_404(Asset, pk=asset_id) task = test_asset_connectivity_manual.delay(asset) return Response({"task": task.id}) class AssetGatewayApi(generics.RetrieveAPIView): permission_classes = (IsOrgAdminOrAppUser,) serializer_class = serializers.GatewayWithAuthSerializer model = Asset def retrieve(self, request, *args, **kwargs): asset_id = kwargs.get('pk') asset = get_object_or_404(Asset, pk=asset_id) if asset.domain and \ asset.domain.gateways.filter(protocol='ssh').exists(): gateway = random.choice(asset.domain.gateways.filter(protocol='ssh')) serializer = serializers.GatewayWithAuthSerializer(instance=gateway) return Response(serializer.data) else: return Response({"msg": "Not have gateway"}, status=404)