mirror of https://github.com/jumpserver/jumpserver
perf: 优化 account,去掉版本好
parent
b91b9ef39e
commit
4c233cfb69
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'},
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -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):
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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': '',
|
||||||
|
|
Loading…
Reference in New Issue