mirror of https://github.com/jumpserver/jumpserver
Merge pull request #3822 from jumpserver/dev_lock
[Update] 优化创建AuthBook逻辑;添加锁机制(基于redis-lock);pull/3829/head
commit
42a6feb35e
|
@ -154,8 +154,8 @@ class AssetUserManager:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(**kwargs):
|
def create(**kwargs):
|
||||||
authbook = AuthBook(**kwargs)
|
# 使用create方法创建AuthBook对象,解决并发创建问题(添加锁机制)
|
||||||
authbook.save()
|
authbook = AuthBook.objects.create(**kwargs)
|
||||||
return authbook
|
return authbook
|
||||||
|
|
||||||
def __getattr__(self, item):
|
def __getattr__(self, item):
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.db import models
|
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 django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orgs.mixins.models import OrgManager
|
from orgs.mixins.models import OrgManager
|
||||||
|
@ -11,12 +13,30 @@ __all__ = ['AuthBook']
|
||||||
|
|
||||||
|
|
||||||
class AuthBookQuerySet(models.QuerySet):
|
class AuthBookQuerySet(models.QuerySet):
|
||||||
def latest_version(self):
|
def delete(self):
|
||||||
return self.filter(is_latest=True)
|
raise PermissionError("Bulk delete authbook deny")
|
||||||
|
|
||||||
|
|
||||||
class AuthBookManager(OrgManager):
|
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):
|
class AuthBook(BaseUser):
|
||||||
|
@ -33,31 +53,6 @@ class AuthBook(BaseUser):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('AuthBook')
|
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):
|
def get_related_assets(self):
|
||||||
return [self.asset]
|
return [self.asset]
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ class AssetUserWriteSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializ
|
||||||
if not validated_data.get("name") and validated_data.get("username"):
|
if not validated_data.get("name") and validated_data.get("username"):
|
||||||
validated_data["name"] = validated_data["username"]
|
validated_data["name"] = validated_data["username"]
|
||||||
instance = AssetUserManager.create(**validated_data)
|
instance = AssetUserManager.create(**validated_data)
|
||||||
instance.set_to_latest()
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ from .utils import TreeService
|
||||||
from .tasks import (
|
from .tasks import (
|
||||||
update_assets_hardware_info_util,
|
update_assets_hardware_info_util,
|
||||||
test_asset_connectivity_util,
|
test_asset_connectivity_util,
|
||||||
push_system_user_to_assets,
|
|
||||||
push_system_user_to_assets_manual,
|
push_system_user_to_assets_manual,
|
||||||
push_system_user_to_assets,
|
push_system_user_to_assets,
|
||||||
add_nodes_assets_to_system_users
|
add_nodes_assets_to_system_users
|
||||||
|
@ -235,9 +234,3 @@ def on_node_update_or_created(sender, **kwargs):
|
||||||
Node.refresh_nodes()
|
Node.refresh_nodes()
|
||||||
with tmp_to_root_org():
|
with tmp_to_root_org():
|
||||||
Node.refresh_nodes()
|
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
|
# Cache use redis
|
||||||
CACHES = {
|
CACHES = {
|
||||||
'default': {
|
'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' % {
|
'LOCATION': 'redis://:%(password)s@%(host)s:%(port)s/%(db)s' % {
|
||||||
'password': CONFIG.REDIS_PASSWORD,
|
'password': CONFIG.REDIS_PASSWORD,
|
||||||
'host': CONFIG.REDIS_HOST,
|
'host': CONFIG.REDIS_HOST,
|
||||||
|
|
|
@ -96,3 +96,5 @@ django-cas-ng==4.0.1
|
||||||
python-cas==1.5.0
|
python-cas==1.5.0
|
||||||
ipython
|
ipython
|
||||||
huaweicloud-sdk-python==1.0.21
|
huaweicloud-sdk-python==1.0.21
|
||||||
|
django-redis==4.11.0
|
||||||
|
python-redis-lock==3.5.0
|
||||||
|
|
Loading…
Reference in New Issue