mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-06-02 03:45:20 +00:00
perf: Create authorization to add template account Push account parameters
This commit is contained in:
parent
dcfc4e6e7b
commit
c92188887d
@ -81,21 +81,28 @@ class AccountCreateUpdateSerializerMixin(serializers.Serializer):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_template_attr_for_account(template):
|
def get_template_attr_for_account(template):
|
||||||
# Set initial data from template
|
|
||||||
field_names = [
|
field_names = [
|
||||||
'name', 'username', 'secret', 'push_params',
|
'name', 'username',
|
||||||
'secret_type', 'privileged', 'is_active'
|
'secret_type', 'secret',
|
||||||
|
'privileged', 'is_active'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
field_map = {
|
||||||
|
'push_params': 'params',
|
||||||
|
'auto_push': 'push_now'
|
||||||
|
}
|
||||||
|
|
||||||
|
field_names.extend(field_map.keys())
|
||||||
|
|
||||||
attrs = {}
|
attrs = {}
|
||||||
for name in field_names:
|
for name in field_names:
|
||||||
value = getattr(template, name, None)
|
value = getattr(template, name, None)
|
||||||
if value is None:
|
if value is None:
|
||||||
continue
|
continue
|
||||||
if name == 'push_params':
|
|
||||||
attrs['params'] = value
|
attr_name = field_map.get(name, name)
|
||||||
else:
|
attrs[attr_name] = value
|
||||||
attrs[name] = value
|
|
||||||
attrs['secret'] = template.get_secret()
|
attrs['secret'] = template.get_secret()
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
@ -178,6 +185,7 @@ class AccountCreateUpdateSerializerMixin(serializers.Serializer):
|
|||||||
params = validated_data.pop('params', None)
|
params = validated_data.pop('params', None)
|
||||||
self.clean_auth_fields(validated_data)
|
self.clean_auth_fields(validated_data)
|
||||||
instance, stat = self.do_create(validated_data)
|
instance, stat = self.do_create(validated_data)
|
||||||
|
if instance.source == Source.LOCAL:
|
||||||
self.push_account_if_need(instance, push_now, params, stat)
|
self.push_account_if_need(instance, push_now, params, stat)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
@ -280,8 +288,8 @@ class AssetAccountBulkSerializer(
|
|||||||
fields = [
|
fields = [
|
||||||
'name', 'username', 'secret', 'secret_type', 'passphrase',
|
'name', 'username', 'secret', 'secret_type', 'passphrase',
|
||||||
'privileged', 'is_active', 'comment', 'template',
|
'privileged', 'is_active', 'comment', 'template',
|
||||||
'on_invalid', 'push_now', 'assets', 'su_from_username',
|
'on_invalid', 'push_now', 'params', 'assets',
|
||||||
'source', 'source_id',
|
'su_from_username', 'source', 'source_id',
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'name': {'required': False},
|
'name': {'required': False},
|
||||||
@ -419,16 +427,23 @@ class AssetAccountBulkSerializer(
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def push_accounts_if_need(results, push_now):
|
def push_accounts_if_need(results, push_now, params):
|
||||||
if not push_now:
|
if not push_now:
|
||||||
return
|
return
|
||||||
accounts = [str(v['instance']) for v in results if v.get('instance')]
|
|
||||||
push_accounts_to_assets_task.delay(accounts)
|
account_ids = [v['instance'] for v in results if v.get('instance')]
|
||||||
|
accounts = Account.objects.filter(id__in=account_ids, source=Source.LOCAL)
|
||||||
|
if not accounts.exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
account_ids = [str(_id) for _id in accounts.values_list('id', flat=True)]
|
||||||
|
push_accounts_to_assets_task.delay(account_ids, params)
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
|
params = validated_data.pop('params', None)
|
||||||
push_now = validated_data.pop('push_now', False)
|
push_now = validated_data.pop('push_now', False)
|
||||||
results = self.perform_bulk_create(validated_data)
|
results = self.perform_bulk_create(validated_data)
|
||||||
self.push_accounts_if_need(results, push_now)
|
self.push_accounts_if_need(results, push_now, params)
|
||||||
for res in results:
|
for res in results:
|
||||||
res['asset'] = str(res['asset'])
|
res['asset'] = str(res['asset'])
|
||||||
return results
|
return results
|
||||||
|
@ -6,6 +6,7 @@ from django.dispatch import receiver
|
|||||||
from django.utils.translation import gettext_noop
|
from django.utils.translation import gettext_noop
|
||||||
|
|
||||||
from accounts.backends import vault_client
|
from accounts.backends import vault_client
|
||||||
|
from accounts.const import Source
|
||||||
from audits.const import ActivityChoices
|
from audits.const import ActivityChoices
|
||||||
from audits.signal_handlers import create_activities
|
from audits.signal_handlers import create_activities
|
||||||
from common.decorators import merge_delay_run
|
from common.decorators import merge_delay_run
|
||||||
@ -32,7 +33,7 @@ def push_accounts_if_need(accounts=()):
|
|||||||
template_accounts = defaultdict(list)
|
template_accounts = defaultdict(list)
|
||||||
for ac in accounts:
|
for ac in accounts:
|
||||||
# 再强调一次吧
|
# 再强调一次吧
|
||||||
if ac.source != 'template':
|
if ac.source != Source.TEMPLATE:
|
||||||
continue
|
continue
|
||||||
template_accounts[ac.source_id].append(ac)
|
template_accounts[ac.source_id].append(ac)
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ def create_accounts_activities(account, action='create'):
|
|||||||
|
|
||||||
@receiver(post_save, sender=Account)
|
@receiver(post_save, sender=Account)
|
||||||
def on_account_create_by_template(sender, instance, created=False, **kwargs):
|
def on_account_create_by_template(sender, instance, created=False, **kwargs):
|
||||||
if not created or instance.source != 'template':
|
if not created or instance.source != Source.TEMPLATE:
|
||||||
return
|
return
|
||||||
push_accounts_if_need.delay(accounts=(instance,))
|
push_accounts_if_need.delay(accounts=(instance,))
|
||||||
create_accounts_activities(instance, action='create')
|
create_accounts_activities(instance, action='create')
|
||||||
|
@ -6,7 +6,6 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
from accounts.const import Source
|
from accounts.const import Source
|
||||||
from accounts.models import AccountTemplate, Account
|
from accounts.models import AccountTemplate, Account
|
||||||
from accounts.tasks import push_accounts_to_assets_task
|
|
||||||
from assets.models import Asset, Node
|
from assets.models import Asset, Node
|
||||||
from common.serializers import ResourceLabelsMixin
|
from common.serializers import ResourceLabelsMixin
|
||||||
from common.serializers.fields import BitChoicesField, ObjectRelatedField
|
from common.serializers.fields import BitChoicesField, ObjectRelatedField
|
||||||
@ -84,44 +83,35 @@ class AssetPermissionSerializer(ResourceLabelsMixin, BulkOrgResourceModelSeriali
|
|||||||
return Asset.objects.filter(id__in=asset_ids)
|
return Asset.objects.filter(id__in=asset_ids)
|
||||||
|
|
||||||
def create_accounts(self, assets):
|
def create_accounts(self, assets):
|
||||||
need_create_accounts = []
|
account_objs = []
|
||||||
account_attribute = [
|
account_attribute = [
|
||||||
'name', 'username', 'secret_type', 'secret',
|
'name', 'username', 'secret_type', 'secret',
|
||||||
'privileged', 'is_active', 'org_id'
|
'privileged', 'is_active', 'org_id'
|
||||||
]
|
]
|
||||||
for asset in assets:
|
for asset in assets:
|
||||||
asset_exist_accounts = Account.objects.none()
|
asset_exist_account_names = set(asset.accounts.values_list('name', flat=True))
|
||||||
asset_exist_account_names = asset.accounts.values_list('name', flat=True)
|
|
||||||
|
asset_exist_accounts = asset.accounts.values('username', 'secret_type')
|
||||||
|
username_secret_type_set = {(acc['username'], acc['secret_type']) for acc in asset_exist_accounts}
|
||||||
for template in self.template_accounts:
|
for template in self.template_accounts:
|
||||||
asset_exist_accounts |= asset.accounts.filter(
|
condition = (template.username, template.secret_type)
|
||||||
username=template.username,
|
if condition in username_secret_type_set or template.name in asset_exist_account_names:
|
||||||
secret_type=template.secret_type,
|
|
||||||
)
|
|
||||||
username_secret_type_dict = asset_exist_accounts.values('username', 'secret_type')
|
|
||||||
for template in self.template_accounts:
|
|
||||||
condition = {
|
|
||||||
'username': template.username,
|
|
||||||
'secret_type': template.secret_type
|
|
||||||
}
|
|
||||||
if condition in username_secret_type_dict or \
|
|
||||||
template.name in asset_exist_account_names:
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
account_data = {key: getattr(template, key) for key in account_attribute}
|
account_data = {key: getattr(template, key) for key in account_attribute}
|
||||||
account_data['su_from'] = template.get_su_from_account(asset)
|
account_data['su_from'] = template.get_su_from_account(asset)
|
||||||
account_data['source'] = Source.TEMPLATE
|
account_data['source'] = Source.TEMPLATE
|
||||||
account_data['source_id'] = str(template.id)
|
account_data['source_id'] = str(template.id)
|
||||||
need_create_accounts.append(Account(**{'asset_id': asset.id, **account_data}))
|
account_objs.append(Account(asset=asset, **account_data))
|
||||||
return Account.objects.bulk_create(need_create_accounts)
|
|
||||||
|
|
||||||
def create_and_push_account(self, nodes, assets):
|
if account_objs:
|
||||||
|
Account.objects.bulk_create(account_objs)
|
||||||
|
|
||||||
|
def create_account_through_template(self, nodes, assets):
|
||||||
if not self.template_accounts:
|
if not self.template_accounts:
|
||||||
return
|
return
|
||||||
assets = self.get_all_assets(nodes, assets)
|
assets = self.get_all_assets(nodes, assets)
|
||||||
accounts = self.create_accounts(assets)
|
self.create_accounts(assets)
|
||||||
account_ids = [str(account.id) for account in accounts]
|
|
||||||
slice_count = 20
|
|
||||||
for i in range(0, len(account_ids), slice_count):
|
|
||||||
push_accounts_to_assets_task.delay(account_ids[i:i + slice_count])
|
|
||||||
|
|
||||||
def validate_accounts(self, usernames):
|
def validate_accounts(self, usernames):
|
||||||
template_ids = []
|
template_ids = []
|
||||||
@ -169,7 +159,7 @@ class AssetPermissionSerializer(ResourceLabelsMixin, BulkOrgResourceModelSeriali
|
|||||||
instance.nodes.add(*nodes_to_set)
|
instance.nodes.add(*nodes_to_set)
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
self.create_and_push_account(
|
self.create_account_through_template(
|
||||||
attrs.get("nodes", []),
|
attrs.get("nodes", []),
|
||||||
attrs.get("assets", [])
|
attrs.get("assets", [])
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user