未验证 提交 de43980e 编写于 作者: baltery's avatar baltery 提交者: GitHub

Dev beta2 (#3177)

* [Update] 添加loading

* [Update] stash

* [Update] 修改permission
上级 d5dcab15
......@@ -34,7 +34,6 @@ var actions = {
}};
$(document).ready(function () {
initTree();
initTable();
}).on('click', '.labels li', function () {
var val = $(this).text();
$("#user_assets_table_filter input").val(val);
......
......@@ -51,15 +51,15 @@ urlpatterns = [
path('system-users/<uuid:pk>/auth-info/',
api.SystemUserAuthInfoApi.as_view(), name='system-user-auth-info'),
path('system-users/<uuid:pk>/asset/<uuid:aid>/auth-info/',
path('system-users/<uuid:pk>/assets/<uuid:aid>/auth-info/',
api.SystemUserAssetAuthInfoApi.as_view(), name='system-user-asset-auth-info'),
path('system-users/<uuid:pk>/assets/',
api.SystemUserAssetsListView.as_view(), name='system-user-assets'),
path('system-users/<uuid:pk>/push/',
api.SystemUserPushApi.as_view(), name='system-user-push'),
path('system-users/<uuid:pk>/asset/<uuid:aid>/push/',
path('system-users/<uuid:pk>/assets/<uuid:aid>/push/',
api.SystemUserPushToAssetApi.as_view(), name='system-user-push-to-asset'),
path('system-users/<uuid:pk>/asset/<uuid:aid>/test/',
path('system-users/<uuid:pk>/assets/<uuid:aid>/test/',
api.SystemUserTestAssetConnectivityApi.as_view(), name='system-user-test-to-asset'),
path('system-users/<uuid:pk>/connective/',
api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'),
......
......@@ -66,27 +66,23 @@ class TreeService(Tree):
super().__init__(*args, **kwargs)
self.nodes_assets_map = defaultdict(set)
self.all_nodes_assets_map = {}
self.mutex = threading.Lock()
@classmethod
@timeit
def new(cls):
from .models import Node
from orgs.utils import get_current_org, set_to_root_org
origin_org = get_current_org()
set_to_root_org()
all_nodes = Node.objects.all()
origin_org.change_to()
tree = cls()
tree.create_node(tag='', identifier='')
for node in all_nodes:
tree.create_node(
tag=node.value, identifier=node.key,
parent=node.parent_key,
)
tree.init_assets_async()
from orgs.utils import tmp_to_root_org
with tmp_to_root_org():
all_nodes = Node.objects.all()
tree = cls()
tree.create_node(tag='', identifier='')
for node in all_nodes:
tree.create_node(
tag=node.value, identifier=node.key,
parent=node.parent_key,
)
tree.init_assets()
return tree
def init_assets_async(self):
......@@ -95,17 +91,16 @@ class TreeService(Tree):
def init_assets(self):
from orgs.utils import get_current_org, set_to_root_org
with self.mutex:
origin_org = get_current_org()
set_to_root_org()
queryset = Asset.objects.all().valid().values_list('id', 'nodes__key')
if origin_org:
origin_org.change_to()
for asset_id, key in queryset:
if not key:
continue
self.nodes_assets_map[key].add(asset_id)
origin_org = get_current_org()
set_to_root_org()
queryset = Asset.objects.all().valid().values_list('id', 'nodes__key')
if origin_org:
origin_org.change_to()
for asset_id, key in queryset:
if not key:
continue
self.nodes_assets_map[key].add(asset_id)
def all_children(self, nid, with_self=True, deep=False):
children_ids = self.expand_tree(nid)
......@@ -146,13 +141,11 @@ class TreeService(Tree):
return parent
def assets(self, nid):
with self.mutex:
assets = self.nodes_assets_map[nid]
return assets
assets = self.nodes_assets_map[nid]
return assets
def set_assets(self, nid, assets):
with self.mutex:
self.nodes_assets_map[nid] = assets
self.nodes_assets_map[nid] = assets
def all_assets(self, nid):
assets = self.all_nodes_assets_map.get(nid)
......@@ -186,12 +179,17 @@ class TreeService(Tree):
self.safe_add_ancestors(ancestors)
parent = self.get_node(parent_id)
print("Add node: {} {}".format(node.identifier, parent.identifier))
# 如果当前节点已再树中,则移动当前节点到父节点中
# 这个是由于 当前节点放到了二级节点中
if self.contains(node.identifier):
self.move_node(node.identifier, parent.identifier)
else:
self.add_node(node, parent)
#
# def __getstate__(self):
# self.mutex = None
# return self.__dict__
#
# def __setstate__(self, state):
# self.__dict__ = state
# self.mutex = threading.Lock()
# ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals
from django.conf.urls import url
from django.urls.conf import re_path
from rest_framework.routers import DefaultRouter
from common import api as capi
from .. import api
app_name = "audits"
router = DefaultRouter()
router.register(r'ftp-log', api.FTPLogViewSet, 'ftp-log')
router.register(r'ftp-logs', api.FTPLogViewSet, 'ftp-log')
urlpatterns = [
]
old_version_urlpatterns = [
re_path('(?P<resource>ftp-log)/.*', capi.redirect_plural_name_api)
]
urlpatterns += router.urls
......@@ -12,11 +12,14 @@ from rest_framework import generics, serializers
from .http import HttpResponseTemporaryRedirect
from .const import KEY_CACHE_RESOURCES_ID
from .utils import get_logger
__all__ = [
'LogTailApi', 'ResourcesIDCacheApi',
]
logger = get_logger(__file__)
class OutputSerializer(serializers.Serializer):
output = serializers.CharField()
......@@ -93,6 +96,7 @@ class ResourcesIDCacheApi(APIView):
@csrf_exempt
def redirect_plural_name_api(request, *args, **kwargs):
resource = kwargs.get("resource", "")
full_path = request.get_full_path()
full_path = full_path.replace(resource, resource+"s", 1)
org_full_path = request.get_full_path()
full_path = org_full_path.replace(resource, resource+"s", 1)
logger.debug("Redirect {} => {}".format(org_full_path, full_path))
return HttpResponseTemporaryRedirect(full_path)
......@@ -10,9 +10,10 @@ from . import user_permission as uapi
__all__ = [
'UserGroupGrantedAssetsApi', 'UserGroupGrantedNodesApi',
'UserGroupGrantedNodeAssetsApi', 'UserGroupGrantedNodeChildrenApi',
'UserGroupGrantedNodeChildrenAsTreeApi', 'UserGroupGrantedNodesWithAssetsAsTreeApi',
'UserGroupGrantedNodeChildrenAsTreeApi',
'UserGroupGrantedNodeChildrenWithAssetsAsTreeApi',
'UserGroupGrantedAssetSystemUsersApi',
# 'UserGroupGrantedNodesWithAssetsAsTreeApi',
# 'UserGroupGrantedNodeChildrenWithAssetsAsTreeApi',
]
......@@ -45,7 +46,7 @@ class UserGroupGrantedNodeChildrenAsTreeApi(UserGroupPermissionMixin, uapi.UserG
pass
class UserGroupGrantedNodesWithAssetsAsTreeApi(UserGroupPermissionMixin, uapi.UserGrantedNodesWithAssetsAsTreeApi):
class UserGroupGrantedNodeChildrenWithAssetsAsTreeApi(UserGroupPermissionMixin, uapi.UserGrantedNodeChildrenWithAssetsAsTreeApi):
pass
......
......@@ -23,12 +23,19 @@ from ..models import Action
logger = get_logger(__name__)
__all__ = [
'UserGrantedAssetsApi', 'UserGrantedNodesApi',
'UserGrantedAssetsApi',
'UserGrantedAssetsAsTreeApi',
'UserGrantedNodeAssetsApi',
'UserGrantedNodesApi',
'UserGrantedNodesAsTreeApi',
'UserGrantedNodesWithAssetsAsTreeApi',
'UserGrantedNodeChildrenApi',
'UserGrantedNodeChildrenAsTreeApi',
'UserGrantedNodeChildrenWithAssetsAsTreeApi',
'RefreshAssetPermissionCacheApi',
'UserGrantedAssetSystemUsersApi',
'ValidateUserAssetPermissionApi',
'UserGrantedNodesWithAssetsAsTreeApi', 'GetUserAssetPermissionActionsApi',
'RefreshAssetPermissionCacheApi', 'UserGrantedAssetSystemUsersApi',
'UserGrantedNodeChildrenAsTreeApi', 'UserGrantedNodesWithAssetsAsTreeApi',
'GetUserAssetPermissionActionsApi',
]
......@@ -58,6 +65,66 @@ class UserPermissionMixin:
return super().get_permissions()
class UserNodePermissionMixin(UserPermissionMixin):
util = None
def initial(self, *args, **kwargs):
super().initial(*args, *kwargs)
self.util = AssetPermissionUtilV2(self.obj)
class UserNodeTreeMixin:
serializer_class = TreeNodeSerializer
nodes_only_fields = ParserNode.nodes_only_fields
tree = None
def parse_nodes_to_queryset(self, nodes):
nodes = nodes.only(*self.nodes_only_fields)
_queryset = []
tree = self.util.get_user_tree()
for node in nodes:
assets_amount = tree.assets_amount(node.key)
if assets_amount == 0:
continue
node._assets_amount = assets_amount
data = ParserNode.parse_node_to_tree_node(node)
_queryset.append(data)
return _queryset
def get_serializer_queryset(self, queryset):
queryset = self.parse_nodes_to_queryset(queryset)
return queryset
def get_serializer(self, queryset, many=True, **kwargs):
queryset = self.get_serializer_queryset(queryset)
queryset.sort()
return super().get_serializer(queryset, many=many, **kwargs)
class UserAssetTreeMixin:
serializer_class = TreeNodeSerializer
nodes_only_fields = ParserNode.assets_only_fields
@staticmethod
def parse_assets_to_queryset(assets, node):
_queryset = []
for asset in assets:
data = ParserNode.parse_asset_to_tree_node(node, asset)
_queryset.append(data)
return _queryset
def get_serializer_queryset(self, queryset):
queryset = queryset.only(*self.nodes_only_fields)
_queryset = self.parse_assets_to_queryset(queryset, None)
return _queryset
def get_serializer(self, queryset, many=True, **kwargs):
queryset = self.get_serializer_queryset(queryset)
queryset.sort()
return super().get_serializer(queryset, many=many, **kwargs)
class UserGrantedAssetsApi(UserPermissionMixin, ListAPIView):
permission_classes = (IsOrgAdminOrAppUser,)
serializer_class = serializers.AssetGrantedSerializer
......@@ -89,6 +156,10 @@ class UserGrantedAssetsApi(UserPermissionMixin, ListAPIView):
return queryset
class UserGrantedAssetsAsTreeApi(UserAssetTreeMixin, UserGrantedAssetsApi):
pass
class UserGrantedNodeAssetsApi(UserGrantedAssetsApi):
def get_queryset(self):
node_id = self.kwargs.get("node_id")
......@@ -100,18 +171,13 @@ class UserGrantedNodeAssetsApi(UserGrantedAssetsApi):
return queryset
class UserGrantedNodesApi(UserPermissionMixin, ListAPIView):
class UserGrantedNodesApi(UserNodePermissionMixin, ListAPIView):
"""
查询用户授权的所有节点的API
"""
permission_classes = (IsOrgAdminOrAppUser,)
serializer_class = serializers.NodeGrantedSerializer
only_fields = NodeSerializer.Meta.only_fields
util = None
def get(self, request, *args, **kwargs):
self.util = AssetPermissionUtilV2(self.obj)
return super().get(request, *args, **kwargs)
nodes_only_fields = NodeSerializer.Meta.only_fields
def get_serializer_context(self):
context = super().get_serializer_context()
......@@ -120,21 +186,35 @@ class UserGrantedNodesApi(UserPermissionMixin, ListAPIView):
def get_queryset(self):
node_keys = self.util.get_nodes()
queryset = Node.objects.filter(key__in=node_keys)
queryset = Node.objects.filter(key__in=node_keys)\
.only(*self.nodes_only_fields)
return queryset
class UserGrantedNodesAsTreeApi(UserNodeTreeMixin, UserGrantedNodesApi):
pass
class UserGrantedNodesWithAssetsAsTreeApi(UserGrantedNodesAsTreeApi):
def get_serializer_queryset(self, queryset):
_queryset = super().get_serializer_queryset(queryset)
for node in queryset:
assets = self.util.get_nodes_assets(node)
_queryset.extend(
UserAssetTreeMixin.parse_assets_to_queryset(assets, node)
)
return _queryset
class UserGrantedNodeChildrenApi(UserGrantedNodesApi):
node = None
util = None
tree = None
root_keys = None
root_keys = None # 如果是第一次访问,则需要把二级节点添加进去,这个 roots_keys
def get(self, request, *args, **kwargs):
key = self.request.query_params.get("key")
pk = self.request.query_params.get("id")
system_user_id = self.request.query_params.get("system_user")
self.util = AssetPermissionUtilV2(self.obj)
if system_user_id:
self.util.filter_permissions(system_users=system_user_id)
self.tree = self.util.get_user_tree()
......@@ -161,26 +241,16 @@ class UserGrantedNodeChildrenApi(UserGrantedNodesApi):
return queryset
class UserGrantedNodeChildrenAsTreeApi(UserGrantedNodeChildrenApi):
serializer_class = TreeNodeSerializer
only_fields = ParserNode.nodes_only_fields
def get_queryset(self):
nodes = super().get_queryset()
queryset = []
for node in nodes:
node._assets_amount = self.tree.assets_amount(node.key)
data = ParserNode.parse_node_to_tree_node(node)
queryset.append(data)
return queryset
class UserGrantedNodeChildrenAsTreeApi(UserNodeTreeMixin, UserGrantedNodeChildrenApi):
pass
class UserGrantedNodesWithAssetsAsTreeApi(UserGrantedNodeChildrenAsTreeApi):
class UserGrantedNodeChildrenWithAssetsAsTreeApi(UserGrantedNodeChildrenAsTreeApi):
nodes_only_fields = ParserNode.nodes_only_fields
assets_only_fields = ParserNode.assets_only_fields
def get_queryset(self):
queryset = super().get_queryset()
def get_serializer_queryset(self, queryset):
_queryset = super().get_serializer_queryset(queryset)
nodes = []
if self.node:
nodes.append(self.node)
......@@ -188,12 +258,13 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserGrantedNodeChildrenAsTreeApi):
nodes = Node.objects.filter(key__in=self.root_keys)
for node in nodes:
assets = self.util.get_nodes_assets(node).only(*self.assets_only_fields)
for asset in assets:
data = ParserNode.parse_asset_to_tree_node(node, asset)
queryset.append(data)
queryset = sorted(queryset)
return queryset
assets = self.util.get_nodes_assets(node).only(
*self.assets_only_fields
)
_queryset.extend(
UserAssetTreeMixin.parse_assets_to_queryset(assets, node)
)
return _queryset
class GetUserAssetPermissionActionsApi(RetrieveAPIView):
......
......@@ -17,16 +17,34 @@ asset_permission_urlpatterns = [
path('users/<uuid:pk>/assets/', api.UserGrantedAssetsApi.as_view(), name='user-assets'),
path('users/assets/', api.UserGrantedAssetsApi.as_view(), name='my-assets'),
# Assets as tree
path('users/<uuid:pk>/assets/tree/', api.UserGrantedAssetsAsTreeApi.as_view(), name='user-assets-as-tree'),
path('users/assets/tree/', api.UserGrantedAssetsAsTreeApi.as_view(), name='my-assets-as-tree'),
# Nodes
path('users/<uuid:pk>/nodes/', api.UserGrantedNodesApi.as_view(), name='user-nodes'),
path('users/nodes/', api.UserGrantedNodesApi.as_view(), name='my-nodes'),
# Node children
path('users/<uuid:pk>/nodes/children/', api.UserGrantedNodesApi.as_view(), name='user-nodes-children'),
path('users/nodes/children/', api.UserGrantedNodesApi.as_view(), name='my-nodes-children'),
# Node as tree
path('users/<uuid:pk>/nodes/tree/', api.UserGrantedNodesAsTreeApi.as_view(), name='user-nodes-as-tree'),
path('users/nodes/tree/', api.UserGrantedNodesAsTreeApi.as_view(), name='my-nodes-as-tree'),
# Node with assets as tree
path('users/<uuid:pk>/nodes-with-assets/tree/', api.UserGrantedNodesWithAssetsAsTreeApi.as_view(), name='user-nodes-with-assets-as-tree'),
path('users/nodes-with-assets/tree/', api.UserGrantedNodesWithAssetsAsTreeApi.as_view(), name='my-nodes-with-assets-as-tree'),
# Node children as tree
path('users/<uuid:pk>/nodes/children/tree/', api.UserGrantedNodeChildrenAsTreeApi.as_view(), name='user-nodes-children-as-tree'),
path('users/nodes/children/tree/', api.UserGrantedNodeChildrenAsTreeApi.as_view(), name='my-nodes-children-as-tree'),
# Node children with assets as tree
path('users/<uuid:pk>/nodes/children-with-assets/tree/', api.UserGrantedNodeChildrenWithAssetsAsTreeApi.as_view(), name='user-nodes-children-with-assets-as-tree'),
path('users/nodes/children-with-assets/tree/', api.UserGrantedNodeChildrenWithAssetsAsTreeApi.as_view(), name='my-nodes-children-with-assets-as-tree'),
# Node assets
path('users/<uuid:pk>/nodes/<uuid:node_id>/assets/', api.UserGrantedNodeAssetsApi.as_view(), name='user-node-assets'),
path('users/nodes/<uuid:node_id>/assets/', api.UserGrantedNodeAssetsApi.as_view(), name='my-node-assets'),
......@@ -35,10 +53,6 @@ asset_permission_urlpatterns = [
path('users/<uuid:pk>/assets/<uuid:asset_id>/system-users/', api.UserGrantedAssetSystemUsersApi.as_view(), name='user-asset-system-users'),
path('users/assets/<uuid:asset_id>/system-users/', api.UserGrantedAssetSystemUsersApi.as_view(), name='my-asset-system-users'),
# Node assets as tree
path('users/<uuid:pk>/nodes/children-with-assets/tree/', api.UserGrantedNodesWithAssetsAsTreeApi.as_view(), name='user-nodes-children-with-assets-as-tree'),
path('users/nodes/children-with-assets/tree/', api.UserGrantedNodesWithAssetsAsTreeApi.as_view(), name='my-nodes-children-with-assets-as-tree'),
# 查询某个用户组授权的资产和资产组
path('user-groups/<uuid:pk>/assets/', api.UserGroupGrantedAssetsApi.as_view(), name='user-group-assets'),
path('user-groups/<uuid:pk>/nodes/', api.UserGroupGrantedNodesApi.as_view(), name='user-group-nodes'),
......
# coding: utf-8
import pickle
import threading
from collections import defaultdict
from functools import reduce
from django.core.cache import cache
from django.db.models import Q
from django.conf import settings
......@@ -12,7 +15,6 @@ from common.tree import TreeNode
from assets.utils import TreeService
from ..models import AssetPermission
from ..hands import Node, Asset, SystemUser
from .. import const
logger = get_logger(__file__)
......@@ -69,9 +71,12 @@ class AssetPermissionUtilV2:
'id', 'hostname', 'ip', "platform", "domain_id",
'comment', 'is_active', 'os', 'org_id'
)
user_tree_cache_key = 'USER_PERM_TREE_{}'
user_tree_cache_ttl = 3600
def __init__(self, obj, cache_policy='0'):
self.object = obj
self.cache_policy = cache_policy
self.obj_id = str(obj.id)
self._permissions = None
self._permissions_id = None # 标记_permission的唯一值
......@@ -84,6 +89,7 @@ class AssetPermissionUtilV2:
self._nodes_direct = None
self._user_tree = None
self.full_tree = Node.tree()
self.mutex = threading.Lock()
@staticmethod
def change_org_if_need():
......@@ -103,6 +109,31 @@ class AssetPermissionUtilV2:
def filter_permissions(self, **filters):
self._permissions = self.permissions.filter(**filters)
@classmethod
def get_user_tree_from_cache(cls, obj_id):
return None
key = cls.user_tree_cache_key.format(obj_id)
data = cache.get(key)
if not data:
return None
user_tree = pickle.loads(data)
return user_tree
@classmethod
def expire_user_tree_cache(cls, obj_id):
if obj_id == 'all':
key = cls.user_tree_cache_key.format('*')
cache.delete_pattern(key)
else:
key = cls.user_tree_cache_key.format(obj_id)
cache.delete(key)
@classmethod
def set_user_tree_to_cache(cls, obj_id, user_tree):
data = pickle.dumps(user_tree)
key = cls.user_tree_cache_key.format(obj_id)
cache.set(key, data, cls.user_tree_cache_ttl)
@property
def user_tree(self):
return self.get_user_tree()
......@@ -237,20 +268,26 @@ class AssetPermissionUtilV2:
@timeit
def get_user_tree(self):
if self._user_tree:
return self._user_tree
user_tree = TreeService()
full_tree_root = self.full_tree.root_node()
user_tree.create_node(
tag=full_tree_root.tag,
identifier=full_tree_root.identifier
)
self.add_direct_nodes_to_user_tree(user_tree)
self.add_single_assets_node_to_user_tree(user_tree)
self.parse_user_tree_to_full_tree(user_tree)
self.add_empty_node_if_need(user_tree)
self._user_tree = user_tree
return user_tree
with self.mutex:
if self._user_tree:
return self._user_tree
print(id(self), self._user_tree)
user_tree = self.__class__.get_user_tree_from_cache(self.obj_id)
if user_tree:
self._user_tree = user_tree
return user_tree
user_tree = TreeService()
full_tree_root = self.full_tree.root_node()
user_tree.create_node(
tag=full_tree_root.tag,
identifier=full_tree_root.identifier
)
self.add_direct_nodes_to_user_tree(user_tree)
self.add_single_assets_node_to_user_tree(user_tree)
self.parse_user_tree_to_full_tree(user_tree)
self.add_empty_node_if_need(user_tree)
self.__class__.set_user_tree_to_cache(self.obj_id, user_tree)
return user_tree
# Todo: 是否可以获取多个资产的系统用户
def get_asset_system_users_with_actions(self, asset):
......@@ -401,15 +438,17 @@ class ParserNode:
@staticmethod
def parse_asset_to_tree_node(node, asset):
icon_skin = 'file'
if asset.platform.lower() == 'windows':
platform = asset.platform.lower()
if platform == 'windows':
icon_skin = 'windows'
elif asset.platform.lower() == 'linux':
elif platform == 'linux':
icon_skin = 'linux'
parent_id = node.key if node else ''
data = {
'id': str(asset.id),
'name': asset.hostname,
'title': asset.ip,
'pId': node.key,
'pId': parent_id,
'isParent': False,
'open': False,
'iconSkin': icon_skin,
......
......@@ -2,20 +2,21 @@
# -*- coding: utf-8 -*-
#
from django.urls import path, include
from django.urls import path, include, re_path
from rest_framework_bulk.routes import BulkRouter
from common import api as capi
from .. import api
app_name = 'terminal'
router = BulkRouter()
router.register(r'sessions', api.SessionViewSet, 'session')
router.register(r'terminal/(?P<terminal>[a-zA-Z0-9\-]{36})?/?status', api.StatusViewSet, 'terminal-status')
router.register(r'terminal/(?P<terminal>[a-zA-Z0-9\-]{36})?/?sessions', api.SessionViewSet, 'terminal-sessions')
router.register(r'terminal', api.TerminalViewSet, 'terminal')
router.register(r'terminals/(?P<terminal>[a-zA-Z0-9\-]{36})?/?status', api.StatusViewSet, 'terminal-status')
router.register(r'terminals/(?P<terminal>[a-zA-Z0-9\-]{36})?/?sessions', api.SessionViewSet, 'terminal-sessions')
router.register(r'terminals', api.TerminalViewSet, 'terminal')
router.register(r'tasks', api.TaskViewSet, 'tasks')
router.register(r'command', api.CommandViewSet, 'command')
router.register(r'commands', api.CommandViewSet, 'command')
router.register(r'status', api.StatusViewSet, 'status')
urlpatterns = [
......@@ -23,9 +24,9 @@ urlpatterns = [
api.SessionReplayViewSet.as_view({'get': 'retrieve', 'post': 'create'}),
name='session-replay'),
path('tasks/kill-session/', api.KillSessionAPI.as_view(), name='kill-session'),
path('terminal/<uuid:terminal>/access-key/', api.TerminalTokenApi.as_view(),
path('terminals/<uuid:terminal>/access-key/', api.TerminalTokenApi.as_view(),
name='terminal-access-key'),
path('terminal/config/', api.TerminalConfig.as_view(), name='terminal-config'),
path('terminals/config/', api.TerminalConfig.as_view(), name='terminal-config'),
path('commands/export/', api.CommandExportApi.as_view(), name="command-export")
# v2: get session's replay
# path('v2/sessions/<uuid:pk>/replay/',
......@@ -33,7 +34,11 @@ urlpatterns = [
# name='session-replay-v2'),
]
urlpatterns += router.urls
old_version_urlpatterns = [
re_path('(?P<resource>terminal|command)/.*', capi.redirect_plural_name_api)
]
urlpatterns += router.urls + old_version_urlpatterns
......@@ -2,15 +2,16 @@
# -*- coding: utf-8 -*-
#
from django.urls import path
from django.urls import path, re_path
from rest_framework_bulk.routes import BulkRouter
from common import api as capi
from .. import api_v2 as api
app_name = 'terminal'
router = BulkRouter()
router.register(r'terminal', api.TerminalViewSet, 'terminal')
router.register(r'terminals', api.TerminalViewSet, 'terminal')
urlpatterns = [
......@@ -18,4 +19,8 @@ urlpatterns = [
name='terminal-registration')
]
old_version_urlpatterns = [
re_path('(?P<resource>terminal)/.*', capi.redirect_plural_name_api)
]
urlpatterns += router.urls
......@@ -108,7 +108,7 @@ function onSelected(event, treeNode) {
}
function initTree() {
function initTree(refresh) {
var setting = {
view: {
dblClickExpand: false,
......@@ -131,11 +131,13 @@ function initTree() {
};
$.get(treeUrl, function(data, status) {
$.fn.zTree.init($("#assetTree"), setting, data);
zTree = $.fn.zTree.getZTreeObj("assetTree");
zTree = $.fn.zTree.init($("#assetTree"), setting, data);
if (!refresh) {
initTable();
}
rootNodeAddDom(zTree, function () {
treeUrl = setUrlParam(treeUrl, 'cache_policy', '2');
initTree();
initTree(true);
});
});
}
......
......@@ -39,7 +39,6 @@ var systemUsersUrl = "{% url 'api-perms:user-asset-system-users' pk=object.id as
$(document).ready(function () {
initTree();
initTable();
});
</script>
{% endblock %}
......@@ -42,7 +42,6 @@ var showAssetHref = true; // Need input default true
$(document).ready(function () {
initTree();
initTable();
});
</script>
{% endblock %}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册