node.py 9.3 KB
Newer Older
baltery's avatar
baltery 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# ~*~ coding: utf-8 ~*~
# Copyright (C) 2014-2018 Beijing DuiZhan Technology Co.,Ltd. All Rights Reserved.
#
# Licensed under the GNU General Public License v2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.gnu.org/licenses/gpl-2.0.html
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

baltery's avatar
baltery 已提交
16
from rest_framework import generics, mixins, viewsets
17
from rest_framework.serializers import ValidationError
18
from rest_framework.views import APIView
baltery's avatar
baltery 已提交
19 20
from rest_framework.response import Response
from django.utils.translation import ugettext_lazy as _
21
from django.shortcuts import get_object_or_404
baltery's avatar
baltery 已提交
22

baltery's avatar
baltery 已提交
23
from common.utils import get_logger, get_object_or_none
baltery's avatar
baltery 已提交
24
from common.tree import TreeNodeSerializer
baltery's avatar
baltery 已提交
25
from ..hands import IsOrgAdmin
baltery's avatar
baltery 已提交
26
from ..models import Node
baltery's avatar
baltery 已提交
27
from ..tasks import update_assets_hardware_info_util, test_asset_connectivity_util
baltery's avatar
baltery 已提交
28 29 30 31
from .. import serializers


logger = get_logger(__file__)
32
__all__ = [
baltery's avatar
baltery 已提交
33 34
    'NodeViewSet', 'NodeChildrenApi', 'NodeAssetsApi',
    'NodeAddAssetsApi', 'NodeRemoveAssetsApi', 'NodeReplaceAssetsApi',
35
    'NodeAddChildrenApi', 'RefreshNodeHardwareInfoApi',
baltery's avatar
baltery 已提交
36
    'TestNodeConnectiveApi', 'NodeListAsTreeApi',
37
    'NodeChildrenAsTreeApi', 'RefreshAssetsAmount',
38
]
baltery's avatar
baltery 已提交
39 40


baltery's avatar
baltery 已提交
41
class NodeViewSet(viewsets.ModelViewSet):
baltery's avatar
baltery 已提交
42
    queryset = Node.objects.all()
baltery's avatar
baltery 已提交
43
    permission_classes = (IsOrgAdmin,)
44
    serializer_class = serializers.NodeSerializer
baltery's avatar
baltery 已提交
45 46


baltery's avatar
baltery 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
class NodeListAsTreeApi(generics.ListAPIView):
    """
    获取节点列表树
    [
      {
        "id": "",
        "name": "",
        "pId": "",
        "meta": ""
      }
    ]
    """
    permission_classes = (IsOrgAdmin,)
    serializer_class = TreeNodeSerializer

    def get_queryset(self):
        queryset = [node.as_tree_node() for node in Node.objects.all()]
        return queryset

    def filter_queryset(self, queryset):
        if self.request.query_params.get('refresh', '0') == '1':
            queryset = self.refresh_nodes(queryset)
        return queryset

    @staticmethod
    def refresh_nodes(queryset):
        Node.expire_nodes_assets_amount()
        Node.expire_nodes_full_value()
        return queryset


class NodeChildrenAsTreeApi(generics.ListAPIView):
    """
    节点子节点作为树返回,
    [
      {
        "id": "",
        "name": "",
        "pId": "",
        "meta": ""
      }
    ]

    """
    permission_classes = (IsOrgAdmin,)
    serializer_class = TreeNodeSerializer
    node = None
    is_root = False

    def get_queryset(self):
        node_key = self.request.query_params.get('key')
        if node_key:
            self.node = Node.objects.get(key=node_key)
            queryset = self.node.get_children(with_self=False)
        else:
            self.is_root = True
            self.node = Node.root()
            queryset = list(self.node.get_children(with_self=True))
            nodes_invalid = Node.objects.exclude(key__startswith=self.node.key)
            queryset.extend(list(nodes_invalid))
        queryset = [node.as_tree_node() for node in queryset]
        return queryset

    def filter_assets(self, queryset):
        include_assets = self.request.query_params.get('assets', '0') == '1'
        if not include_assets:
            return queryset
        assets = self.node.get_assets()
        for asset in assets:
            queryset.append(asset.as_tree_node(self.node))
        return queryset

    def filter_queryset(self, queryset):
        queryset = self.filter_assets(queryset)
        queryset = self.filter_refresh_nodes(queryset)
        return queryset

    def filter_refresh_nodes(self, queryset):
        if self.request.query_params.get('refresh', '0') == '1':
            Node.expire_nodes_assets_amount()
            Node.expire_nodes_full_value()
        return queryset
129

baltery's avatar
baltery 已提交
130 131

class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
baltery's avatar
baltery 已提交
132
    queryset = Node.objects.all()
baltery's avatar
baltery 已提交
133
    permission_classes = (IsOrgAdmin,)
baltery's avatar
baltery 已提交
134 135 136
    serializer_class = serializers.NodeSerializer
    instance = None

baltery's avatar
baltery 已提交
137 138 139
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

baltery's avatar
baltery 已提交
140
    def post(self, request, *args, **kwargs):
baltery's avatar
baltery 已提交
141
        instance = self.get_object()
baltery's avatar
baltery 已提交
142
        if not request.data.get("value"):
baltery's avatar
baltery 已提交
143
            request.data["value"] = instance.get_next_child_preset_name()
baltery's avatar
baltery 已提交
144 145 146 147 148
        return super().post(request, *args, **kwargs)

    def create(self, request, *args, **kwargs):
        instance = self.get_object()
        value = request.data.get("value")
149 150
        values = [child.value for child in instance.get_children()]
        if value in values:
151 152 153
            raise ValidationError(
                'The same level node name cannot be the same'
            )
baltery's avatar
baltery 已提交
154
        node = instance.create_child(value=value)
baltery's avatar
baltery 已提交
155
        return Response(self.serializer_class(instance=node).data, status=201)
baltery's avatar
baltery 已提交
156

baltery's avatar
baltery 已提交
157 158 159
    def get_object(self):
        pk = self.kwargs.get('pk') or self.request.query_params.get('id')
        if not pk:
baltery's avatar
baltery 已提交
160
            node = Node.root()
baltery's avatar
baltery 已提交
161 162 163 164 165
        else:
            node = get_object_or_404(Node, pk=pk)
        return node

    def get_queryset(self):
baltery's avatar
baltery 已提交
166
        queryset = []
baltery's avatar
baltery 已提交
167 168
        query_all = self.request.query_params.get("all")
        node = self.get_object()
baltery's avatar
baltery 已提交
169

170 171
        if node is None:
            node = Node.root()
baltery's avatar
baltery 已提交
172
            node.assets__count = node.get_all_assets().count()
baltery's avatar
baltery 已提交
173
            queryset.append(node)
baltery's avatar
baltery 已提交
174

baltery's avatar
baltery 已提交
175
        if query_all:
176
            children = node.get_all_children()
baltery's avatar
baltery 已提交
177
        else:
178
            children = node.get_children()
baltery's avatar
baltery 已提交
179
        queryset.extend(list(children))
baltery's avatar
baltery 已提交
180 181 182 183
        return queryset


class NodeAssetsApi(generics.ListAPIView):
baltery's avatar
baltery 已提交
184
    permission_classes = (IsOrgAdmin,)
baltery's avatar
baltery 已提交
185 186 187 188 189 190 191 192
    serializer_class = serializers.AssetSerializer

    def get_queryset(self):
        node_id = self.kwargs.get('pk')
        query_all = self.request.query_params.get('all')
        instance = get_object_or_404(Node, pk=node_id)
        if query_all:
            return instance.get_all_assets()
baltery's avatar
baltery 已提交
193
        else:
baltery's avatar
baltery 已提交
194
            return instance.get_assets()
baltery's avatar
baltery 已提交
195

196

baltery's avatar
baltery 已提交
197
class NodeAddChildrenApi(generics.UpdateAPIView):
baltery's avatar
baltery 已提交
198
    queryset = Node.objects.all()
baltery's avatar
baltery 已提交
199
    permission_classes = (IsOrgAdmin,)
baltery's avatar
baltery 已提交
200 201 202 203 204 205 206 207 208 209
    serializer_class = serializers.NodeAddChildrenSerializer
    instance = None

    def put(self, request, *args, **kwargs):
        instance = self.get_object()
        nodes_id = request.data.get("nodes")
        children = [get_object_or_none(Node, id=pk) for pk in nodes_id]
        for node in children:
            if not node:
                continue
210
            node.parent = instance
baltery's avatar
baltery 已提交
211 212 213
        return Response("OK")


214 215
class NodeAddAssetsApi(generics.UpdateAPIView):
    serializer_class = serializers.NodeAssetsSerializer
baltery's avatar
baltery 已提交
216
    queryset = Node.objects.all()
baltery's avatar
baltery 已提交
217
    permission_classes = (IsOrgAdmin,)
218 219 220 221 222 223 224 225 226 227
    instance = None

    def perform_update(self, serializer):
        assets = serializer.validated_data.get('assets')
        instance = self.get_object()
        instance.assets.add(*tuple(assets))


class NodeRemoveAssetsApi(generics.UpdateAPIView):
    serializer_class = serializers.NodeAssetsSerializer
baltery's avatar
baltery 已提交
228
    queryset = Node.objects.all()
baltery's avatar
baltery 已提交
229
    permission_classes = (IsOrgAdmin,)
230 231 232 233 234
    instance = None

    def perform_update(self, serializer):
        assets = serializer.validated_data.get('assets')
        instance = self.get_object()
baltery's avatar
baltery 已提交
235 236
        if instance != Node.root():
            instance.assets.remove(*tuple(assets))
237 238 239
        else:
            assets = [asset for asset in assets if asset.nodes.count() > 1]
            instance.assets.remove(*tuple(assets))
240 241


baltery's avatar
baltery 已提交
242 243
class NodeReplaceAssetsApi(generics.UpdateAPIView):
    serializer_class = serializers.NodeAssetsSerializer
baltery's avatar
baltery 已提交
244
    queryset = Node.objects.all()
baltery's avatar
baltery 已提交
245
    permission_classes = (IsOrgAdmin,)
baltery's avatar
baltery 已提交
246 247 248 249 250 251 252 253 254
    instance = None

    def perform_update(self, serializer):
        assets = serializer.validated_data.get('assets')
        instance = self.get_object()
        for asset in assets:
            asset.nodes.set([instance])


255
class RefreshNodeHardwareInfoApi(APIView):
baltery's avatar
baltery 已提交
256
    permission_classes = (IsOrgAdmin,)
257 258 259 260 261 262
    model = Node

    def get(self, request, *args, **kwargs):
        node_id = kwargs.get('pk')
        node = get_object_or_404(self.model, id=node_id)
        assets = node.assets.all()
baltery's avatar
baltery 已提交
263 264
        # task_name = _("更新节点资产硬件信息: {}".format(node.name))
        task_name = _("Update node asset hardware information: {}").format(node.name)
265 266
        task = update_assets_hardware_info_util.delay(assets, task_name=task_name)
        return Response({"task": task.id})
267 268 269


class TestNodeConnectiveApi(APIView):
baltery's avatar
baltery 已提交
270
    permission_classes = (IsOrgAdmin,)
271 272 273 274 275 276
    model = Node

    def get(self, request, *args, **kwargs):
        node_id = kwargs.get('pk')
        node = get_object_or_404(self.model, id=node_id)
        assets = node.assets.all()
baltery's avatar
baltery 已提交
277 278
        # task_name = _("测试节点下资产是否可连接: {}".format(node.name))
        task_name = _("Test if the assets under the node are connectable: {}".format(node.name))
baltery's avatar
baltery 已提交
279
        task = test_asset_connectivity_util.delay(assets, task_name=task_name)
280
        return Response({"task": task.id})
281 282 283 284 285 286 287 288 289


class RefreshAssetsAmount(APIView):
    permission_classes = (IsOrgAdmin,)
    model = Node

    def get(self, request, *args, **kwargs):
        self.model.expire_nodes_assets_amount()
        return Response("Ok")