mirror of https://github.com/jumpserver/jumpserver
Merge pull request #10235 from jumpserver/pr@dev@perf_asset_set_default_nodes
perf: custom fields 仅custom 类型资产支持pull/10236/head
commit
996690fc02
|
@ -60,7 +60,7 @@ class AccountCreateUpdateSerializerMixin(serializers.Serializer):
|
||||||
|
|
||||||
def set_uniq_name_if_need(self, initial_data, asset):
|
def set_uniq_name_if_need(self, initial_data, asset):
|
||||||
name = initial_data.get('name')
|
name = initial_data.get('name')
|
||||||
if name is None:
|
if name is not None:
|
||||||
return
|
return
|
||||||
if not name:
|
if not name:
|
||||||
name = initial_data.get('username')
|
name = initial_data.get('username')
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
import re
|
from django.db.models import F
|
||||||
|
|
||||||
from django.db.models import F, QuerySet
|
|
||||||
from django.db.transaction import atomic
|
from django.db.transaction import atomic
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from accounts.models import Account
|
from accounts.models import Account
|
||||||
from accounts.serializers import AccountSerializer
|
from accounts.serializers import AccountSerializer
|
||||||
from common.serializers import WritableNestedModelSerializer, SecretReadableMixin, CommonModelSerializer, \
|
from common.const import UUID_PATTERN
|
||||||
MethodSerializer
|
from common.serializers import (
|
||||||
from common.serializers.dynamic import create_serializer_class
|
WritableNestedModelSerializer, SecretReadableMixin,
|
||||||
|
CommonModelSerializer, MethodSerializer
|
||||||
|
)
|
||||||
from common.serializers.fields import LabeledChoiceField
|
from common.serializers.fields import LabeledChoiceField
|
||||||
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
from ...const import Category, AllTypes
|
from ...const import Category, AllTypes
|
||||||
|
@ -25,8 +25,6 @@ __all__ = [
|
||||||
'AccountSecretSerializer', 'AssetProtocolsPermsSerializer'
|
'AccountSecretSerializer', 'AssetProtocolsPermsSerializer'
|
||||||
]
|
]
|
||||||
|
|
||||||
uuid_pattern = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')
|
|
||||||
|
|
||||||
|
|
||||||
class AssetProtocolsSerializer(serializers.ModelSerializer):
|
class AssetProtocolsSerializer(serializers.ModelSerializer):
|
||||||
port = serializers.IntegerField(required=False, allow_null=True, max_value=65535, min_value=1)
|
port = serializers.IntegerField(required=False, allow_null=True, max_value=65535, min_value=1)
|
||||||
|
@ -121,12 +119,11 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
|
||||||
protocols = AssetProtocolsSerializer(many=True, required=False, label=_('Protocols'), default=())
|
protocols = AssetProtocolsSerializer(many=True, required=False, label=_('Protocols'), default=())
|
||||||
accounts = AssetAccountSerializer(many=True, required=False, allow_null=True, write_only=True, label=_('Account'))
|
accounts = AssetAccountSerializer(many=True, required=False, allow_null=True, write_only=True, label=_('Account'))
|
||||||
nodes_display = serializers.ListField(read_only=False, required=False, label=_("Node path"))
|
nodes_display = serializers.ListField(read_only=False, required=False, label=_("Node path"))
|
||||||
custom_info = MethodSerializer(label=_('Custom info'))
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Asset
|
model = Asset
|
||||||
fields_mini = ['id', 'name', 'address']
|
fields_mini = ['id', 'name', 'address']
|
||||||
fields_small = fields_mini + ['custom_info', 'is_active', 'comment']
|
fields_small = fields_mini + ['is_active', 'comment']
|
||||||
fields_fk = ['domain', 'platform']
|
fields_fk = ['domain', 'platform']
|
||||||
fields_m2m = [
|
fields_m2m = [
|
||||||
'nodes', 'labels', 'protocols',
|
'nodes', 'labels', 'protocols',
|
||||||
|
@ -193,36 +190,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
|
||||||
.annotate(type=F("platform__type"))
|
.annotate(type=F("platform__type"))
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def get_custom_info_serializer(self):
|
|
||||||
request = self.context.get('request')
|
|
||||||
default_field = serializers.DictField(required=False, label=_('Custom info'))
|
|
||||||
|
|
||||||
if not request:
|
|
||||||
return default_field
|
|
||||||
|
|
||||||
if self.instance and isinstance(self.instance, (QuerySet, list)):
|
|
||||||
return default_field
|
|
||||||
|
|
||||||
if not self.instance and uuid_pattern.findall(request.path):
|
|
||||||
pk = uuid_pattern.findall(request.path)[0]
|
|
||||||
self.instance = Asset.objects.filter(id=pk).first()
|
|
||||||
|
|
||||||
platform = None
|
|
||||||
if self.instance:
|
|
||||||
platform = self.instance.platform
|
|
||||||
elif request.query_params.get('platform'):
|
|
||||||
platform_id = request.query_params.get('platform')
|
|
||||||
platform_id = int(platform_id) if platform_id.isdigit() else 0
|
|
||||||
platform = Platform.objects.filter(id=platform_id).first()
|
|
||||||
|
|
||||||
if not platform:
|
|
||||||
return default_field
|
|
||||||
custom_fields = platform.custom_fields
|
|
||||||
if not custom_fields:
|
|
||||||
return default_field
|
|
||||||
name = platform.name.title() + 'CustomSerializer'
|
|
||||||
return create_serializer_class(name, custom_fields)()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def perform_nodes_display_create(instance, nodes_display):
|
def perform_nodes_display_create(instance, nodes_display):
|
||||||
if not nodes_display:
|
if not nodes_display:
|
||||||
|
@ -267,12 +234,13 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
|
||||||
nodes_display = self.initial_data.get('nodes_display')
|
nodes_display = self.initial_data.get('nodes_display')
|
||||||
if nodes_display:
|
if nodes_display:
|
||||||
return nodes
|
return nodes
|
||||||
|
default_node = Node.org_root()
|
||||||
request = self.context.get('request')
|
request = self.context.get('request')
|
||||||
if not request:
|
if not request:
|
||||||
return []
|
return [default_node]
|
||||||
node_id = request.query_params.get('node_id')
|
node_id = request.query_params.get('node_id')
|
||||||
if not node_id:
|
if not node_id:
|
||||||
return []
|
return [default_node]
|
||||||
nodes = Node.objects.filter(id=node_id)
|
nodes = Node.objects.filter(id=node_id)
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
@ -335,8 +303,8 @@ class DetailMixin(serializers.Serializer):
|
||||||
|
|
||||||
def get_instance(self):
|
def get_instance(self):
|
||||||
request = self.context.get('request')
|
request = self.context.get('request')
|
||||||
if not self.instance and uuid_pattern.findall(request.path):
|
if not self.instance and UUID_PATTERN.findall(request.path):
|
||||||
pk = uuid_pattern.findall(request.path)[0]
|
pk = UUID_PATTERN.findall(request.path)[0]
|
||||||
self.instance = Asset.objects.filter(id=pk).first()
|
self.instance = Asset.objects.filter(id=pk).first()
|
||||||
return self.instance
|
return self.instance
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,48 @@
|
||||||
from assets.models import Custom
|
from django.db.models import QuerySet
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from assets.models import Custom, Platform, Asset
|
||||||
|
from common.const import UUID_PATTERN
|
||||||
|
from common.serializers import MethodSerializer, create_serializer_class
|
||||||
from .common import AssetSerializer
|
from .common import AssetSerializer
|
||||||
|
|
||||||
__all__ = ['CustomSerializer']
|
__all__ = ['CustomSerializer']
|
||||||
|
|
||||||
|
|
||||||
class CustomSerializer(AssetSerializer):
|
class CustomSerializer(AssetSerializer):
|
||||||
|
custom_info = MethodSerializer(label=_('Custom info'))
|
||||||
|
|
||||||
class Meta(AssetSerializer.Meta):
|
class Meta(AssetSerializer.Meta):
|
||||||
model = Custom
|
model = Custom
|
||||||
|
fields = AssetSerializer.Meta.fields + ['custom_info']
|
||||||
|
|
||||||
|
def get_custom_info_serializer(self):
|
||||||
|
request = self.context.get('request')
|
||||||
|
default_field = serializers.DictField(required=False, label=_('Custom info'))
|
||||||
|
|
||||||
|
if not request:
|
||||||
|
return default_field
|
||||||
|
|
||||||
|
if self.instance and isinstance(self.instance, (QuerySet, list)):
|
||||||
|
return default_field
|
||||||
|
|
||||||
|
if not self.instance and UUID_PATTERN.findall(request.path):
|
||||||
|
pk = UUID_PATTERN.findall(request.path)[0]
|
||||||
|
self.instance = Asset.objects.filter(id=pk).first()
|
||||||
|
|
||||||
|
platform = None
|
||||||
|
if self.instance:
|
||||||
|
platform = self.instance.platform
|
||||||
|
elif request.query_params.get('platform'):
|
||||||
|
platform_id = request.query_params.get('platform')
|
||||||
|
platform_id = int(platform_id) if platform_id.isdigit() else 0
|
||||||
|
platform = Platform.objects.filter(id=platform_id).first()
|
||||||
|
|
||||||
|
if not platform:
|
||||||
|
return default_field
|
||||||
|
custom_fields = platform.custom_fields
|
||||||
|
if not custom_fields:
|
||||||
|
return default_field
|
||||||
|
name = platform.name.title() + 'CustomSerializer'
|
||||||
|
return create_serializer_class(name, custom_fields)()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import re
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
create_success_msg = _("%(name)s was created successfully")
|
create_success_msg = _("%(name)s was created successfully")
|
||||||
|
@ -9,3 +11,4 @@ KEY_CACHE_RESOURCE_IDS = "RESOURCE_IDS_{}"
|
||||||
# AD User AccountDisable
|
# AD User AccountDisable
|
||||||
# https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties
|
# https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties
|
||||||
LDAP_AD_ACCOUNT_DISABLE = 2
|
LDAP_AD_ACCOUNT_DISABLE = 2
|
||||||
|
UUID_PATTERN = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from drf_writable_nested.serializers import WritableNestedModelSerializer as NestedModelSerializer
|
from drf_writable_nested.serializers import WritableNestedModelSerializer as NestedModelSerializer
|
||||||
|
@ -35,7 +37,11 @@ class MethodSerializer(serializers.Serializer):
|
||||||
@cached_property
|
@cached_property
|
||||||
def serializer(self) -> serializers.Serializer:
|
def serializer(self) -> serializers.Serializer:
|
||||||
method = getattr(self.parent, self.method_name)
|
method = getattr(self.parent, self.method_name)
|
||||||
_serializer = method()
|
try:
|
||||||
|
_serializer = method()
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(e, exc_info=True)
|
||||||
|
raise e
|
||||||
# 设置serializer的parent值,否则在serializer实例中获取parent会出现断层
|
# 设置serializer的parent值,否则在serializer实例中获取parent会出现断层
|
||||||
setattr(_serializer, 'parent', self.parent)
|
setattr(_serializer, 'parent', self.parent)
|
||||||
return _serializer
|
return _serializer
|
||||||
|
|
|
@ -63,7 +63,7 @@ class LabeledChoiceField(ChoiceField):
|
||||||
def to_representation(self, key):
|
def to_representation(self, key):
|
||||||
if key is None:
|
if key is None:
|
||||||
return key
|
return key
|
||||||
label = self.choice_mapper.get(key)
|
label = self.choice_mapper.get(key, key)
|
||||||
return {"value": key, "label": label}
|
return {"value": key, "label": label}
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
|
|
Loading…
Reference in New Issue