mirror of https://github.com/jumpserver/jumpserver
parent
b98aa377b6
commit
f06059837d
|
@ -69,7 +69,7 @@ class SerializeToTreeNodeMixin:
|
||||||
return 'file'
|
return 'file'
|
||||||
|
|
||||||
@timeit
|
@timeit
|
||||||
def serialize_assets(self, assets, node_key=None):
|
def serialize_assets(self, assets, node_key=None, pid=None):
|
||||||
sftp_enabled_platform = PlatformProtocol.objects \
|
sftp_enabled_platform = PlatformProtocol.objects \
|
||||||
.filter(name='ssh', setting__sftp_enabled=True) \
|
.filter(name='ssh', setting__sftp_enabled=True) \
|
||||||
.values_list('platform', flat=True) \
|
.values_list('platform', flat=True) \
|
||||||
|
@ -83,8 +83,10 @@ class SerializeToTreeNodeMixin:
|
||||||
{
|
{
|
||||||
'id': str(asset.id),
|
'id': str(asset.id),
|
||||||
'name': asset.name,
|
'name': asset.name,
|
||||||
'title': f'{asset.address}\n{asset.comment}',
|
'title':
|
||||||
'pId': get_pid(asset),
|
f'{asset.address}\n{asset.comment}'
|
||||||
|
if asset.comment else asset.address,
|
||||||
|
'pId': pid or get_pid(asset),
|
||||||
'isParent': False,
|
'isParent': False,
|
||||||
'open': False,
|
'open': False,
|
||||||
'iconSkin': self.get_icon(asset),
|
'iconSkin': self.get_icon(asset),
|
||||||
|
|
|
@ -193,15 +193,38 @@ class AllTypes(ChoicesMixin):
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def to_tree_nodes(cls, include_asset, count_resource='asset'):
|
|
||||||
from accounts.models import Account
|
|
||||||
from ..models import Asset, Platform
|
|
||||||
if count_resource == 'account':
|
|
||||||
resource_platforms = Account.objects.all().values_list('asset__platform_id', flat=True)
|
|
||||||
else:
|
|
||||||
resource_platforms = Asset.objects.all().values_list('platform_id', flat=True)
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def asset_to_node(cls, asset, pid):
|
||||||
|
node = {
|
||||||
|
'id': '{}'.format(asset.id),
|
||||||
|
'name': asset.name,
|
||||||
|
'title': f'{asset.address}\n{asset.comment}',
|
||||||
|
'pId': pid,
|
||||||
|
'isParent': False,
|
||||||
|
'open': False,
|
||||||
|
'iconSkin': asset.type,
|
||||||
|
'chkDisabled': not asset.is_active,
|
||||||
|
'meta': {
|
||||||
|
'type': 'platform',
|
||||||
|
'data': {
|
||||||
|
'platform_type': asset.platform.type,
|
||||||
|
'org_name': asset.org_name,
|
||||||
|
# 'sftp': asset.platform_id in sftp_enabled_platform,
|
||||||
|
'name': asset.name,
|
||||||
|
'address': asset.address
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_root_nodes(cls):
|
||||||
|
return dict(id='ROOT', name=_('All types'), title=_('All types'), open=True, isParent=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_tree_nodes(cls, resource_platforms, include_asset=False):
|
||||||
|
from ..models import Platform
|
||||||
platform_count = defaultdict(int)
|
platform_count = defaultdict(int)
|
||||||
for platform_id in resource_platforms:
|
for platform_id in resource_platforms:
|
||||||
platform_count[platform_id] += 1
|
platform_count[platform_id] += 1
|
||||||
|
@ -215,8 +238,7 @@ class AllTypes(ChoicesMixin):
|
||||||
category_type_mapper[p.category] += platform_count[p.id]
|
category_type_mapper[p.category] += platform_count[p.id]
|
||||||
tp_platforms[p.category + '_' + p.type].append(p)
|
tp_platforms[p.category + '_' + p.type].append(p)
|
||||||
|
|
||||||
root = dict(id='ROOT', name=_('All types'), title=_('All types'), open=True, isParent=True)
|
nodes = [cls.get_root_nodes()]
|
||||||
nodes = [root]
|
|
||||||
for category, type_cls in cls.category_types():
|
for category, type_cls in cls.category_types():
|
||||||
# Category 格式化
|
# Category 格式化
|
||||||
meta = {'type': 'category', 'category': category.value}
|
meta = {'type': 'category', 'category': category.value}
|
||||||
|
@ -244,6 +266,16 @@ class AllTypes(ChoicesMixin):
|
||||||
nodes.append(platform_node)
|
nodes.append(platform_node)
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def to_tree_nodes(cls, include_asset, count_resource='asset'):
|
||||||
|
from accounts.models import Account
|
||||||
|
from ..models import Asset
|
||||||
|
if count_resource == 'account':
|
||||||
|
resource_platforms = Account.objects.all().values_list('asset__platform_id', flat=True)
|
||||||
|
else:
|
||||||
|
resource_platforms = Asset.objects.all().values_list('platform_id', flat=True)
|
||||||
|
return cls.get_tree_nodes(resource_platforms, include_asset)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_type_default_platform(cls, category, tp):
|
def get_type_default_platform(cls, category, tp):
|
||||||
constraints = cls.get_constraints(category, tp)
|
constraints = cls.get_constraints(category, tp)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import abc
|
import abc
|
||||||
|
import re
|
||||||
|
from collections import defaultdict
|
||||||
from urllib.parse import parse_qsl
|
from urllib.parse import parse_qsl
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -11,6 +13,7 @@ from rest_framework.response import Response
|
||||||
|
|
||||||
from accounts.const import AliasAccount
|
from accounts.const import AliasAccount
|
||||||
from assets.api import SerializeToTreeNodeMixin
|
from assets.api import SerializeToTreeNodeMixin
|
||||||
|
from assets.const import AllTypes
|
||||||
from assets.models import Asset
|
from assets.models import Asset
|
||||||
from assets.utils import KubernetesTree
|
from assets.utils import KubernetesTree
|
||||||
from authentication.models import ConnectionToken
|
from authentication.models import ConnectionToken
|
||||||
|
@ -26,7 +29,8 @@ from ..mixin import SelfOrPKUserMixin
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'UserGrantedK8sAsTreeApi',
|
'UserGrantedK8sAsTreeApi',
|
||||||
'UserPermedNodesWithAssetsAsTreeApi',
|
'UserPermedNodesWithAssetsAsTreeApi',
|
||||||
'UserPermedNodeChildrenWithAssetsAsTreeApi'
|
'UserPermedNodeChildrenWithAssetsAsTreeApi',
|
||||||
|
'UserPermedNodeChildrenWithAssetsAsCategoryTreeApi',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,6 +141,75 @@ class UserPermedNodeChildrenWithAssetsAsTreeApi(BaseUserNodeWithAssetAsTreeApi):
|
||||||
return self.query_node_key or self.default_unfolded_node_key
|
return self.query_node_key or self.default_unfolded_node_key
|
||||||
|
|
||||||
|
|
||||||
|
class UserPermedNodeChildrenWithAssetsAsCategoryTreeApi(
|
||||||
|
SelfOrPKUserMixin, SerializeToTreeNodeMixin, ListAPIView
|
||||||
|
):
|
||||||
|
@property
|
||||||
|
def is_sync(self):
|
||||||
|
sync = self.request.query_params.get('sync', 0)
|
||||||
|
return int(sync) == 1
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tp(self):
|
||||||
|
return self.request.query_params.get('type')
|
||||||
|
|
||||||
|
def get_assets(self):
|
||||||
|
query_asset_util = UserPermAssetUtil(self.user)
|
||||||
|
node = PermNode.objects.filter(
|
||||||
|
granted_node_rels__user=self.user, parent_key='').first()
|
||||||
|
if node:
|
||||||
|
__, assets = query_asset_util.get_node_all_assets(node.id)
|
||||||
|
else:
|
||||||
|
assets = Asset.objects.none()
|
||||||
|
return assets
|
||||||
|
|
||||||
|
def to_tree_nodes(self, assets):
|
||||||
|
if not assets:
|
||||||
|
return []
|
||||||
|
assets = assets.annotate(tp=F('platform__type'))
|
||||||
|
asset_type_map = defaultdict(list)
|
||||||
|
for asset in assets:
|
||||||
|
asset_type_map[asset.tp].append(asset)
|
||||||
|
tp = self.tp
|
||||||
|
if tp:
|
||||||
|
assets = asset_type_map.get(tp, [])
|
||||||
|
if not assets:
|
||||||
|
return []
|
||||||
|
pid = f'ROOT_{str(assets[0].category).upper()}_{tp}'
|
||||||
|
return self.serialize_assets(assets, pid=pid)
|
||||||
|
|
||||||
|
resource_platforms = assets.values_list('platform_id', flat=True)
|
||||||
|
node_all = AllTypes.get_tree_nodes(resource_platforms)
|
||||||
|
pattern = re.compile(r'\(0\)?')
|
||||||
|
nodes = []
|
||||||
|
for node in node_all:
|
||||||
|
meta = node.get('meta', {})
|
||||||
|
if pattern.search(node['name']) or meta.get('type') == 'platform':
|
||||||
|
continue
|
||||||
|
_type = meta.get('_type')
|
||||||
|
if _type:
|
||||||
|
node['type'] = _type
|
||||||
|
nodes.append(node)
|
||||||
|
|
||||||
|
if not self.is_sync:
|
||||||
|
return nodes
|
||||||
|
|
||||||
|
asset_nodes = []
|
||||||
|
for node in nodes:
|
||||||
|
node['open'] = True
|
||||||
|
tp = node.get('meta', {}).get('_type')
|
||||||
|
if not tp:
|
||||||
|
continue
|
||||||
|
assets = asset_type_map.get(tp, [])
|
||||||
|
asset_nodes += self.serialize_assets(assets, pid=node['id'])
|
||||||
|
return nodes + asset_nodes
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
assets = self.get_assets()
|
||||||
|
nodes = self.to_tree_nodes(assets)
|
||||||
|
return Response(data=nodes)
|
||||||
|
|
||||||
|
|
||||||
class UserGrantedK8sAsTreeApi(SelfOrPKUserMixin, ListAPIView):
|
class UserGrantedK8sAsTreeApi(SelfOrPKUserMixin, ListAPIView):
|
||||||
""" 用户授权的K8s树 """
|
""" 用户授权的K8s树 """
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ user_permission_urlpatterns = [
|
||||||
path('<str:user>/nodes/children-with-assets/tree/',
|
path('<str:user>/nodes/children-with-assets/tree/',
|
||||||
api.UserPermedNodeChildrenWithAssetsAsTreeApi.as_view(),
|
api.UserPermedNodeChildrenWithAssetsAsTreeApi.as_view(),
|
||||||
name='user-node-children-with-assets-as-tree'),
|
name='user-node-children-with-assets-as-tree'),
|
||||||
|
path('<str:user>/nodes/children-with-assets/category/tree/',
|
||||||
|
api.UserPermedNodeChildrenWithAssetsAsCategoryTreeApi.as_view(),
|
||||||
|
name='user-node-children-with-assets-as-category-tree'),
|
||||||
# 同步树
|
# 同步树
|
||||||
path('<str:user>/nodes/all-with-assets/tree/',
|
path('<str:user>/nodes/all-with-assets/tree/',
|
||||||
api.UserPermedNodesWithAssetsAsTreeApi.as_view(),
|
api.UserPermedNodesWithAssetsAsTreeApi.as_view(),
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
from assets.models import FavoriteAsset, Asset
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from assets.models import FavoriteAsset, Asset
|
||||||
from common.utils.common import timeit
|
from common.utils.common import timeit
|
||||||
|
|
||||||
from perms.models import AssetPermission, PermNode, UserAssetGrantedTreeNodeRelation
|
from perms.models import AssetPermission, PermNode, UserAssetGrantedTreeNodeRelation
|
||||||
|
|
||||||
from .permission import AssetPermissionUtil
|
from .permission import AssetPermissionUtil
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['AssetPermissionPermAssetUtil', 'UserPermAssetUtil', 'UserPermNodeUtil']
|
__all__ = ['AssetPermissionPermAssetUtil', 'UserPermAssetUtil', 'UserPermNodeUtil']
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue