perf: 优化 account,去掉版本好

pull/9680/head
ibuler 2023-02-22 11:18:42 +08:00
parent b91b9ef39e
commit 4c233cfb69
9 changed files with 43 additions and 54 deletions

View File

@ -8,7 +8,7 @@ from django.utils import timezone
from openpyxl import Workbook from openpyxl import Workbook
from accounts.const import AutomationTypes, SecretType, SSHKeyStrategy, SecretStrategy from accounts.const import AutomationTypes, SecretType, SSHKeyStrategy, SecretStrategy
from accounts.models import ChangeSecretRecord from accounts.models import ChangeSecretRecord, Account
from accounts.notifications import ChangeSecretExecutionTaskMsg from accounts.notifications import ChangeSecretExecutionTaskMsg
from accounts.serializers import ChangeSecretRecordBackUpSerializer from accounts.serializers import ChangeSecretRecordBackUpSerializer
from assets.const import HostTypes from assets.const import HostTypes
@ -86,6 +86,10 @@ class ChangeSecretManager(AccountBasePlaybookManager):
accounts = accounts.filter(username__in=self.snapshot_account_usernames) accounts = accounts.filter(username__in=self.snapshot_account_usernames)
accounts = accounts.filter(secret_type=self.secret_type) accounts = accounts.filter(secret_type=self.secret_type)
if not accounts:
print('没有发现待改密账号: %s 用户名: %s 类型: %s' % (asset.name, account.username, self.secret_type))
return []
method_attr = getattr(automation, self.method_type() + '_method') method_attr = getattr(automation, self.method_type() + '_method')
method_hosts = self.method_hosts_mapper[method_attr] method_hosts = self.method_hosts_mapper[method_attr]
method_hosts = [h for h in method_hosts if h != host['name']] method_hosts = [h for h in method_hosts if h != host['name']]
@ -137,10 +141,12 @@ class ChangeSecretManager(AccountBasePlaybookManager):
recorder.status = 'success' recorder.status = 'success'
recorder.date_finished = timezone.now() recorder.date_finished = timezone.now()
recorder.save() recorder.save()
print('recorder.new_secret', recorder.new_secret) account = Account.objects.filter(id=recorder.account_id).first()
account = recorder.account if not account:
print("Account not found, deleted ?", recorder.account_id)
return
account.secret = recorder.new_secret account.secret = recorder.new_secret
account.save(update_fields=['secret']) account.save(update_fields=['secret', 'version'])
def on_host_error(self, host, error, result): def on_host_error(self, host, error, result):
recorder = self.name_recorder_mapper.get(host) recorder = self.name_recorder_mapper.get(host)

View File

@ -36,7 +36,7 @@ class PushAccountManager(ChangeSecretManager, AccountBasePlaybookManager):
def get_accounts(self, privilege_account, accounts: QuerySet): def get_accounts(self, privilege_account, accounts: QuerySet):
if not privilege_account: if not privilege_account:
logger.debug(f'not privilege account') print(f'not privilege account')
return [] return []
snapshot_account_usernames = self.execution.snapshot['accounts'] snapshot_account_usernames = self.execution.snapshot['accounts']
if '*' in snapshot_account_usernames: if '*' in snapshot_account_usernames:
@ -103,7 +103,7 @@ class PushAccountManager(ChangeSecretManager, AccountBasePlaybookManager):
if not account: if not account:
return return
account.secret = new_secret account.secret = new_secret
account.save(update_fields=['secret']) account.save(update_fields=['secret', 'version'])
def on_host_error(self, host, error, result): def on_host_error(self, host, error, result):
pass pass

View File

@ -1,17 +0,0 @@
# Generated by Django 3.2.14 on 2023-02-21 05:13
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0007_alter_account_options'),
]
operations = [
migrations.AlterModelOptions(
name='account',
options={'permissions': [('view_accountsecret', 'Can view asset account secret'), ('view_historyaccount', 'Can view asset history account'), ('view_historyaccountsecret', 'Can view asset history account secret'), ('verify_account', 'Can verify account'), ('push_account', 'Can push account')], 'verbose_name': 'Account'},
),
]

View File

@ -68,6 +68,9 @@ class Account(AbsConnectivity, BaseAccount):
('push_account', _('Can push account')), ('push_account', _('Can push account')),
] ]
def __str__(self):
return '{}'.format(self.username)
@lazyproperty @lazyproperty
def platform(self): def platform(self):
return self.asset.platform return self.asset.platform
@ -78,9 +81,6 @@ class Account(AbsConnectivity, BaseAccount):
return self.username return self.username
return self.name return self.name
def __str__(self):
return '{}'.format(self.username)
@lazyproperty @lazyproperty
def has_secret(self): def has_secret(self):
return bool(self.secret) return bool(self.secret)
@ -100,12 +100,11 @@ class Account(AbsConnectivity, BaseAccount):
return self.asset.accounts.exclude(id=self.id).exclude(su_from=self) return self.asset.accounts.exclude(id=self.id).exclude(su_from=self)
def secret_changed(self): def secret_changed(self):
history = self.history.first() pre_secret = self.history.exclude(version=self.version) \
if not history: .values_list('secret', flat=True) \
return True .first()
if history.secret != self.secret or history.secret_type != self.secret_type: print("Pre secret is: ", pre_secret)
return True return pre_secret != self.secret
return False
class AccountTemplate(BaseAccount): class AccountTemplate(BaseAccount):

View File

@ -43,7 +43,7 @@ class AccountSerializerCreateValidateMixin:
def push_account(instance, push_now): def push_account(instance, push_now):
if not push_now: if not push_now:
return return
push_accounts_to_assets_task.delay([instance.id], [instance.asset_id]) push_accounts_to_assets_task.delay([instance.id])
def create(self, validated_data): def create(self, validated_data):
push_now = validated_data.pop('push_now', None) push_now = validated_data.pop('push_now', None)
@ -102,7 +102,7 @@ class AccountSerializer(AccountSerializerCreateMixin, BaseAccountSerializer):
class Meta(BaseAccountSerializer.Meta): class Meta(BaseAccountSerializer.Meta):
model = Account model = Account
fields = BaseAccountSerializer.Meta.fields \ fields = BaseAccountSerializer.Meta.fields \
+ ['su_from', 'version', 'asset'] \ + ['su_from', 'asset'] \
+ ['template', 'push_now', 'source'] + ['template', 'push_now', 'source']
extra_kwargs = { extra_kwargs = {
**BaseAccountSerializer.Meta.extra_kwargs, **BaseAccountSerializer.Meta.extra_kwargs,

View File

@ -1,17 +1,17 @@
from django.db.models.signals import pre_save
from django.dispatch import receiver
from common.utils import get_logger from common.utils import get_logger
from .models import Account
logger = get_logger(__name__) logger = get_logger(__name__)
#
@receiver(pre_save, sender=Account) # @receiver(pre_save, sender=Account)
def on_account_pre_create(sender, instance, update_fields=(), **kwargs): # def on_account_pre_save(sender, instance, **kwargs):
# 这是创建时 # if instance.secret != instance.pre_secret:
if instance.version == 0 or instance.secret_changed(): # instance.pre_secret = instance.secret
instance.version += 1 #
#
# 即使在 root 组织也不怕 # @receiver(post_save, sender=Account)
instance.org_id = instance.asset.org_id # @on_transaction_commit
# def on_account_post_create(sender, instance, created=False, **kwargs):
# if created or instance.secret != instance.pre_secret:
# Account.objects.filter(id=instance.id) \
# .update(version=F('version') + 1)

View File

@ -205,9 +205,9 @@ class AssetTaskCreateApi(AssetsTaskMixin, generics.CreateAPIView):
asset_ids = [asset.id] asset_ids = [asset.id]
account_ids = accounts.values_list("id", flat=True) account_ids = accounts.values_list("id", flat=True)
if action == "push_account": if action == "push_account":
task = push_accounts_to_assets_task.delay(account_ids, asset_ids) task = push_accounts_to_assets_task.delay(account_ids)
elif action == "test_account": elif action == "test_account":
task = verify_accounts_connectivity_task.delay(account_ids, asset_ids) task = verify_accounts_connectivity_task.delay(account_ids)
else: else:
task = None task = None
return task return task

View File

@ -64,7 +64,7 @@ class BasePlaybookManager:
if not os.path.exists(path): if not os.path.exists(path):
os.makedirs(path, exist_ok=True, mode=0o755) os.makedirs(path, exist_ok=True, mode=0o755)
if settings.DEBUG_DEV: if settings.DEBUG_DEV:
logger.debug('Ansible runtime dir: {}'.format(path)) print(f'Ansible runtime dir:{path}')
return path return path
@staticmethod @staticmethod
@ -153,10 +153,9 @@ class BasePlaybookManager:
return sub_playbook_path return sub_playbook_path
def get_runners(self): def get_runners(self):
# TODO 临时打印一下 找一下打印不出日志的原因
print('ansible runner: 任务开始执行')
assets_group_by_platform = self.get_assets_group_by_platform() assets_group_by_platform = self.get_assets_group_by_platform()
print('ansible runner: 获取资产分组', assets_group_by_platform) if settings.DEBUG_DEV:
print("assets_group_by_platform: {}".format(assets_group_by_platform))
runners = [] runners = []
for platform, assets in assets_group_by_platform.items(): for platform, assets in assets_group_by_platform.items():
assets_bulked = [assets[i:i + self.bulk_size] for i in range(0, len(assets), self.bulk_size)] assets_bulked = [assets[i:i + self.bulk_size] for i in range(0, len(assets), self.bulk_size)]
@ -210,6 +209,7 @@ class BasePlaybookManager:
with open(path, 'r') as f: with open(path, 'r') as f:
d = json.load(f) d = json.load(f)
def delete_keys(d, keys_to_delete): def delete_keys(d, keys_to_delete):
""" """
递归函数删除嵌套字典中的指定键 递归函数删除嵌套字典中的指定键
@ -223,6 +223,7 @@ class BasePlaybookManager:
else: else:
delete_keys(d[key], keys_to_delete) delete_keys(d[key], keys_to_delete)
return d return d
d = delete_keys(d, ['secret', 'ansible_password']) d = delete_keys(d, ['secret', 'ansible_password'])
with open(path, 'w') as f: with open(path, 'w') as f:
json.dump(d, f) json.dump(d, f)

View File

@ -530,7 +530,7 @@ class Config(dict):
'PERIOD_TASK_ENABLED': True, 'PERIOD_TASK_ENABLED': True,
# 导航栏 帮助 # 导航栏 帮助
'HELP_DOCUMENT_URL': 'http://docs.jumpserver.org', 'HELP_DOCUMENT_URL': 'https://docs.jumpserver.org/zh/v3/',
'HELP_SUPPORT_URL': 'http://www.jumpserver.org/support/', 'HELP_SUPPORT_URL': 'http://www.jumpserver.org/support/',
'FORGOT_PASSWORD_URL': '', 'FORGOT_PASSWORD_URL': '',