mirror of https://github.com/jumpserver/jumpserver
perf: Change secret record
parent
cfbd162890
commit
00f6c3a5de
|
@ -37,7 +37,7 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
|
||||||
)
|
)
|
||||||
self.account_ids = self.execution.snapshot['accounts']
|
self.account_ids = self.execution.snapshot['accounts']
|
||||||
self.record_map = self.execution.snapshot.get('record_map', {}) # 这个是某个失败的记录重试
|
self.record_map = self.execution.snapshot.get('record_map', {}) # 这个是某个失败的记录重试
|
||||||
self.name_recorder_mapper = {} # 做个映射,方便后面处理
|
self.name_record_mapper = {} # 做个映射,方便后面处理
|
||||||
|
|
||||||
def gen_account_inventory(self, account, asset, h, path_dir):
|
def gen_account_inventory(self, account, asset, h, path_dir):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -113,7 +113,6 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
|
||||||
if host.get('error'):
|
if host.get('error'):
|
||||||
return host
|
return host
|
||||||
|
|
||||||
host['check_conn_after_change'] = self.execution.snapshot.get('check_conn_after_change', True)
|
|
||||||
host['ssh_params'] = {}
|
host['ssh_params'] = {}
|
||||||
|
|
||||||
accounts = self.get_accounts(account)
|
accounts = self.get_accounts(account)
|
||||||
|
@ -147,7 +146,8 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
h = self.gen_account_inventory(account, asset, h, path_dir)
|
h, record = self.gen_account_inventory(account, asset, h, path_dir)
|
||||||
|
h['check_conn_after_change'] = record.execution.snapshot.get('check_conn_after_change', True)
|
||||||
account_secret_task_status.set_status(
|
account_secret_task_status.set_status(
|
||||||
account.id,
|
account.id,
|
||||||
ChangeSecretAccountStatus.PROCESSING,
|
ChangeSecretAccountStatus.PROCESSING,
|
||||||
|
@ -162,26 +162,26 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
|
||||||
return inventory_hosts
|
return inventory_hosts
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def save_record(recorder):
|
def save_record(record):
|
||||||
recorder.save(update_fields=['error', 'status', 'date_finished'])
|
record.save(update_fields=['error', 'status', 'date_finished'])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def clear_account_queue_status(account_id):
|
def clear_account_queue_status(account_id):
|
||||||
account_secret_task_status.clear(account_id)
|
account_secret_task_status.clear(account_id)
|
||||||
|
|
||||||
def on_host_success(self, host, result):
|
def on_host_success(self, host, result):
|
||||||
recorder = self.name_recorder_mapper.get(host)
|
record = self.name_record_mapper.get(host)
|
||||||
if not recorder:
|
if not record:
|
||||||
return
|
return
|
||||||
recorder.status = ChangeSecretRecordStatusChoice.success.value
|
record.status = ChangeSecretRecordStatusChoice.success.value
|
||||||
recorder.date_finished = timezone.now()
|
record.date_finished = timezone.now()
|
||||||
|
|
||||||
account = recorder.account
|
account = record.account
|
||||||
if not account:
|
if not account:
|
||||||
print("Account not found, deleted ?")
|
print("Account not found, deleted ?")
|
||||||
return
|
return
|
||||||
|
|
||||||
account.secret = getattr(recorder, 'new_secret', account.secret)
|
account.secret = getattr(record, 'new_secret', account.secret)
|
||||||
account.date_updated = timezone.now()
|
account.date_updated = timezone.now()
|
||||||
account.date_change_secret = timezone.now()
|
account.date_change_secret = timezone.now()
|
||||||
account.change_secret_status = ChangeSecretRecordStatusChoice.success
|
account.change_secret_status = ChangeSecretRecordStatusChoice.success
|
||||||
|
@ -197,17 +197,17 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
|
||||||
|
|
||||||
with safe_atomic_db_connection():
|
with safe_atomic_db_connection():
|
||||||
account.save(update_fields=['secret', 'date_updated', 'date_change_secret', 'change_secret_status'])
|
account.save(update_fields=['secret', 'date_updated', 'date_change_secret', 'change_secret_status'])
|
||||||
self.save_record(recorder)
|
self.save_record(record)
|
||||||
self.clear_account_queue_status(account.id)
|
self.clear_account_queue_status(account.id)
|
||||||
|
|
||||||
def on_host_error(self, host, error, result):
|
def on_host_error(self, host, error, result):
|
||||||
recorder = self.name_recorder_mapper.get(host)
|
record = self.name_record_mapper.get(host)
|
||||||
if not recorder:
|
if not record:
|
||||||
return
|
return
|
||||||
recorder.status = ChangeSecretRecordStatusChoice.failed.value
|
record.status = ChangeSecretRecordStatusChoice.failed.value
|
||||||
recorder.date_finished = timezone.now()
|
record.date_finished = timezone.now()
|
||||||
recorder.error = error
|
record.error = error
|
||||||
account = recorder.account
|
account = record.account
|
||||||
if not account:
|
if not account:
|
||||||
print("Account not found, deleted ?")
|
print("Account not found, deleted ?")
|
||||||
return
|
return
|
||||||
|
@ -218,13 +218,13 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
|
||||||
self.summary['fail_accounts'] += 1
|
self.summary['fail_accounts'] += 1
|
||||||
self.result['fail_accounts'].append(
|
self.result['fail_accounts'].append(
|
||||||
{
|
{
|
||||||
"asset": str(recorder.asset),
|
"asset": str(record.asset),
|
||||||
"username": recorder.account.username,
|
"username": record.account.username,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
super().on_host_error(host, error, result)
|
super().on_host_error(host, error, result)
|
||||||
|
|
||||||
with safe_atomic_db_connection():
|
with safe_atomic_db_connection():
|
||||||
account.save(update_fields=['change_secret_status', 'date_change_secret', 'date_updated'])
|
account.save(update_fields=['change_secret_status', 'date_change_secret', 'date_updated'])
|
||||||
self.save_record(recorder)
|
self.save_record(record)
|
||||||
self.clear_account_queue_status(account.id)
|
self.clear_account_queue_status(account.id)
|
||||||
|
|
|
@ -30,28 +30,28 @@ class ChangeSecretManager(BaseChangeSecretPushManager):
|
||||||
record = self.get_or_create_record(asset, account, h['name'])
|
record = self.get_or_create_record(asset, account, h['name'])
|
||||||
new_secret, private_key_path = self.handle_ssh_secret(account.secret_type, record.new_secret, path_dir)
|
new_secret, private_key_path = self.handle_ssh_secret(account.secret_type, record.new_secret, path_dir)
|
||||||
h = self.gen_inventory(h, account, new_secret, private_key_path, asset)
|
h = self.gen_inventory(h, account, new_secret, private_key_path, asset)
|
||||||
return h
|
return h, record
|
||||||
|
|
||||||
def get_or_create_record(self, asset, account, name):
|
def get_or_create_record(self, asset, account, name):
|
||||||
asset_account_id = f'{asset.id}-{account.id}'
|
asset_account_id = f'{asset.id}-{account.id}'
|
||||||
|
|
||||||
if asset_account_id in self.record_map:
|
if asset_account_id in self.record_map:
|
||||||
record_id = self.record_map[asset_account_id]
|
record_id = self.record_map[asset_account_id]
|
||||||
recorder = ChangeSecretRecord.objects.filter(id=record_id).first()
|
record = ChangeSecretRecord.objects.filter(id=record_id).first()
|
||||||
else:
|
else:
|
||||||
new_secret = self.get_secret(account)
|
new_secret = self.get_secret(account)
|
||||||
recorder = self.create_record(asset, account, new_secret)
|
record = self.create_record(asset, account, new_secret)
|
||||||
|
|
||||||
self.name_recorder_mapper[name] = recorder
|
self.name_record_mapper[name] = record
|
||||||
return recorder
|
return record
|
||||||
|
|
||||||
def create_record(self, asset, account, new_secret):
|
def create_record(self, asset, account, new_secret):
|
||||||
recorder = ChangeSecretRecord(
|
record = ChangeSecretRecord(
|
||||||
asset=asset, account=account, execution=self.execution,
|
asset=asset, account=account, execution=self.execution,
|
||||||
old_secret=account.secret, new_secret=new_secret,
|
old_secret=account.secret, new_secret=new_secret,
|
||||||
comment=f'{account.username}@{asset.address}'
|
comment=f'{account.username}@{asset.address}'
|
||||||
)
|
)
|
||||||
return recorder
|
return record
|
||||||
|
|
||||||
def check_secret(self):
|
def check_secret(self):
|
||||||
if self.secret_strategy == SecretStrategy.custom \
|
if self.secret_strategy == SecretStrategy.custom \
|
||||||
|
@ -61,10 +61,10 @@ class ChangeSecretManager(BaseChangeSecretPushManager):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_summary(recorders):
|
def get_summary(records):
|
||||||
total, succeed, failed = 0, 0, 0
|
total, succeed, failed = 0, 0, 0
|
||||||
for recorder in recorders:
|
for record in records:
|
||||||
if recorder.status == ChangeSecretRecordStatusChoice.success.value:
|
if record.status == ChangeSecretRecordStatusChoice.success.value:
|
||||||
succeed += 1
|
succeed += 1
|
||||||
else:
|
else:
|
||||||
failed += 1
|
failed += 1
|
||||||
|
@ -73,8 +73,8 @@ class ChangeSecretManager(BaseChangeSecretPushManager):
|
||||||
return summary
|
return summary
|
||||||
|
|
||||||
def print_summary(self):
|
def print_summary(self):
|
||||||
recorders = list(self.name_recorder_mapper.values())
|
records = list(self.name_record_mapper.values())
|
||||||
summary = self.get_summary(recorders)
|
summary = self.get_summary(records)
|
||||||
print('\n\n' + '-' * 80)
|
print('\n\n' + '-' * 80)
|
||||||
plan_execution_end = _('Plan execution end')
|
plan_execution_end = _('Plan execution end')
|
||||||
print('{} {}\n'.format(plan_execution_end, local_now_filename()))
|
print('{} {}\n'.format(plan_execution_end, local_now_filename()))
|
||||||
|
@ -86,7 +86,7 @@ class ChangeSecretManager(BaseChangeSecretPushManager):
|
||||||
if self.secret_type and not self.check_secret():
|
if self.secret_type and not self.check_secret():
|
||||||
return
|
return
|
||||||
|
|
||||||
recorders = list(self.name_recorder_mapper.values())
|
records = list(self.name_record_mapper.values())
|
||||||
if self.record_map:
|
if self.record_map:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -98,17 +98,17 @@ class ChangeSecretManager(BaseChangeSecretPushManager):
|
||||||
for user in recipients:
|
for user in recipients:
|
||||||
ChangeSecretReportMsg(user, context).publish()
|
ChangeSecretReportMsg(user, context).publish()
|
||||||
|
|
||||||
if not recorders:
|
if not records:
|
||||||
return
|
return
|
||||||
|
|
||||||
summary = self.get_summary(recorders)
|
summary = self.get_summary(records)
|
||||||
self.send_recorder_mail(recipients, recorders, summary)
|
self.send_record_mail(recipients, records, summary)
|
||||||
|
|
||||||
def send_recorder_mail(self, recipients, recorders, summary):
|
def send_record_mail(self, recipients, records, summary):
|
||||||
name = self.execution.snapshot['name']
|
name = self.execution.snapshot['name']
|
||||||
path = os.path.join(os.path.dirname(settings.BASE_DIR), 'tmp')
|
path = os.path.join(os.path.dirname(settings.BASE_DIR), 'tmp')
|
||||||
filename = os.path.join(path, f'{name}-{local_now_filename()}-{time.time()}.xlsx')
|
filename = os.path.join(path, f'{name}-{local_now_filename()}-{time.time()}.xlsx')
|
||||||
if not self.create_file(recorders, filename):
|
if not self.create_file(records, filename):
|
||||||
return
|
return
|
||||||
|
|
||||||
for user in recipients:
|
for user in recipients:
|
||||||
|
@ -121,9 +121,9 @@ class ChangeSecretManager(BaseChangeSecretPushManager):
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_file(recorders, filename):
|
def create_file(records, filename):
|
||||||
serializer_cls = ChangeSecretRecordBackUpSerializer
|
serializer_cls = ChangeSecretRecordBackUpSerializer
|
||||||
serializer = serializer_cls(recorders, many=True)
|
serializer = serializer_cls(records, many=True)
|
||||||
|
|
||||||
header = [str(v.label) for v in serializer.child.fields.values()]
|
header = [str(v.label) for v in serializer.child.fields.values()]
|
||||||
rows = [[str(i) for i in row.values()] for row in serializer.data]
|
rows = [[str(i) for i in row.values()] for row in serializer.data]
|
||||||
|
|
|
@ -12,7 +12,7 @@ logger = get_logger(__name__)
|
||||||
class PushAccountManager(BaseChangeSecretPushManager):
|
class PushAccountManager(BaseChangeSecretPushManager):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def require_update_version(account, recorder):
|
def require_update_version(account, record):
|
||||||
account.skip_history_when_saving = True
|
account.skip_history_when_saving = True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -31,29 +31,29 @@ class PushAccountManager(BaseChangeSecretPushManager):
|
||||||
secret_type = account.secret_type
|
secret_type = account.secret_type
|
||||||
if not secret:
|
if not secret:
|
||||||
raise ValueError(_('Secret cannot be empty'))
|
raise ValueError(_('Secret cannot be empty'))
|
||||||
self.get_or_create_record(asset, account, h['name'])
|
record = self.get_or_create_record(asset, account, h['name'])
|
||||||
new_secret, private_key_path = self.handle_ssh_secret(secret_type, secret, path_dir)
|
new_secret, private_key_path = self.handle_ssh_secret(secret_type, secret, path_dir)
|
||||||
h = self.gen_inventory(h, account, new_secret, private_key_path, asset)
|
h = self.gen_inventory(h, account, new_secret, private_key_path, asset)
|
||||||
return h
|
return h, record
|
||||||
|
|
||||||
def get_or_create_record(self, asset, account, name):
|
def get_or_create_record(self, asset, account, name):
|
||||||
asset_account_id = f'{asset.id}-{account.id}'
|
asset_account_id = f'{asset.id}-{account.id}'
|
||||||
|
|
||||||
if asset_account_id in self.record_map:
|
if asset_account_id in self.record_map:
|
||||||
record_id = self.record_map[asset_account_id]
|
record_id = self.record_map[asset_account_id]
|
||||||
recorder = PushSecretRecord.objects.filter(id=record_id).first()
|
record = PushSecretRecord.objects.filter(id=record_id).first()
|
||||||
else:
|
else:
|
||||||
recorder = self.create_record(asset, account)
|
record = self.create_record(asset, account)
|
||||||
|
|
||||||
self.name_recorder_mapper[name] = recorder
|
self.name_record_mapper[name] = record
|
||||||
return recorder
|
return record
|
||||||
|
|
||||||
def create_record(self, asset, account):
|
def create_record(self, asset, account):
|
||||||
recorder = PushSecretRecord(
|
record = PushSecretRecord(
|
||||||
asset=asset, account=account, execution=self.execution,
|
asset=asset, account=account, execution=self.execution,
|
||||||
comment=f'{account.username}@{asset.address}'
|
comment=f'{account.username}@{asset.address}'
|
||||||
)
|
)
|
||||||
return recorder
|
return record
|
||||||
|
|
||||||
def print_summary(self):
|
def print_summary(self):
|
||||||
print('\n\n' + '-' * 80)
|
print('\n\n' + '-' * 80)
|
||||||
|
|
Loading…
Reference in New Issue