From 47e8ad3aacc210bb6997e7651d33778ca06da613 Mon Sep 17 00:00:00 2001 From: Bai Date: Thu, 15 Jul 2021 16:03:44 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E8=B5=84=E4=BA=A7=E5=85=B3=E8=81=94=E6=89=80=E5=9C=A8=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E7=9A=84=E7=B3=BB=E7=BB=9F=E7=94=A8=E6=88=B7=E6=97=B6?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E8=AE=BE=E7=BD=AE=E7=BB=84=E7=BB=87ID?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/signals_handler/asset.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/assets/signals_handler/asset.py b/apps/assets/signals_handler/asset.py index de81563f4..538b4b74a 100644 --- a/apps/assets/signals_handler/asset.py +++ b/apps/assets/signals_handler/asset.py @@ -96,7 +96,8 @@ def on_asset_nodes_add(instance, action, reverse, pk_set, **kwargs): asset_ids_to_push.append(asset_id) to_create.append(m2m_model( systemuser_id=system_user_id, - asset_id=asset_id + asset_id=asset_id, + org_id=instance.org_id )) if asset_ids_to_push: push_system_user_to_assets.delay(system_user_id, asset_ids_to_push) From 06a223376c03825fcfefcd78a57ae9b0b481a79b Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 15 Jul 2021 17:51:22 +0800 Subject: [PATCH 2/3] =?UTF-8?q?perf:=20=E5=9F=BA=E6=9C=AC=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/migrations/0071_systemuser_type.py | 26 ++++++++++++++++- .../migrations/0073_auto_20210606_1142.py | 1 + .../0074_remove_systemuser_assets.py | 7 ++--- apps/assets/models/asset.py | 28 ++++++------------- apps/assets/serializers/asset.py | 7 ----- apps/assets/signals_handler/asset.py | 2 ++ apps/assets/signals_handler/authbook.py | 10 ------- 7 files changed, 38 insertions(+), 43 deletions(-) diff --git a/apps/assets/migrations/0071_systemuser_type.py b/apps/assets/migrations/0071_systemuser_type.py index cb18edc60..c7a3a88fe 100644 --- a/apps/assets/migrations/0071_systemuser_type.py +++ b/apps/assets/migrations/0071_systemuser_type.py @@ -1,6 +1,8 @@ # Generated by Django 3.1.6 on 2021-06-04 16:46 from django.db import migrations, models, transaction +import django.db.models.deletion +from django.db.models import F def migrate_admin_user_to_system_user(apps, schema_editor): @@ -40,6 +42,13 @@ def migrate_admin_user_to_system_user(apps, schema_editor): s.assets.set(assets) +def migrate_assets_admin_user(apps, schema_editor): + asset_model = apps.get_model("assets", "Asset") + db_alias = schema_editor.connection.alias + assets = asset_model.objects.using(db_alias).all() + assets.update(admin_user=F('_admin_user')) + + class Migration(migrations.Migration): dependencies = [ @@ -62,5 +71,20 @@ class Migration(migrations.Migration): name='protocol', field=models.CharField(choices=[('ssh', 'SSH'), ('rdp', 'RDP'), ('telnet', 'Telnet'), ('vnc', 'VNC'), ('mysql', 'MySQL'), ('oracle', 'Oracle'), ('mariadb', 'MariaDB'), ('postgresql', 'PostgreSQL'), ('k8s', 'K8S')], default='ssh', max_length=16, verbose_name='Protocol'), ), - migrations.RunPython(migrate_admin_user_to_system_user) + migrations.RunPython(migrate_admin_user_to_system_user), + migrations.RenameField( + model_name='asset', + old_name='admin_user', + new_name='_admin_user', + ), + migrations.AddField( + model_name='asset', + name='admin_user', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='admin_assets', to='assets.systemuser', verbose_name='Admin user'), + ), + migrations.RunPython(migrate_assets_admin_user), + migrations.RemoveField( + model_name='asset', + name='_admin_user', + ), ] diff --git a/apps/assets/migrations/0073_auto_20210606_1142.py b/apps/assets/migrations/0073_auto_20210606_1142.py index e3ca122ce..5ba47716d 100644 --- a/apps/assets/migrations/0073_auto_20210606_1142.py +++ b/apps/assets/migrations/0073_auto_20210606_1142.py @@ -5,6 +5,7 @@ from django.db import migrations, models, transaction import django.db.models.deletion + def migrate_system_assets_to_authbook(apps, schema_editor): system_user_model = apps.get_model("assets", "SystemUser") system_user_asset_model = system_user_model.assets.through diff --git a/apps/assets/migrations/0074_remove_systemuser_assets.py b/apps/assets/migrations/0074_remove_systemuser_assets.py index c9961f5ad..250c31b34 100644 --- a/apps/assets/migrations/0074_remove_systemuser_assets.py +++ b/apps/assets/migrations/0074_remove_systemuser_assets.py @@ -1,6 +1,7 @@ # Generated by Django 3.1.6 on 2021-06-06 03:40 from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): @@ -14,11 +15,7 @@ class Migration(migrations.Migration): model_name='systemuser', name='assets', ), - migrations.RenameField( - model_name='asset', - old_name='admin_user', - new_name='_admin_user', - ), + migrations.AddField( model_name='systemuser', name='assets', diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index 3078543b1..523ef7d07 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -7,7 +7,6 @@ import logging from functools import reduce from collections import OrderedDict -from django.utils import timezone from django.db import models from common.db.models import TextChoices from django.utils.translation import ugettext_lazy as _ @@ -191,7 +190,7 @@ class Asset(AbsConnectivity, ProtocolsMixin, NodesRelationMixin, OrgModelMixin): is_active = models.BooleanField(default=True, verbose_name=_('Is active')) # Auth - _admin_user = models.ForeignKey('assets.AdminUser', on_delete=models.PROTECT, null=True, verbose_name=_("Admin user"), related_name='assets') + admin_user = models.ForeignKey('assets.SystemUser', on_delete=models.SET_NULL, null=True, verbose_name=_("Admin user"), related_name='admin_assets') # Some information public_ip = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Public IP')) @@ -225,22 +224,15 @@ class Asset(AbsConnectivity, ProtocolsMixin, NodesRelationMixin, OrgModelMixin): def __str__(self): return '{0.hostname}({0.ip})'.format(self) - __admin_user = None - - @property - def admin_user(self): - # 解决每次获取资产管理用户时都是最新的对象 - if self.__admin_user is None: - self.__admin_user = self.system_users.filter(type='admin').first() - return self.__admin_user - - @admin_user.setter - def admin_user(self, system_user): - if not system_user: + def set_admin_user_relation(self): + from .authbook import AuthBook + if not self.admin_user: return - if system_user.type != 'admin': + if self.admin_user.type != 'admin': raise ValidationError('System user should be type admin') - system_user.assets.add(self) + + defaults = {'asset': self, 'systemuser': self.admin_user, 'org_id': self.org_id} + AuthBook.objects.get_or_create(defaults=defaults, asset=self, systemuser=self.admin_user) @property def admin_user_display(self): @@ -248,10 +240,6 @@ class Asset(AbsConnectivity, ProtocolsMixin, NodesRelationMixin, OrgModelMixin): return '' return str(self.admin_user) - def remove_admin_user(self): - from ..models import AuthBook - AuthBook.objects.filter(asset=self, systemuser__type='admin').delete() - @property def is_valid(self): warning = '' diff --git a/apps/assets/serializers/asset.py b/apps/assets/serializers/asset.py index d329575eb..34a6c478d 100644 --- a/apps/assets/serializers/asset.py +++ b/apps/assets/serializers/asset.py @@ -62,9 +62,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer): platform = serializers.SlugRelatedField( slug_field='name', queryset=Platform.objects.all(), label=_("Platform") ) - admin_user = serializers.PrimaryKeyRelatedField( - queryset=SystemUser.objects, label=_('Admin user'), write_only=True - ) protocols = ProtocolsField(label=_('Protocols'), required=False, default=['ssh/22']) domain_display = serializers.ReadOnlyField(source='domain.name', label=_('Domain name')) nodes_display = serializers.ListField(child=serializers.CharField(), label=_('Nodes name'), required=False) @@ -147,19 +144,15 @@ class AssetSerializer(BulkOrgResourceModelSerializer): def create(self, validated_data): self.compatible_with_old_protocol(validated_data) nodes_display = validated_data.pop('nodes_display', '') - admin_user = validated_data.pop('admin_user', '') instance = super().create(validated_data) self.perform_nodes_display_create(instance, nodes_display) - instance.admin_user = admin_user return instance def update(self, instance, validated_data): nodes_display = validated_data.pop('nodes_display', '') self.compatible_with_old_protocol(validated_data) - admin_user = validated_data.pop('admin_user', '') instance = super().update(instance, validated_data) self.perform_nodes_display_create(instance, nodes_display) - instance.admin_user = admin_user return instance diff --git a/apps/assets/signals_handler/asset.py b/apps/assets/signals_handler/asset.py index 538b4b74a..97f727a46 100644 --- a/apps/assets/signals_handler/asset.py +++ b/apps/assets/signals_handler/asset.py @@ -52,6 +52,8 @@ def on_asset_created_or_update(sender, instance=None, created=False, **kwargs): if not has_node: instance.nodes.add(Node.org_root()) + instance.set_admin_user_relation() + @receiver(m2m_changed, sender=Asset.nodes.through) def on_asset_nodes_add(instance, action, reverse, pk_set, **kwargs): diff --git a/apps/assets/signals_handler/authbook.py b/apps/assets/signals_handler/authbook.py index 0068ad9b3..f1cb2303c 100644 --- a/apps/assets/signals_handler/authbook.py +++ b/apps/assets/signals_handler/authbook.py @@ -4,7 +4,6 @@ from simple_history.signals import pre_create_historical_record from django.db.models.signals import post_save, pre_save from common.utils import get_logger -from orgs.utils import tmp_to_root_org from ..models import AuthBook, SystemUser AuthBookHistory = apps.get_model('assets', 'HistoricalAuthBook') @@ -31,15 +30,6 @@ def pre_create_historical_record_callback(sender, history_instance=None, **kwarg @receiver(post_save, sender=AuthBook) def on_authbook_post_create(sender, instance, **kwargs): - # 去掉这个资产的管理用户 - if instance.systemuser and instance.systemuser.is_admin_user: - with tmp_to_root_org(): - deleted_count, other = AuthBook.objects.filter( - asset=instance.asset, - systemuser__type=SystemUser.Type.admin - ).exclude(id=instance.id).delete() - logger.debug('Remove asset old admin user: {}'.format(deleted_count)) - if not instance.systemuser: instance.sync_to_system_user_account() From 329565251a9ae2842bcda79c27490e526e8c4e2d Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 15 Jul 2021 17:57:14 +0800 Subject: [PATCH 3/3] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9prefetch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/asset.py | 1 - apps/assets/migrations/0073_auto_20210606_1142.py | 1 - apps/assets/serializers/asset.py | 15 +++------------ 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index 19e3dc9db..b4ed17556 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -42,7 +42,6 @@ class AssetViewSet(FilterAssetByNodeMixin, OrgBulkModelViewSet): ordering_fields = ("hostname", "ip", "port", "cpu_cores") serializer_classes = { 'default': serializers.AssetSerializer, - 'single': serializers.AssetVerboseSerializer, } permission_classes = (IsOrgAdminOrAppUser,) extra_filter_backends = [FilterAssetByNodeFilterBackend, LabelFilterBackend, IpInFilterBackend] diff --git a/apps/assets/migrations/0073_auto_20210606_1142.py b/apps/assets/migrations/0073_auto_20210606_1142.py index 5ba47716d..e3ca122ce 100644 --- a/apps/assets/migrations/0073_auto_20210606_1142.py +++ b/apps/assets/migrations/0073_auto_20210606_1142.py @@ -5,7 +5,6 @@ from django.db import migrations, models, transaction import django.db.models.deletion - def migrate_system_assets_to_authbook(apps, schema_editor): system_user_model = apps.get_model("assets", "SystemUser") system_user_asset_model = system_user_model.assets.through diff --git a/apps/assets/serializers/asset.py b/apps/assets/serializers/asset.py index 34a6c478d..6ed7990c8 100644 --- a/apps/assets/serializers/asset.py +++ b/apps/assets/serializers/asset.py @@ -8,7 +8,7 @@ from orgs.mixins.serializers import BulkOrgResourceModelSerializer from ..models import Asset, Node, Platform, SystemUser __all__ = [ - 'AssetSerializer', 'AssetSimpleSerializer', 'AssetVerboseSerializer', + 'AssetSerializer', 'AssetSimpleSerializer', 'ProtocolsField', 'PlatformSerializer', 'AssetTaskSerializer', ] @@ -80,7 +80,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer): 'hardware_info', 'connectivity', 'date_verified' ] fields_fk = [ - 'domain', 'domain_display', 'platform', 'admin_user', + 'domain', 'domain_display', 'platform', 'admin_user', 'admin_user_display' ] fields_m2m = [ 'nodes', 'nodes_display', 'labels', @@ -109,7 +109,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer): @classmethod def setup_eager_loading(cls, queryset): """ Perform necessary eager loading of data. """ - queryset = queryset.prefetch_related('domain', 'platform') + queryset = queryset.prefetch_related('domain', 'platform', 'admin_user') queryset = queryset.prefetch_related('nodes', 'labels') return queryset @@ -156,15 +156,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer): return instance -class AssetVerboseSerializer(AssetSerializer): - admin_user = serializers.PrimaryKeyRelatedField( - queryset=SystemUser.objects, label=_('Admin user') - ) - - class Meta(AssetSerializer.Meta): - fields = AssetSerializer.Meta.fields + ['admin_user_display'] - - class PlatformSerializer(serializers.ModelSerializer): meta = serializers.DictField(required=False, allow_null=True, label=_('Meta'))