diff --git a/apps/assets/migrations/0093_auto_20220711_1413.py b/apps/assets/migrations/0093_auto_20220711_1413.py index ecb4b47e6..ba7d7e0c0 100644 --- a/apps/assets/migrations/0093_auto_20220711_1413.py +++ b/apps/assets/migrations/0093_auto_20220711_1413.py @@ -39,6 +39,7 @@ def migrate_accounts(apps, schema_editor): values.update({attr: getattr(system_user, attr) for attr in auth_attrs}) values['protocol'] = system_user.protocol values['created_by'] = str(system_user.id) + values['type'] = system_user.type auth_book_auth = {attr: getattr(auth_book, attr) for attr in auth_attrs} auth_book_auth = {attr: value for attr, value in auth_book_auth.items() if value} diff --git a/apps/assets/migrations/0096_auto_20220714_1627.py b/apps/assets/migrations/0096_auto_20220714_1627.py new file mode 100644 index 000000000..4637128ff --- /dev/null +++ b/apps/assets/migrations/0096_auto_20220714_1627.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.12 on 2022-07-14 08:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0095_auto_20220713_1746'), + ] + + operations = [ + migrations.RenameField( + model_name='systemuser', + old_name='auto_push', + new_name='auto_push_account', + ), + migrations.AddField( + model_name='systemuser', + name='auto_create_account', + field=models.BooleanField(default=False, verbose_name='Auto account if not exist'), + ), + ] diff --git a/apps/assets/models/account.py b/apps/assets/models/account.py index d060ec40d..9d503c99b 100644 --- a/apps/assets/models/account.py +++ b/apps/assets/models/account.py @@ -32,4 +32,4 @@ class Account(BaseUser, AbsConnectivity, ProtocolMixin): ] def __str__(self): - return '{}//{}@{}'.format(self.protocol, self.username, self.asset.hostname) + return '{}://{}@{}'.format(self.protocol, self.username, self.asset.hostname) diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index 7dde0862f..157895dae 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -238,16 +238,6 @@ class Asset(AbsConnectivity, AbsHardwareInfo, ProtocolsMixin, NodesRelationMixin def get_target_ip(self): return self.ip - def set_admin_user_relation(self): - from .authbook import AuthBook - if not self.admin_user: - return - if self.admin_user.type != 'admin': - raise ValidationError('System user should be type admin') - - defaults = {'asset': self, 'systemuser': self.admin_user, 'org_id': self.org_id} - AuthBook.objects.get_or_create(defaults=defaults, asset=self, systemuser=self.admin_user) - @property def admin_user_display(self): if not self.admin_user: diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index 29f7b5972..bfa4dd3af 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -7,12 +7,10 @@ import logging from django.db import models from django.utils.translation import ugettext_lazy as _ from django.core.validators import MinValueValidator, MaxValueValidator -from django.core.cache import cache -from common.utils import signer, get_object_or_none +from common.utils import signer from .base import BaseUser from .asset import Asset -from .authbook import AuthBook __all__ = ['AdminUser', 'SystemUser', 'ProtocolMixin'] @@ -82,155 +80,11 @@ class ProtocolMixin: return self.protocol in self.ASSET_CATEGORY_PROTOCOLS -class AuthMixin: - username_same_with_user: bool - protocol: str - ASSET_CATEGORY_PROTOCOLS: list - login_mode: str - LOGIN_MANUAL: str - id: str - username: str - password: str - private_key: str - public_key: str - - def set_temp_auth(self, asset_or_app_id, user_id, auth, ttl=300): - if not auth: - raise ValueError('Auth not set') - key = 'TEMP_PASSWORD_{}_{}_{}'.format(self.id, asset_or_app_id, user_id) - logger.debug(f'Set system user temp auth: {key}') - cache.set(key, auth, ttl) - - def get_temp_auth(self, asset_or_app_id, user_id): - key = 'TEMP_PASSWORD_{}_{}_{}'.format(self.id, asset_or_app_id, user_id) - logger.debug(f'Get system user temp auth: {key}') - password = cache.get(key) - return password - - def _clean_auth_info_if_manual_login_mode(self): - if self.login_mode == self.LOGIN_MANUAL: - self.password = '' - self.private_key = '' - self.public_key = '' - - def _load_tmp_auth_if_has(self, asset_or_app_id, user_id): - if self.login_mode != self.LOGIN_MANUAL: - return - - if not asset_or_app_id or not user_id: - return - - auth = self.get_temp_auth(asset_or_app_id, user_id) - if not auth: - return - - username = auth.get('username') - password = auth.get('password') - - if username: - self.username = username - if password: - self.password = password - - def load_app_more_auth(self, app_id=None, username=None, user_id=None): - # 清除认证信息 - self._clean_auth_info_if_manual_login_mode() - - # 先加载临时认证信息 - if self.login_mode == self.LOGIN_MANUAL: - self._load_tmp_auth_if_has(app_id, user_id) - return - - # Remote app - from applications.models import Application - app = get_object_or_none(Application, pk=app_id) - if app and app.category_remote_app: - # Remote app - self._load_remoteapp_more_auth(app, username, user_id) - return - - # Other app - # 更新用户名 - from users.models import User - user = get_object_or_none(User, pk=user_id) if user_id else None - if self.username_same_with_user: - if user and not username: - _username = user.username - else: - _username = username - self.username = _username - - def _load_remoteapp_more_auth(self, app, username, user_id): - asset = app.get_remote_app_asset(raise_exception=False) - if asset: - self.load_asset_more_auth(asset_id=asset.id, username=username, user_id=user_id) - - def load_asset_special_auth(self, asset, username=''): - """ - AuthBook 的数据状态 - | asset | systemuser | username | - 1 | * | * | x | - 2 | * | x | * | - - 当前 AuthBook 只有以上两种状态,systemuser 与 username 不会并存。 - 正常的资产与系统用户关联产生的是第1种状态,改密则产生第2种状态。改密之后 - 只有 username 而没有 systemuser 。 - - Freq: 关联同一资产的多个系统用户指定同一用户名时,修改用户密码会影响所有系统用户 - - 这里有一个不对称的行为,同名系统用户密码覆盖 - 当有相同 username 的多个系统用户时,有改密动作之后,所有的同名系统用户都使用最后 - 一次改动,但如果没有发生过改密,同名系统用户使用的密码还是各自的。 - - """ - if username == '': - username = self.username - - authbook = AuthBook.objects.filter( - asset=asset, username=username, systemuser__isnull=True - ).order_by('-date_created').first() - - if not authbook: - authbook = AuthBook.objects.filter( - asset=asset, systemuser=self - ).order_by('-date_created').first() - - if not authbook: - return None - - authbook.load_auth() - self.password = authbook.password - self.private_key = authbook.private_key - self.public_key = authbook.public_key - - def load_asset_more_auth(self, asset_id=None, username=None, user_id=None): - from users.models import User - self._clean_auth_info_if_manual_login_mode() - # 加载临时认证信息 - if self.login_mode == self.LOGIN_MANUAL: - self._load_tmp_auth_if_has(asset_id, user_id) - return - # 更新用户名 - user = get_object_or_none(User, pk=user_id) if user_id else None - if self.username_same_with_user: - if user and not username: - _username = user.username - else: - _username = username - self.username = _username - # 加载某个资产的特殊配置认证信息 - asset = get_object_or_none(Asset, pk=asset_id) if asset_id else None - if not asset: - logger.debug('Asset not found, pass') - return - self.load_asset_special_auth(asset, self.username) - - -class SystemUser(ProtocolMixin, AuthMixin, BaseUser): +class SystemUser(ProtocolMixin, BaseUser): LOGIN_AUTO = 'auto' LOGIN_MANUAL = 'manual' LOGIN_MODE_CHOICES = ( - (LOGIN_AUTO, _('Automatic managed')), + (LOGIN_AUTO, _('使用账号')), (LOGIN_MANUAL, _('Manually input')) ) @@ -246,13 +100,19 @@ class SystemUser(ProtocolMixin, AuthMixin, BaseUser): ) users = models.ManyToManyField('users.User', blank=True, verbose_name=_("Users")) groups = models.ManyToManyField('users.UserGroup', blank=True, verbose_name=_("User groups")) - type = models.CharField(max_length=16, choices=Type.choices, default=Type.common, verbose_name=_('Type')) - priority = models.IntegerField(default=81, verbose_name=_("Priority"), help_text=_("1-100, the lower the value will be match first"), validators=[MinValueValidator(1), MaxValueValidator(100)]) + priority = models.IntegerField( + default=81, verbose_name=_("Priority"), + help_text=_("1-100, the lower the value will be match first"), + validators=[MinValueValidator(1), MaxValueValidator(100)] + ) protocol = models.CharField(max_length=16, choices=ProtocolMixin.Protocol.choices, default='ssh', verbose_name=_('Protocol')) - auto_push = models.BooleanField(default=True, verbose_name=_('Auto push')) + + login_mode = models.CharField(choices=LOGIN_MODE_CHOICES, default=LOGIN_AUTO, max_length=10, verbose_name=_('Login mode')) + auto_create_account = models.BooleanField(default=False, verbose_name=_("自动创建账号")) + auto_push_account = models.BooleanField(default=True, verbose_name=_('推送账号到资产')) + type = models.CharField(max_length=16, choices=Type.choices, default=Type.common, verbose_name=_('Type')) sudo = models.TextField(default='/bin/whoami', verbose_name=_('Sudo')) shell = models.CharField(max_length=64, default='/bin/bash', verbose_name=_('Shell')) - login_mode = models.CharField(choices=LOGIN_MODE_CHOICES, default=LOGIN_AUTO, max_length=10, verbose_name=_('Login mode')) sftp_root = models.CharField(default='tmp', max_length=128, verbose_name=_("SFTP Root")) token = models.TextField(default='', verbose_name=_('Token')) home = models.CharField(max_length=4096, default='', verbose_name=_('Home'), blank=True) @@ -277,7 +137,7 @@ class SystemUser(ProtocolMixin, AuthMixin, BaseUser): return self.get_login_mode_display() def is_need_push(self): - if self.auto_push and self.is_protocol_support_push: + if self.auto_push_account and self.is_protocol_support_push: return True else: return False diff --git a/apps/assets/serializers/account.py b/apps/assets/serializers/account.py index e4e320f33..33632d0c9 100644 --- a/apps/assets/serializers/account.py +++ b/apps/assets/serializers/account.py @@ -1,7 +1,8 @@ from rest_framework import serializers from django.utils.translation import ugettext_lazy as _ +from django.db.models import F -from assets.models import AuthBook +from assets.models import Account from orgs.mixins.serializers import BulkOrgResourceModelSerializer from .base import AuthSerializerMixin @@ -13,7 +14,6 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): ip = serializers.ReadOnlyField(label=_("IP")) hostname = serializers.ReadOnlyField(label=_("Hostname")) platform = serializers.ReadOnlyField(label=_("Platform")) - protocols = serializers.SerializerMethodField(label=_("Protocols")) date_created = serializers.DateTimeField( label=_('Date created'), format="%Y/%m/%d %H:%M:%S", read_only=True ) @@ -22,18 +22,20 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): ) class Meta: - model = AuthBook - fields_mini = ['id', 'username', 'ip', 'hostname', 'platform', 'protocols', 'version'] - fields_write_only = ['password', 'private_key', "public_key", 'passphrase'] + model = Account + fields_mini = [ + 'id', 'type', 'username', 'ip', 'hostname', + 'platform', 'protocol', 'version' + ] + fields_write_only = ['password', 'private_key', 'public_key', 'passphrase'] fields_other = ['date_created', 'date_updated', 'connectivity', 'date_verified', 'comment'] fields_small = fields_mini + fields_write_only + fields_other - fields_fk = ['asset', 'systemuser', 'systemuser_display'] + fields_fk = ['asset'] fields = fields_small + fields_fk extra_kwargs = { 'username': {'required': True}, 'private_key': {'write_only': True}, 'public_key': {'write_only': True}, - 'systemuser_display': {'label': _('System user display')} } ref_name = 'AssetAccountSerializer' @@ -52,27 +54,14 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): attrs = self._validate_gen_key(attrs) return attrs - def get_protocols(self, v): - """ protocols 是 queryset 中返回的,Post 创建成功后返回序列化时没有这个字段 """ - if hasattr(v, 'protocols'): - protocols = v.protocols - elif hasattr(v, 'asset') and v.asset: - protocols = v.asset.protocols - else: - protocols = '' - protocols = protocols.replace(' ', ', ') - return protocols - @classmethod def setup_eager_loading(cls, queryset): """ Perform necessary eager loading of data. """ - queryset = queryset.prefetch_related('systemuser', 'asset') + queryset = queryset.prefetch_related('asset')\ + .annotate(ip=F('asset__ip')) \ + .annotate(hostname=F('asset__hostname')) return queryset - def to_representation(self, instance): - instance.load_auth() - return super().to_representation(instance) - class AccountSecretSerializer(SecretReadableMixin, AccountSerializer): class Meta(AccountSerializer.Meta): diff --git a/apps/assets/serializers/account_history.py b/apps/assets/serializers/account_history.py index fb2844182..b0846c04d 100644 --- a/apps/assets/serializers/account_history.py +++ b/apps/assets/serializers/account_history.py @@ -1,29 +1,20 @@ -from rest_framework import serializers -from django.utils.translation import ugettext_lazy as _ -from assets.models import AuthBook +from assets.models import Account from common.drf.serializers import SecretReadableMixin from .account import AccountSerializer, AccountSecretSerializer class AccountHistorySerializer(AccountSerializer): - systemuser_display = serializers.SerializerMethodField(label=_('System user display')) class Meta: - model = AuthBook.history.model + model = Account.history.model fields = AccountSerializer.Meta.fields_mini + \ - AccountSerializer.Meta.fields_write_only + \ - AccountSerializer.Meta.fields_fk + \ - ['history_id', 'date_created', 'date_updated'] + AccountSerializer.Meta.fields_write_only + \ + AccountSerializer.Meta.fields_fk + \ + ['history_id', 'date_created', 'date_updated'] read_only_fields = fields ref_name = 'AccountHistorySerializer' - @staticmethod - def get_systemuser_display(instance): - if not instance.systemuser: - return '' - return str(instance.systemuser) - def get_field_names(self, declared_fields, info): fields = super().get_field_names(declared_fields, info) fields = list(set(fields) - {'org_name'}) diff --git a/apps/assets/serializers/asset.py b/apps/assets/serializers/asset.py index 427d0e470..da1a0a0fc 100644 --- a/apps/assets/serializers/asset.py +++ b/apps/assets/serializers/asset.py @@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _ from orgs.mixins.serializers import BulkOrgResourceModelSerializer from ..models import Asset, Node, Platform, SystemUser +from .account import AccountSerializer __all__ = [ 'AssetSerializer', 'AssetSimpleSerializer', 'MiniAssetSerializer', @@ -70,6 +71,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer): labels_display = serializers.ListField( child=serializers.CharField(), label=_('Labels name'), required=False, read_only=True ) + accounts = AccountSerializer(many=True, write_only=True, required=False) """ 资产的数据结构 @@ -92,7 +94,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer): 'domain', 'domain_display', 'platform', 'admin_user', 'admin_user_display' ] fields_m2m = [ - 'nodes', 'nodes_display', 'labels', 'labels_display', + 'nodes', 'nodes_display', 'labels', 'labels_display', 'accounts' ] read_only_fields = [ 'connectivity', 'date_verified', 'cpu_info', 'hardware_info', @@ -107,6 +109,11 @@ class AssetSerializer(BulkOrgResourceModelSerializer): 'cpu_info': {'label': _('CPU info')}, } + def __init__(self, *args, **kwargs): + data = kwargs.get('data', {}) + self.accounts_data = data.pop('accounts', []) + super().__init__(*args, **kwargs) + def get_fields(self): fields = super().get_fields() @@ -151,10 +158,24 @@ class AssetSerializer(BulkOrgResourceModelSerializer): nodes_to_set.append(node) instance.nodes.set(nodes_to_set) + @staticmethod + def add_accounts(instance, accounts_data): + for data in accounts_data: + data['asset'] = instance.id + print("Data: ", accounts_data) + serializer = AccountSerializer(data=accounts_data, many=True) + try: + serializer.is_valid(raise_exception=True) + except Exception as e: + raise serializers.ValidationError({'accounts': e}) + serializer.save() + def create(self, validated_data): self.compatible_with_old_protocol(validated_data) nodes_display = validated_data.pop('nodes_display', '') instance = super().create(validated_data) + if self.accounts_data: + self.add_accounts(instance, self.accounts_data) self.perform_nodes_display_create(instance, nodes_display) return instance diff --git a/apps/assets/serializers/system_user.py b/apps/assets/serializers/system_user.py index aa17b0585..a572a1736 100644 --- a/apps/assets/serializers/system_user.py +++ b/apps/assets/serializers/system_user.py @@ -47,9 +47,9 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): fields_small = fields_mini + fields_write_only + [ 'token', 'ssh_key_fingerprint', 'type', 'type_display', 'protocol', 'is_asset_protocol', - 'login_mode', 'login_mode_display', 'priority', + 'auto_create_account', 'login_mode', 'login_mode_display', 'priority', 'sudo', 'shell', 'sftp_root', 'home', 'system_groups', 'ad_domain', - 'username_same_with_user', 'auto_push', 'auto_generate_key', + 'username_same_with_user', 'auto_push_account', 'auto_generate_key', 'su_enabled', 'su_from', 'date_created', 'date_updated', 'comment', 'created_by', ] @@ -191,7 +191,7 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): attrs['protocol'] = SystemUser.Protocol.ssh attrs['login_mode'] = SystemUser.LOGIN_AUTO attrs['username_same_with_user'] = False - attrs['auto_push'] = False + attrs['auto_push_account'] = False return attrs def _validate_gen_key(self, attrs): @@ -259,7 +259,7 @@ class SystemUserWithAuthInfoSerializer(SecretReadableMixin, SystemUserSerializer fields_small = fields_mini + fields_write_only + [ 'protocol', 'login_mode', 'login_mode_display', 'priority', 'sudo', 'shell', 'ad_domain', 'sftp_root', 'token', - "username_same_with_user", 'auto_push', 'auto_generate_key', + "username_same_with_user", 'auto_push_account', 'auto_generate_key', 'comment', ] fields = fields_small diff --git a/apps/assets/signal_handlers/asset.py b/apps/assets/signal_handlers/asset.py index 97f727a46..a7e466c9b 100644 --- a/apps/assets/signal_handlers/asset.py +++ b/apps/assets/signal_handlers/asset.py @@ -52,8 +52,6 @@ def on_asset_created_or_update(sender, instance=None, created=False, **kwargs): if not has_node: instance.nodes.add(Node.org_root()) - instance.set_admin_user_relation() - @receiver(m2m_changed, sender=Asset.nodes.through) def on_asset_nodes_add(instance, action, reverse, pk_set, **kwargs): @@ -89,22 +87,22 @@ def on_asset_nodes_add(instance, action, reverse, pk_set, **kwargs): systemuser_id__in=system_user_ids, asset_id__in=asset_ids ).values_list('systemuser_id', 'asset_id')) # TODO 优化 - to_create = [] - for system_user_id in system_user_ids: - asset_ids_to_push = [] - for asset_id in asset_ids: - if (system_user_id, asset_id) in exist: - continue - asset_ids_to_push.append(asset_id) - to_create.append(m2m_model( - systemuser_id=system_user_id, - asset_id=asset_id, - org_id=instance.org_id - )) - if asset_ids_to_push: - push_system_user_to_assets.delay(system_user_id, asset_ids_to_push) - m2m_model.objects.bulk_create(to_create) - + # to_create = [] + # for system_user_id in system_user_ids: + # asset_ids_to_push = [] + # for asset_id in asset_ids: + # if (system_user_id, asset_id) in exist: + # continue + # asset_ids_to_push.append(asset_id) + # to_create.append(m2m_model( + # systemuser_id=system_user_id, + # asset_id=asset_id, + # org_id=instance.org_id + # )) + # if asset_ids_to_push: + # push_system_user_to_assets.delay(system_user_id, asset_ids_to_push) + # m2m_model.objects.bulk_create(to_create) + # RELATED_NODE_IDS = '_related_node_ids' diff --git a/apps/assets/signal_handlers/authbook.py b/apps/assets/signal_handlers/authbook.py index 513488763..8020e4087 100644 --- a/apps/assets/signal_handlers/authbook.py +++ b/apps/assets/signal_handlers/authbook.py @@ -1,50 +1,14 @@ from django.dispatch import receiver -from django.apps import apps -from simple_history.signals import pre_create_historical_record -from django.db.models.signals import post_save, pre_save, pre_delete +from django.db.models.signals import pre_save from common.utils import get_logger -from ..models import AuthBook, SystemUser +from ..models import Account -AuthBookHistory = apps.get_model('assets', 'HistoricalAuthBook') logger = get_logger(__name__) -@receiver(pre_create_historical_record, sender=AuthBookHistory) -def pre_create_historical_record_callback(sender, history_instance=None, **kwargs): - attrs_to_copy = ['username', 'password', 'private_key'] - - for attr in attrs_to_copy: - if getattr(history_instance, attr): - continue - try: - system_user = history_instance.systemuser - except SystemUser.DoesNotExist: - continue - if not system_user: - continue - system_user_attr_value = getattr(history_instance.systemuser, attr) - if system_user_attr_value: - setattr(history_instance, attr, system_user_attr_value) - - -@receiver(pre_delete, sender=AuthBook) -def on_authbook_post_delete(sender, instance, **kwargs): - instance.remove_asset_admin_user_if_need() - - -@receiver(post_save, sender=AuthBook) -def on_authbook_post_create(sender, instance, created, **kwargs): - instance.sync_to_system_user_account() - if created: - pass - # # 不再自动更新资产管理用户,只允许用户手动指定。 - # 只在创建时进行更新资产的管理用户 - # instance.update_asset_admin_user_if_need() - - -@receiver(pre_save, sender=AuthBook) -def on_authbook_pre_create(sender, instance, **kwargs): +@receiver(pre_save, sender=Account) +def on_account_pre_create(sender, instance, **kwargs): # 升级版本号 instance.version += 1 # 即使在 root 组织也不怕 diff --git a/apps/assets/signal_handlers/system_user.py b/apps/assets/signal_handlers/system_user.py index 00b19e110..64a656c29 100644 --- a/apps/assets/signal_handlers/system_user.py +++ b/apps/assets/signal_handlers/system_user.py @@ -9,9 +9,8 @@ from common.exceptions import M2MReverseNotAllowed from common.const.signals import POST_ADD from common.utils import get_logger from common.decorator import on_transaction_commit -from assets.models import Asset, SystemUser, Node, AuthBook +from assets.models import Asset, SystemUser, Node from users.models import User -from orgs.utils import tmp_to_root_org from assets.tasks import ( push_system_user_to_assets_manual, push_system_user_to_assets, @@ -39,35 +38,7 @@ def on_system_user_assets_change(instance, action, model, pk_set, **kwargs): else: system_user_ids = pk_set asset_ids = [instance.id] - - org_id = instance.org_id - - # 关联创建的 authbook 没有系统用户id - with tmp_to_root_org(): - authbooks = AuthBook.objects.filter( - asset_id__in=asset_ids, - systemuser_id__in=system_user_ids - ) - if action == POST_ADD: - authbooks.update(org_id=org_id) - - save_action_mapper = { - 'pre_add': pre_save, - 'post_add': post_save, - 'pre_remove': pre_delete, - 'post_remove': post_delete - } - - for ab in authbooks: - ab.org_id = org_id - - save_action = save_action_mapper[action] - logger.debug('Send AuthBook post save signal: {} -> {}'.format(action, ab.id)) - save_action.send(sender=AuthBook, instance=ab, created=True) - - if action == POST_ADD: - for system_user_id in system_user_ids: - push_system_user_to_assets.delay(system_user_id, asset_ids) + # todo: Auto create account if need @receiver(m2m_changed, sender=SystemUser.users.through) diff --git a/apps/assets/task_handlers/backup/handlers.py b/apps/assets/task_handlers/backup/handlers.py index 311d8e395..969ed5433 100644 --- a/apps/assets/task_handlers/backup/handlers.py +++ b/apps/assets/task_handlers/backup/handlers.py @@ -7,7 +7,7 @@ from django.conf import settings from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers -from assets.models import AuthBook +from assets.models import Account from assets.serializers import AccountSecretSerializer from assets.notifications import AccountBackupExecutionTaskMsg from applications.models import Account @@ -74,9 +74,9 @@ class AssetAccountHandler(BaseAccountHandler): @classmethod def create_data_map(cls): data_map = defaultdict(list) - sheet_name = AuthBook._meta.verbose_name + sheet_name = Account._meta.verbose_name - accounts = AuthBook.get_queryset().select_related('systemuser') + accounts = Account.get_queryset() if not accounts.first(): return data_map diff --git a/apps/assets/tasks/common.py b/apps/assets/tasks/common.py index a1bd79e11..6ad17b4c3 100644 --- a/apps/assets/tasks/common.py +++ b/apps/assets/tasks/common.py @@ -9,6 +9,7 @@ from assets.models import AuthBook __all__ = ['add_nodes_assets_to_system_users'] +# Todo: 等待优化 @shared_task @tmp_to_root_org() def add_nodes_assets_to_system_users(nodes_keys, system_users): diff --git a/apps/assets/tasks/utils.py b/apps/assets/tasks/utils.py index 93aaa4bfc..a60f1b494 100644 --- a/apps/assets/tasks/utils.py +++ b/apps/assets/tasks/utils.py @@ -25,7 +25,7 @@ def check_asset_can_run_ansible(asset): def check_system_user_can_run_ansible(system_user): - if not system_user.auto_push: + if not system_user.auto_push_account: logger.warn(f'Push system user task skip, auto push not enable: system_user={system_user.name}') return False if not system_user.is_protocol_support_push: diff --git a/apps/audits/const.py b/apps/audits/const.py index 9ff993556..eaed75fc0 100644 --- a/apps/audits/const.py +++ b/apps/audits/const.py @@ -11,7 +11,7 @@ MODELS_NEED_RECORD = ( 'LoginACL', 'LoginAssetACL', 'LoginConfirmSetting', # assets 'Asset', 'Node', 'AdminUser', 'SystemUser', 'Domain', 'Gateway', 'CommandFilterRule', - 'CommandFilter', 'Platform', 'AuthBook', + 'CommandFilter', 'Platform', 'Account', # applications 'Application', # orgs diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index b6f6e9863..28c740189 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -81,7 +81,6 @@ TERMINAL_HOST_KEY = CONFIG.TERMINAL_HOST_KEY TERMINAL_HEADER_TITLE = CONFIG.TERMINAL_HEADER_TITLE TERMINAL_TELNET_REGEX = CONFIG.TERMINAL_TELNET_REGEX -# Asset user auth external backend, default AuthBook backend BACKEND_ASSET_USER_AUTH_VAULT = False PERM_SINGLE_ASSET_TO_UNGROUP_NODE = CONFIG.PERM_SINGLE_ASSET_TO_UNGROUP_NODE diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index cf215a3fb..c66a34a44 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -785,13 +785,13 @@ msgstr "密码" #: xpack/plugins/change_auth_plan/models/asset.py:130 #: xpack/plugins/change_auth_plan/models/asset.py:206 msgid "SSH private key" -msgstr "SSH密钥" +msgstr "SSH 密钥" #: assets/models/base.py:179 xpack/plugins/change_auth_plan/models/asset.py:56 #: xpack/plugins/change_auth_plan/models/asset.py:126 #: xpack/plugins/change_auth_plan/models/asset.py:202 msgid "SSH public key" -msgstr "SSH公钥" +msgstr "SSH 公钥" #: assets/models/cluster.py:20 msgid "Bandwidth" @@ -2067,7 +2067,7 @@ msgstr "Access key" #: authentication/models.py:41 msgid "Private Token" -msgstr "SSH密钥" +msgstr "SSH 密钥" #: authentication/models.py:50 msgid "Expired" @@ -5468,7 +5468,7 @@ msgstr "原来密码错误" #: users/forms/profile.py:129 msgid "Automatically configure and download the SSH key" -msgstr "自动配置并下载SSH密钥" +msgstr "自动配置并下载 SSH 密钥" #: users/forms/profile.py:131 msgid "ssh public key" @@ -5489,11 +5489,11 @@ msgstr "不能和原来的密钥相同" #: users/forms/profile.py:150 users/serializers/profile.py:100 #: users/serializers/profile.py:183 users/serializers/profile.py:210 msgid "Not a valid ssh public key" -msgstr "SSH密钥不合法" +msgstr "SSH 密钥不合法" #: users/forms/profile.py:161 users/models/user.py:692 msgid "Public key" -msgstr "SSH公钥" +msgstr "SSH 公钥" #: users/models/user.py:558 msgid "Force enable" diff --git a/apps/perms/serializers/system_user_permission.py b/apps/perms/serializers/system_user_permission.py index 3452d7af3..def2516d6 100644 --- a/apps/perms/serializers/system_user_permission.py +++ b/apps/perms/serializers/system_user_permission.py @@ -13,7 +13,7 @@ class SystemUserSerializer(serializers.ModelSerializer): 'id', 'name', 'username', 'protocol', 'login_mode', 'login_mode_display', 'priority', 'username_same_with_user', - 'auto_push', 'cmd_filters', 'sudo', 'shell', 'comment', + 'auto_push_account', 'cmd_filters', 'sudo', 'shell', 'comment', 'sftp_root', 'date_created', 'created_by' ] ref_name = 'PermedSystemUserSerializer' diff --git a/utils/create_assets_user/bulk_create_user.py b/utils/create_assets_user/bulk_create_user.py index 14cbca820..2897d4f0c 100644 --- a/utils/create_assets_user/bulk_create_user.py +++ b/utils/create_assets_user/bulk_create_user.py @@ -113,7 +113,7 @@ class UserCreation: "username": username, "password": password, "protocol": protocol, - "auto_push": bool(int(auto_push)), + "auto_push_account": bool(int(auto_push)), "login_mode": "auto" } users.append(info)