From 76390d013e5a1d91fd2fddf87d68148feceab994 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Wed, 24 Aug 2022 16:36:42 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E6=A8=A1=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/serializers/__init__.py | 2 - apps/assets/serializers/account/__init__.py | 3 + .../serializers/{ => account}/account.py | 36 ++++----- .../{ => account}/account_history.py | 7 +- .../serializers/account/account_template.py | 74 +++++++++++++++++++ apps/assets/serializers/account/common.py | 26 +++++++ apps/assets/serializers/account_template.py | 22 ------ apps/assets/serializers/asset/common.py | 8 +- 8 files changed, 126 insertions(+), 52 deletions(-) create mode 100644 apps/assets/serializers/account/__init__.py rename apps/assets/serializers/{ => account}/account.py (65%) rename apps/assets/serializers/{ => account}/account_history.py (80%) create mode 100644 apps/assets/serializers/account/account_template.py create mode 100644 apps/assets/serializers/account/common.py delete mode 100644 apps/assets/serializers/account_template.py diff --git a/apps/assets/serializers/__init__.py b/apps/assets/serializers/__init__.py index a86110712..ef4b40abe 100644 --- a/apps/assets/serializers/__init__.py +++ b/apps/assets/serializers/__init__.py @@ -8,7 +8,5 @@ from .domain import * from .gathered_user import * from .favorite_asset import * from .account import * -from .account_history import * -from .account_template import * from .backup import * from .platform import * diff --git a/apps/assets/serializers/account/__init__.py b/apps/assets/serializers/account/__init__.py new file mode 100644 index 000000000..7ef87134a --- /dev/null +++ b/apps/assets/serializers/account/__init__.py @@ -0,0 +1,3 @@ +from .account import * +from .account_history import * +from .account_template import * diff --git a/apps/assets/serializers/account.py b/apps/assets/serializers/account/account.py similarity index 65% rename from apps/assets/serializers/account.py rename to apps/assets/serializers/account/account.py index 6695aa348..44da7837b 100644 --- a/apps/assets/serializers/account.py +++ b/apps/assets/serializers/account/account.py @@ -1,45 +1,35 @@ -from rest_framework import serializers -from django.utils.translation import ugettext_lazy as _ from django.db.models import F +from django.utils.translation import ugettext_lazy as _ +from rest_framework import serializers -from assets.models import Account from orgs.mixins.serializers import BulkOrgResourceModelSerializer - -from .base import AuthSerializerMixin from common.drf.serializers import SecretReadableMixin +from assets.models import Account +from assets.serializers.base import AuthSerializerMixin +from .account_template import AccountTemplateSerializerMixin +from .common import BaseAccountSerializer -class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): +class AccountSerializer( + AccountTemplateSerializerMixin, AuthSerializerMixin, BulkOrgResourceModelSerializer +): ip = serializers.ReadOnlyField(label=_("IP")) asset_name = serializers.ReadOnlyField(label=_("Asset")) platform = serializers.ReadOnlyField(label=_("Platform")) - class Meta: + class Meta(BaseAccountSerializer.Meta): model = Account - fields_mini = [ - 'id', 'privileged', 'username', 'ip', 'asset_name', - 'platform', 'version' - ] - fields_write_only = ['password', 'private_key', 'public_key', 'passphrase'] - fields_other = ['date_created', 'date_updated', 'connectivity', 'date_verified', 'comment'] - fields_small = fields_mini + fields_write_only + fields_other - fields_fk = ['asset'] - fields = fields_small + fields_fk - extra_kwargs = { - 'username': {'required': True}, - 'private_key': {'write_only': True}, - 'public_key': {'write_only': True}, - } - ref_name = 'AssetAccountSerializer' + fields = BaseAccountSerializer.Meta.fields + ['account_template', ] def validate(self, attrs): attrs = self._validate_gen_key(attrs) + attrs = super()._validate(attrs) return attrs @classmethod def setup_eager_loading(cls, queryset): """ Perform necessary eager loading of data. """ - queryset = queryset.prefetch_related('asset')\ + queryset = queryset.prefetch_related('asset') \ .annotate(ip=F('asset__ip')) \ .annotate(asset_name=F('asset__name')) return queryset diff --git a/apps/assets/serializers/account_history.py b/apps/assets/serializers/account/account_history.py similarity index 80% rename from apps/assets/serializers/account_history.py rename to apps/assets/serializers/account/account_history.py index b0846c04d..7fadc1a47 100644 --- a/apps/assets/serializers/account_history.py +++ b/apps/assets/serializers/account/account_history.py @@ -1,6 +1,7 @@ from assets.models import Account from common.drf.serializers import SecretReadableMixin +from .common import BaseAccountSerializer from .account import AccountSerializer, AccountSecretSerializer @@ -8,9 +9,9 @@ class AccountHistorySerializer(AccountSerializer): class Meta: model = Account.history.model - fields = AccountSerializer.Meta.fields_mini + \ - AccountSerializer.Meta.fields_write_only + \ - AccountSerializer.Meta.fields_fk + \ + fields = BaseAccountSerializer.Meta.fields_mini + \ + BaseAccountSerializer.Meta.fields_write_only + \ + BaseAccountSerializer.Meta.fields_fk + \ ['history_id', 'date_created', 'date_updated'] read_only_fields = fields ref_name = 'AccountHistorySerializer' diff --git a/apps/assets/serializers/account/account_template.py b/apps/assets/serializers/account/account_template.py new file mode 100644 index 000000000..dbe298f43 --- /dev/null +++ b/apps/assets/serializers/account/account_template.py @@ -0,0 +1,74 @@ +from django.utils.translation import ugettext_lazy as _ +from rest_framework import serializers + +from assets.models import AccountTemplate +from orgs.mixins.serializers import BulkOrgResourceModelSerializer +from assets.serializers.base import AuthSerializerMixin +from .common import BaseAccountSerializer + + +class AccountTemplateSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): + class Meta: + model = AccountTemplate + fields_mini = ['id', 'privileged', 'username', 'name'] + fields_write_only = BaseAccountSerializer.Meta.fields_write_only + fields_other = BaseAccountSerializer.Meta.fields_other + fields = fields_mini + fields_write_only + fields_other + extra_kwargs = { + 'username': {'required': True}, + 'private_key': {'write_only': True}, + 'public_key': {'write_only': True}, + } + + def validate(self, attrs): + attrs = self._validate_gen_key(attrs) + return attrs + + @classmethod + def validate_required(cls, attrs): + required_field_dict = {} + error = _('This field is required.') + for k, v in cls().fields.items(): + if v.required and k not in attrs: + required_field_dict[k] = error + print(required_field_dict) + if not required_field_dict: + return + raise serializers.ValidationError(required_field_dict) + + +class AccountTemplateSerializerMixin(serializers.ModelSerializer): + account_template = serializers.UUIDField( + required=False, allow_null=True, write_only=True, + label=_('Account template') + ) + + @staticmethod + def validate_account_template(value): + AccountTemplate.objects.get_or_create() + model = AccountTemplate + try: + return model.objects.get(id=value) + except AccountTemplate.DoesNotExist: + raise serializers.ValidationError(_('Account template not found')) + + @staticmethod + def replace_attrs(account_template: AccountTemplate, attrs: dict): + exclude_fields = [ + '_state', 'org_id', 'date_verified', 'id', 'date_created', 'date_updated', 'created_by' + ] + template_attrs = {k: v for k, v in account_template.__dict__.items() if k not in exclude_fields} + for k, v in template_attrs.items(): + attrs.setdefault(k, v) + + def _validate(self, attrs): + account_template = attrs.pop('account_template', None) + if account_template: + self.replace_attrs(account_template, attrs) + else: + AccountTemplateSerializer.validate_required(attrs) + return attrs + + + + diff --git a/apps/assets/serializers/account/common.py b/apps/assets/serializers/account/common.py new file mode 100644 index 000000000..3ad033e0e --- /dev/null +++ b/apps/assets/serializers/account/common.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# +from rest_framework import serializers + +__all__ = [ + 'BaseAccountSerializer', +] + + +class BaseAccountSerializer(serializers.ModelSerializer): + class Meta: + fields_mini = [ + 'id', 'privileged', 'username', 'ip', 'asset_name', + 'platform', 'version' + ] + fields_write_only = ['password', 'private_key', 'public_key', 'passphrase'] + fields_other = ['date_created', 'date_updated', 'connectivity', 'date_verified', 'comment'] + fields_small = fields_mini + fields_write_only + fields_other + fields_fk = ['asset'] + fields = fields_small + fields_fk + ref_name = 'AssetAccountSerializer' + extra_kwargs = { + 'username': {'required': True}, + 'private_key': {'write_only': True}, + 'public_key': {'write_only': True}, + } diff --git a/apps/assets/serializers/account_template.py b/apps/assets/serializers/account_template.py deleted file mode 100644 index 0762789fd..000000000 --- a/apps/assets/serializers/account_template.py +++ /dev/null @@ -1,22 +0,0 @@ -from assets.models import AccountTemplate -from orgs.mixins.serializers import BulkOrgResourceModelSerializer - -from .base import AuthSerializerMixin -from .account import AccountSerializer - - -class AccountTemplateSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): - class Meta: - model = AccountTemplate - fields_mini = ['id', 'privileged', 'username', 'name'] - fields_write_only = AccountSerializer.Meta.fields_write_only - fields_other = AccountSerializer.Meta.fields_other - fields = fields_mini + fields_write_only + fields_other - extra_kwargs = AccountSerializer.Meta.extra_kwargs - - def validate(self, attrs): - print(attrs) - - raise ValueError('test') - attrs = self._validate_gen_key(attrs) - return attrs diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 778137e23..aff489c84 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -2,6 +2,7 @@ # from rest_framework import serializers from django.utils.translation import ugettext_lazy as _ +from django.db.transaction import atomic from django.db.models import F from common.drf.serializers import JMSWritableNestedModelSerializer @@ -72,6 +73,7 @@ class AssetSerializer(JMSWritableNestedModelSerializer): """ 资产的数据结构 """ + class Meta: model = Asset fields_mini = [ @@ -108,8 +110,8 @@ class AssetSerializer(JMSWritableNestedModelSerializer): @classmethod def setup_eager_loading(cls, queryset): """ Perform necessary eager loading of data. """ - queryset = queryset.prefetch_related('domain', 'platform', 'protocols')\ - .annotate(category=F("platform__category"))\ + queryset = queryset.prefetch_related('domain', 'platform', 'protocols') \ + .annotate(category=F("platform__category")) \ .annotate(type=F("platform__type")) queryset = queryset.prefetch_related('nodes', 'labels') return queryset @@ -138,6 +140,7 @@ class AssetSerializer(JMSWritableNestedModelSerializer): raise serializers.ValidationError({'accounts': e}) serializer.save() + @atomic def create(self, validated_data): nodes_display = validated_data.pop('nodes_display', '') instance = super().create(validated_data) @@ -146,6 +149,7 @@ class AssetSerializer(JMSWritableNestedModelSerializer): self.perform_nodes_display_create(instance, nodes_display) return instance + @atomic def update(self, instance, validated_data): nodes_display = validated_data.pop('nodes_display', '') instance = super().update(instance, validated_data)