diff --git a/apps/assets/signals_handler.py b/apps/assets/signals_handler.py index c3f0e979d..1c2813aa9 100644 --- a/apps/assets/signals_handler.py +++ b/apps/assets/signals_handler.py @@ -58,7 +58,8 @@ def on_asset_created_or_update(sender, instance=None, created=False, **kwargs): @receiver(post_save, sender=SystemUser, dispatch_uid="jms") -def on_system_user_update(sender, instance=None, created=True, **kwargs): +@on_transaction_commit +def on_system_user_update(instance: SystemUser, created, **kwargs): """ 当系统用户更新时,可能更新了秘钥,用户名等,这时要自动推送系统用户到资产上, 其实应该当 用户名,密码,秘钥 sudo等更新时再推送,这里偷个懒, @@ -68,26 +69,25 @@ def on_system_user_update(sender, instance=None, created=True, **kwargs): if instance and not created: logger.info("System user update signal recv: {}".format(instance)) assets = instance.assets.all().valid() - push_system_user_to_assets.delay(instance, assets) + push_system_user_to_assets.delay(instance.id, [_asset.id for _asset in assets]) @receiver(m2m_changed, sender=SystemUser.assets.through) -def on_system_user_assets_change(sender, instance=None, action='', model=None, pk_set=None, **kwargs): +def on_system_user_assets_change(instance, action, model, pk_set, **kwargs): """ 当系统用户和资产关系发生变化时,应该重新推送系统用户到新添加的资产中 """ if action != POST_ADD: return logger.debug("System user assets change signal recv: {}".format(instance)) - queryset = model.objects.filter(pk__in=pk_set) if model == Asset: - system_users = [instance] - assets = queryset + system_users_id = [instance.id] + assets_id = pk_set else: - system_users = queryset - assets = [instance] - for system_user in system_users: - push_system_user_to_assets.delay(system_user, assets) + system_users_id = pk_set + assets_id = [instance.id] + for system_user_id in system_users_id: + push_system_user_to_assets.delay(system_user_id, assets_id) @receiver(m2m_changed, sender=SystemUser.users.through) diff --git a/apps/assets/tasks/push_system_user.py b/apps/assets/tasks/push_system_user.py index 7fc7bdab2..efb86d892 100644 --- a/apps/assets/tasks/push_system_user.py +++ b/apps/assets/tasks/push_system_user.py @@ -2,7 +2,7 @@ from itertools import groupby from celery import shared_task -from common.db.utils import get_object_if_need, get_objects_if_need +from common.db.utils import get_object_if_need, get_objects_if_need, get_objects from django.utils.translation import ugettext as _ from django.db.models import Empty @@ -240,10 +240,10 @@ def push_system_user_a_asset_manual(system_user, asset, username=None): @shared_task(queue="ansible") -def push_system_user_to_assets(system_user, assets, username=None): +def push_system_user_to_assets(system_user_id, assets_id, username=None): + system_user = SystemUser.objects.get(id=system_user_id) + assets = get_objects(Asset, assets_id) task_name = _("Push system users to assets: {}").format(system_user.name) - system_user = get_object_if_need(SystemUser, system_user) - assets = get_objects_if_need(Asset, assets) return push_system_user_util(system_user, assets, task_name, username=username) # @shared_task diff --git a/apps/common/db/utils.py b/apps/common/db/utils.py index b71b27906..e8b6f8872 100644 --- a/apps/common/db/utils.py +++ b/apps/common/db/utils.py @@ -25,3 +25,16 @@ def get_objects_if_need(model, pks): logger.error(f'DoesNotExist: <{model.__name__}: {not_found_pks}>') return objs return pks + + +def get_objects(model, pks): + if not pks: + return pks + + objs = list(model.objects.filter(id__in=pks)) + if len(objs) != len(pks): + pks = set(pks) + exists_pks = {o.id for o in objs} + not_found_pks = ','.join(pks - exists_pks) + logger.error(f'DoesNotExist: <{model.__name__}: {not_found_pks}>') + return objs