mirror of https://github.com/jumpserver/jumpserver
[Update] 优化创建AuthBook逻辑;添加锁机制(基于redis-lock);
parent
a09b0c6c06
commit
4503df910d
|
@ -154,8 +154,8 @@ class AssetUserManager:
|
|||
|
||||
@staticmethod
|
||||
def create(**kwargs):
|
||||
authbook = AuthBook(**kwargs)
|
||||
authbook.save()
|
||||
# 使用create方法创建AuthBook对象,解决并发创建问题(添加锁机制)
|
||||
authbook = AuthBook.objects.create(**kwargs)
|
||||
return authbook
|
||||
|
||||
def __getattr__(self, item):
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Max
|
||||
from django.core.cache import cache
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orgs.mixins.models import OrgManager
|
||||
|
@ -11,12 +13,30 @@ __all__ = ['AuthBook']
|
|||
|
||||
|
||||
class AuthBookQuerySet(models.QuerySet):
|
||||
def latest_version(self):
|
||||
return self.filter(is_latest=True)
|
||||
def delete(self):
|
||||
raise PermissionError("Bulk delete authbook deny")
|
||||
|
||||
|
||||
class AuthBookManager(OrgManager):
|
||||
pass
|
||||
|
||||
def get_max_version(self, username, asset):
|
||||
version_max = self.filter(username=username, asset=asset)\
|
||||
.aggregate(Max('version'))
|
||||
version_max = version_max['version__max'] or 0
|
||||
return version_max
|
||||
|
||||
def create(self, **kwargs):
|
||||
username = kwargs['username']
|
||||
asset = kwargs['asset']
|
||||
key_lock = 'KEY_LOCK_CREATE_AUTH_BOOK_{}_{}'.format(username, asset.id)
|
||||
with cache.lock(key_lock, expire=60):
|
||||
self.filter(username=username, asset=asset, is_latest=True)\
|
||||
.update(is_latest=False)
|
||||
max_version = self.get_max_version(username, asset)
|
||||
kwargs['version'] = max_version + 1
|
||||
kwargs['is_latest'] = True
|
||||
obj = super().create(**kwargs)
|
||||
return obj
|
||||
|
||||
|
||||
class AuthBook(BaseUser):
|
||||
|
@ -33,31 +53,6 @@ class AuthBook(BaseUser):
|
|||
class Meta:
|
||||
verbose_name = _('AuthBook')
|
||||
|
||||
def set_to_latest(self):
|
||||
self.remove_pre_latest()
|
||||
self.is_latest = True
|
||||
self.save()
|
||||
|
||||
def get_pre_latest(self):
|
||||
pre_obj = self.__class__.objects.filter(
|
||||
username=self.username, asset=self.asset
|
||||
).latest_version().first()
|
||||
return pre_obj
|
||||
|
||||
def remove_pre_latest(self):
|
||||
pre_obj = self.get_pre_latest()
|
||||
if pre_obj:
|
||||
pre_obj.is_latest = False
|
||||
pre_obj.save()
|
||||
|
||||
def set_version(self):
|
||||
pre_obj = self.get_pre_latest()
|
||||
if pre_obj:
|
||||
self.version = pre_obj.version + 1
|
||||
else:
|
||||
self.version = 1
|
||||
self.save()
|
||||
|
||||
def get_related_assets(self):
|
||||
return [self.asset]
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ class AssetUserWriteSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializ
|
|||
if not validated_data.get("name") and validated_data.get("username"):
|
||||
validated_data["name"] = validated_data["username"]
|
||||
instance = AssetUserManager.create(**validated_data)
|
||||
instance.set_to_latest()
|
||||
return instance
|
||||
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ from .utils import TreeService
|
|||
from .tasks import (
|
||||
update_assets_hardware_info_util,
|
||||
test_asset_connectivity_util,
|
||||
push_system_user_to_assets,
|
||||
push_system_user_to_assets_manual,
|
||||
push_system_user_to_assets,
|
||||
add_nodes_assets_to_system_users
|
||||
|
@ -235,9 +234,3 @@ def on_node_update_or_created(sender, **kwargs):
|
|||
Node.refresh_nodes()
|
||||
with tmp_to_root_org():
|
||||
Node.refresh_nodes()
|
||||
|
||||
|
||||
@receiver(post_save, sender=AuthBook)
|
||||
def on_authbook_created(sender, instance=None, created=True, **kwargs):
|
||||
if created and instance:
|
||||
instance.set_version()
|
||||
|
|
|
@ -232,7 +232,8 @@ FILE_UPLOAD_DIRECTORY_PERMISSIONS = 0o755
|
|||
# Cache use redis
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'redis_cache.RedisCache',
|
||||
# 'BACKEND': 'redis_cache.RedisCache',
|
||||
'BACKEND': 'redis_lock.django_cache.RedisCache',
|
||||
'LOCATION': 'redis://:%(password)s@%(host)s:%(port)s/%(db)s' % {
|
||||
'password': CONFIG.REDIS_PASSWORD,
|
||||
'host': CONFIG.REDIS_HOST,
|
||||
|
|
|
@ -96,3 +96,5 @@ django-cas-ng==4.0.1
|
|||
python-cas==1.5.0
|
||||
ipython
|
||||
huaweicloud-sdk-python==1.0.21
|
||||
django-redis==4.11.0
|
||||
python-redis-lock==3.5.0
|
||||
|
|
Loading…
Reference in New Issue