From e53aa9696bbec1246022380082c94b0756d461f0 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 5 May 2022 16:18:05 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20serializer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/platform.py | 11 ++++++++- apps/assets/const.py | 32 ++++++++++++++++++++----- apps/assets/models/platform.py | 7 +++--- apps/assets/serializers/asset/common.py | 24 +++++++++---------- apps/assets/serializers/platform.py | 32 +++---------------------- 5 files changed, 53 insertions(+), 53 deletions(-) diff --git a/apps/assets/api/platform.py b/apps/assets/api/platform.py index dfa63f8f6..6bc1c4681 100644 --- a/apps/assets/api/platform.py +++ b/apps/assets/api/platform.py @@ -20,7 +20,8 @@ class AssetPlatformViewSet(JMSModelViewSet): filterset_fields = ['name'] search_fields = ['name'] rbac_perms = { - 'categories': 'assets.view_platform' + 'categories': 'assets.view_platform', + 'type_limits': 'assets-view_platform' } @action(methods=['GET'], detail=False) @@ -29,6 +30,14 @@ class AssetPlatformViewSet(JMSModelViewSet): serializer = self.get_serializer(data, many=True) return Response(serializer.data) + @action(methods=['GET'], detail=False, url_path='type-limits') + def type_limits(self, request, *args, **kwargs): + category = request.query_params.get('category') + tp = request.query_params.get('type') + limits = AllTypes.get_type_limits(category, tp) + return Response(limits) + + def check_object_permissions(self, request, obj): if request.method.lower() in ['delete', 'put', 'patch'] and obj.internal: self.permission_denied( diff --git a/apps/assets/const.py b/apps/assets/const.py index 87f17b1af..08269cf4d 100644 --- a/apps/assets/const.py +++ b/apps/assets/const.py @@ -11,7 +11,7 @@ __all__ = [ class PlatformMixin: @classmethod - def platform_meta(cls): + def platform_limits(cls): return {} @@ -23,7 +23,7 @@ class Category(PlatformMixin, models.TextChoices): CLOUD = 'cloud', _("Clouding") @classmethod - def platform_meta(cls): + def platform_limits(cls): return { cls.HOST: { 'has_domain': True, @@ -40,7 +40,8 @@ class Category(PlatformMixin, models.TextChoices): 'has_domain': True }, cls.CLOUD: { - 'has_domain': False + 'has_domain': False, + 'protocol_limit': [] } } @@ -55,7 +56,7 @@ class HostTypes(PlatformMixin, models.TextChoices): OTHER_HOST = 'other_host', _("Other host") @classmethod - def platform_meta(cls): + def platform_limits(cls): return {} @classmethod @@ -87,9 +88,9 @@ class DatabaseTypes(PlatformMixin, models.TextChoices): REDIS = 'redis', 'Redis' @classmethod - def platform_meta(cls): + def platform_limits(cls): meta = {} - for name, labal in cls.choices: + for name, label in cls.choices: meta[name] = { 'protocols_limit': [name] } @@ -114,6 +115,25 @@ class AllTypes(metaclass=IncludesTextChoicesMeta): RemoteAppTypes, CloudTypes ] + @classmethod + def get_type_limits(cls, category, tp): + limits = Category.platform_limits().get(category, {}) + types_cls = dict(cls.category_types()).get(category) + if not types_cls: + return {} + types_limits = types_cls.platform_limits() or {} + type_limits = types_limits.get(tp, {}) + limits.update(type_limits) + + _protocols_limit = limits.get('protocols_limit', []) + default_ports = Protocol.default_ports() + protocols_limit = [] + for p in _protocols_limit: + port = default_ports.get(p, 0) + protocols_limit.append(f'{p}/{port}') + limits['protocols_limit'] = protocols_limit + return limits + @classmethod def category_types(cls): return ( diff --git a/apps/assets/models/platform.py b/apps/assets/models/platform.py index 186da3dd3..4a7ed2ce4 100644 --- a/apps/assets/models/platform.py +++ b/apps/assets/models/platform.py @@ -39,15 +39,14 @@ class Platform(models.Model): def get_type_meta(cls, category, tp): meta = Category.platform_meta().get(category, {}) types = dict(AllTypes.category_types()).get(category) - # if not types: - # return {} types_meta = types.platform_meta() or {} type_meta = types_meta.get(tp, {}) meta.update(type_meta) return meta - def get_meta(self): - return self.__class__.get_type_meta(self.category, self.type) + @property + def type_limits(self): + return AllTypes.get_type_limits(self.category, self.type) @classmethod def default(cls): diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 883a1d0b8..74f54ed07 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -27,7 +27,9 @@ def validate_duplicate_protocols(values): errors = [] names = [] - for value in values: + print("Value is: ", values) + + for value in values.split(' '): if not value or '/' not in value: continue name = value.split('/')[0] @@ -42,9 +44,7 @@ def validate_duplicate_protocols(values): class ProtocolsField(serializers.ListField): default_validators = [validate_duplicate_protocols] - def __init__(self, protocols=None, *args, **kwargs): - self.choices = [] - self.set_protocols(protocols) + def __init__(self, *args, **kwargs): kwargs['child'] = ProtocolField() kwargs['allow_null'] = True kwargs['allow_empty'] = True @@ -52,12 +52,6 @@ class ProtocolsField(serializers.ListField): kwargs['max_length'] = 32 super().__init__(*args, **kwargs) - def set_protocols(self, protocols): - if protocols is None: - protocols = [] - self.choices = [(c, c) for c in protocols] - print("Chocies: ", self.choices) - def to_representation(self, value): if not value: return [] @@ -65,6 +59,9 @@ class ProtocolsField(serializers.ListField): return value.split(' ') return value + def to_internal_value(self, data): + return ' '.join(data) + class AssetSerializer(CategoryDisplayMixin, OrgResourceModelSerializerMixin): protocols = ProtocolsField(label=_('Protocols'), required=False, default=['ssh/22']) @@ -76,7 +73,9 @@ class AssetSerializer(CategoryDisplayMixin, OrgResourceModelSerializerMixin): child=serializers.CharField(), label=_('Labels name'), required=False, read_only=True ) - platform_display = serializers.SlugField(source='platform.name', label=_("Platform display"), read_only=True) + platform_display = serializers.SlugField( + source='platform.name', label=_("Platform display"), read_only=True + ) """ 资产的数据结构 @@ -100,8 +99,7 @@ class AssetSerializer(CategoryDisplayMixin, OrgResourceModelSerializerMixin): ] read_only_fields = [ 'category', 'category_display', 'type', 'type_display', - 'connectivity', 'date_verified', - 'created_by', 'date_created', + 'connectivity', 'date_verified', 'created_by', 'date_created', ] fields = fields_small + fields_fk + fields_m2m + read_only_fields extra_kwargs = { diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py index 44e8ebb88..7a68e045d 100644 --- a/apps/assets/serializers/platform.py +++ b/apps/assets/serializers/platform.py @@ -13,6 +13,7 @@ __all__ = ['PlatformSerializer'] class PlatformSerializer(CategoryDisplayMixin, serializers.ModelSerializer): meta = serializers.DictField(required=False, allow_null=True, label=_('Meta')) protocols_default = ProtocolsField(label=_('Protocols'), required=False) + type_limits = serializers.ReadOnlyField(required=False, read_only=True) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -21,35 +22,7 @@ class PlatformSerializer(CategoryDisplayMixin, serializers.ModelSerializer): validators = self.fields['name'].validators if isinstance(validators[-1], RegexValidator): validators.pop() - self.set_platform_meta() - - def set_platform_meta(self): - view = self.context.get('view') - if not view: - return - request = view.request - - if isinstance(self.instance, Platform): - category = self.instance.category - tp = self.instance.type - else: - tp = request.query_params.get('type') - category = request.query_params.get('category') - - print("Request: {}".format(self.context.get('request').method), category, tp) - if not all([tp, category]): - return - meta = Platform.get_type_meta(category, tp) - print("Platform meta: {}".format(meta)) - protocols_default = self.fields['protocols_default'] - limits = meta.get('protocols_limit', []) - default_ports = Protocol.default_ports() - protocols = [] - for protocol in limits: - port = default_ports.get(protocol, 22) - protocols.append(f'{protocol}/{port}') - print("set ptocols: ", protocols) - protocols_default.set_protocols(protocols) + # self.set_platform_meta() class Meta: model = Platform @@ -58,6 +31,7 @@ class PlatformSerializer(CategoryDisplayMixin, serializers.ModelSerializer): 'meta', 'comment', 'charset', 'category', 'category_display', 'type', 'type_display', + 'type_limits', ] fields_fk = [ 'domain_enabled', 'domain_default',