jumpserver/apps/assets/api/asset/asset.py

167 lines
5.6 KiB
Python
Raw Normal View History

2022-04-06 02:15:06 +00:00
# -*- coding: utf-8 -*-
#
2022-11-11 07:04:31 +00:00
2022-09-20 08:18:23 +00:00
import django_filters
2022-04-06 02:15:06 +00:00
from rest_framework.decorators import action
from rest_framework.response import Response
from assets import serializers
from assets.models import Asset
2022-11-11 07:04:31 +00:00
from assets.filters import IpInFilterBackend, LabelFilterBackend, NodeFilterBackend
2022-04-06 02:15:06 +00:00
from assets.tasks import (
push_accounts_to_assets, test_assets_connectivity_manual,
update_assets_hardware_info_manual, verify_accounts_connectivity,
2022-04-06 02:15:06 +00:00
)
2022-11-11 07:04:31 +00:00
from common.drf.filters import BaseFilterSet
from common.mixins.api import SuggestionMixin
from common.utils import get_logger
from orgs.mixins import generics
from orgs.mixins.api import OrgBulkModelViewSet
2022-08-22 10:32:33 +00:00
from ..mixin import NodeFilterMixin
2022-04-06 02:15:06 +00:00
logger = get_logger(__file__)
__all__ = [
2022-11-11 07:04:31 +00:00
"AssetViewSet",
"AssetTaskCreateApi",
"AssetsTaskCreateApi",
2022-04-06 02:15:06 +00:00
]
2022-08-22 10:32:33 +00:00
class AssetFilterSet(BaseFilterSet):
2022-11-11 07:04:31 +00:00
type = django_filters.CharFilter(field_name="platform__type", lookup_expr="exact")
category = django_filters.CharFilter(
field_name="platform__category", lookup_expr="exact"
)
hostname = django_filters.CharFilter(field_name="name", lookup_expr="exact")
2022-08-22 10:32:33 +00:00
class Meta:
model = Asset
2022-11-11 07:04:31 +00:00
fields = ["name", "address", "is_active", "type", "category", "hostname"]
2022-08-22 10:32:33 +00:00
class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
2022-04-06 02:15:06 +00:00
"""
API endpoint that allows Asset to be viewed or edited.
"""
2022-11-11 07:04:31 +00:00
2022-04-06 02:15:06 +00:00
model = Asset
2022-08-22 10:32:33 +00:00
filterset_class = AssetFilterSet
2022-09-21 03:17:14 +00:00
search_fields = ("name", "address")
ordering_fields = ("name", "address")
2022-11-11 07:04:31 +00:00
ordering = ("name",)
2022-05-04 01:57:45 +00:00
serializer_classes = (
2022-11-11 07:04:31 +00:00
("default", serializers.AssetSerializer),
("suggestion", serializers.MiniAssetSerializer),
("platform", serializers.PlatformSerializer),
("gateways", serializers.GatewayWithAuthSerializer),
2022-05-04 01:57:45 +00:00
)
rbac_perms = (
2022-11-11 07:04:31 +00:00
("match", "assets.match_asset"),
("platform", "assets.view_platform"),
("gateways", "assets.view_gateway"),
2022-05-04 01:57:45 +00:00
)
2022-11-11 07:04:31 +00:00
extra_filter_backends = [LabelFilterBackend, IpInFilterBackend, NodeFilterBackend]
2022-04-06 02:15:06 +00:00
2022-11-11 07:04:31 +00:00
@action(methods=["GET"], detail=True, url_path="platform")
2022-04-06 02:15:06 +00:00
def platform(self, *args, **kwargs):
asset = self.get_object()
serializer = self.get_serializer(asset.platform)
return Response(serializer.data)
2022-11-11 07:04:31 +00:00
@action(methods=["GET"], detail=True, url_path="gateways")
2022-04-06 02:15:06 +00:00
def gateways(self, *args, **kwargs):
asset = self.get_object()
if not asset.domain:
gateways = Asset.objects.none()
2022-04-06 02:15:06 +00:00
else:
2022-11-11 07:04:31 +00:00
gateways = asset.domain.gateways.filter(protocol="ssh")
2022-04-06 02:15:06 +00:00
return self.get_paginated_response_from_queryset(gateways)
class AssetsTaskMixin:
def perform_assets_task(self, serializer):
data = serializer.validated_data
2022-11-11 07:04:31 +00:00
assets = data.get("assets", [])
asset_ids = [asset.id for asset in assets]
2022-11-11 07:04:31 +00:00
if data["action"] == "refresh":
task = update_assets_hardware_info_manual.delay(asset_ids)
2022-04-06 02:15:06 +00:00
else:
task = test_assets_connectivity_manual.delay(asset_ids)
2022-04-06 02:15:06 +00:00
return task
def perform_create(self, serializer):
task = self.perform_assets_task(serializer)
self.set_task_to_serializer_data(serializer, task)
def set_task_to_serializer_data(self, serializer, task):
2022-11-11 07:04:31 +00:00
data = getattr(serializer, "_data", {})
2022-04-06 02:15:06 +00:00
data["task"] = task.id
2022-11-11 07:04:31 +00:00
setattr(serializer, "_data", data)
2022-04-06 02:15:06 +00:00
class AssetTaskCreateApi(AssetsTaskMixin, generics.CreateAPIView):
model = Asset
serializer_class = serializers.AssetTaskSerializer
def create(self, request, *args, **kwargs):
2022-11-11 07:04:31 +00:00
pk = self.kwargs.get("pk")
request.data["asset"] = pk
request.data["assets"] = [pk]
2022-04-06 02:15:06 +00:00
return super().create(request, *args, **kwargs)
def check_permissions(self, request):
2022-11-11 07:04:31 +00:00
action = request.data.get("action")
2022-04-06 02:15:06 +00:00
action_perm_require = {
2022-11-11 07:04:31 +00:00
"refresh": "assets.refresh_assethardwareinfo",
"push_account": "assets.push_assetsystemuser",
"test": "assets.test_assetconnectivity",
"test_account": "assets.test_assetconnectivity",
2022-04-06 02:15:06 +00:00
}
perm_required = action_perm_require.get(action)
has = self.request.user.has_perm(perm_required)
if not has:
self.permission_denied(request)
@staticmethod
def perform_asset_task(serializer):
2022-04-06 02:15:06 +00:00
data = serializer.validated_data
2022-11-11 07:04:31 +00:00
if data["action"] not in ["push_system_user", "test_system_user"]:
2022-04-06 02:15:06 +00:00
return
2022-11-11 07:04:31 +00:00
asset = data["asset"]
accounts = data.get("accounts")
if not accounts:
accounts = asset.accounts.all()
asset_ids = [asset.id]
2022-11-11 07:04:31 +00:00
account_ids = accounts.values_list("id", flat=True)
if action == "push_account":
task = push_accounts_to_assets.delay(account_ids, asset_ids)
2022-11-11 07:04:31 +00:00
elif action == "test_account":
task = verify_accounts_connectivity.delay(account_ids, asset_ids)
2022-04-06 02:15:06 +00:00
else:
task = None
return task
def perform_create(self, serializer):
task = self.perform_asset_task(serializer)
if not task:
task = self.perform_assets_task(serializer)
self.set_task_to_serializer_data(serializer, task)
class AssetsTaskCreateApi(AssetsTaskMixin, generics.CreateAPIView):
model = Asset
serializer_class = serializers.AssetsTaskSerializer
def check_permissions(self, request):
2022-11-11 07:04:31 +00:00
action = request.data.get("action")
2022-04-06 02:15:06 +00:00
action_perm_require = {
2022-11-11 07:04:31 +00:00
"refresh": "assets.refresh_assethardwareinfo",
2022-04-06 02:15:06 +00:00
}
perm_required = action_perm_require.get(action)
has = self.request.user.has_perm(perm_required)
if not has:
self.permission_denied(request)