From 37c54e976f505cf493ae57f589f9667ed7471292 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 20 Feb 2023 18:00:29 +0800 Subject: [PATCH 1/8] =?UTF-8?q?perf=EF=BC=9A=20=E4=BC=98=E5=8C=96=20tasks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/api/account/account.py | 23 +++++++--------- apps/accounts/api/account/backup.py | 4 +-- apps/accounts/api/automations/base.py | 4 +-- .../change_secret/host/posix/main.yml | 8 ++---- .../models/automations/backup_account.py | 6 ++--- apps/accounts/models/automations/base.py | 4 +-- apps/accounts/serializers/account/account.py | 6 +++-- apps/accounts/tasks/automation.py | 2 +- apps/accounts/tasks/backup_account.py | 3 ++- apps/accounts/tasks/gather_accounts.py | 4 +-- apps/accounts/tasks/push_account.py | 27 ++++++++----------- apps/accounts/tasks/verify_account.py | 6 ++--- apps/accounts/urls.py | 17 +++++++----- apps/assets/api/asset/asset.py | 6 ++--- apps/assets/models/automations/base.py | 4 +-- apps/assets/tasks/automation.py | 6 ++--- 16 files changed, 63 insertions(+), 67 deletions(-) diff --git a/apps/accounts/api/account/account.py b/apps/accounts/api/account/account.py index 3d4bcebd5..3a5e6b45e 100644 --- a/apps/accounts/api/account/account.py +++ b/apps/accounts/api/account/account.py @@ -6,7 +6,7 @@ from rest_framework.response import Response from accounts import serializers from accounts.filters import AccountFilterSet from accounts.models import Account -from accounts.tasks import verify_accounts_connectivity +from accounts.tasks import verify_accounts_connectivity_task, push_accounts_to_assets_task from assets.models import Asset from authentication.const import ConfirmType from common.permissions import UserConfirmation @@ -15,7 +15,7 @@ from orgs.mixins.api import OrgBulkModelViewSet __all__ = [ 'AccountViewSet', 'AccountSecretsViewSet', - 'AccountTaskCreateAPI', 'AccountHistoriesSecretAPI' + 'AccountsTaskCreateAPI', 'AccountHistoriesSecretAPI' ] from rbac.permissions import RBACPermission @@ -29,7 +29,6 @@ class AccountViewSet(OrgBulkModelViewSet): 'default': serializers.AccountSerializer, } rbac_perms = { - 'verify_account': 'accounts.test_account', 'partial_update': ['accounts.change_account'], 'su_from_accounts': 'accounts.view_account', } @@ -49,14 +48,6 @@ class AccountViewSet(OrgBulkModelViewSet): serializer = serializers.AccountSerializer(accounts, many=True) return Response(data=serializer.data) - @action(methods=['post'], detail=True, url_path='verify') - def verify_account(self, request, *args, **kwargs): - account = super().get_object() - account_ids = [account.id] - asset_ids = [account.asset_id] - task = verify_accounts_connectivity.delay(account_ids, asset_ids) - return Response(data={'task': task.id}) - class AccountSecretsViewSet(RecordViewLogMixin, AccountViewSet): """ @@ -86,7 +77,7 @@ class AccountHistoriesSecretAPI(RecordViewLogMixin, ListAPIView): return self.model.objects.filter(id=self.kwargs.get('pk')) -class AccountTaskCreateAPI(CreateAPIView): +class AccountsTaskCreateAPI(CreateAPIView): serializer_class = serializers.AccountTaskSerializer search_fields = AccountViewSet.search_fields filterset_class = AccountViewSet.filterset_class @@ -100,10 +91,16 @@ class AccountTaskCreateAPI(CreateAPIView): return queryset def perform_create(self, serializer): + data = serializer.validated_data accounts = self.get_accounts() account_ids = accounts.values_list('id', flat=True) asset_ids = [account.asset_id for account in accounts] - task = verify_accounts_connectivity.delay(account_ids, asset_ids) + + if data['action'] == 'push': + task = push_accounts_to_assets_task.delay(account_ids, asset_ids) + else: + task = verify_accounts_connectivity_task.delay(account_ids, asset_ids) + data = getattr(serializer, '_data', {}) data["task"] = task.id setattr(serializer, '_data', data) diff --git a/apps/accounts/api/account/backup.py b/apps/accounts/api/account/backup.py index fa068a0df..134f9548c 100644 --- a/apps/accounts/api/account/backup.py +++ b/apps/accounts/api/account/backup.py @@ -7,7 +7,7 @@ from accounts import serializers from accounts.models import ( AccountBackupAutomation, AccountBackupExecution ) -from accounts.tasks import execute_account_backup_plan +from accounts.tasks import execute_account_backup_task from common.const.choices import Trigger from orgs.mixins.api import OrgBulkModelViewSet @@ -38,5 +38,5 @@ class AccountBackupPlanExecutionViewSet(viewsets.ModelViewSet): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) pid = serializer.data.get('plan') - task = execute_account_backup_plan.delay(pid=str(pid), trigger=Trigger.manual) + task = execute_account_backup_task.delay(pid=str(pid), trigger=Trigger.manual) return Response({'task': task.id}, status=status.HTTP_201_CREATED) diff --git a/apps/accounts/api/automations/base.py b/apps/accounts/api/automations/base.py index 700484e9b..7d5db0ac8 100644 --- a/apps/accounts/api/automations/base.py +++ b/apps/accounts/api/automations/base.py @@ -4,7 +4,7 @@ from rest_framework import status, mixins, viewsets from rest_framework.response import Response from accounts.models import AutomationExecution -from accounts.tasks import execute_automation +from accounts.tasks import execute_account_automation_task from assets import serializers from assets.models import BaseAutomation from common.const.choices import Trigger @@ -109,7 +109,7 @@ class AutomationExecutionViewSet( serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) automation = serializer.validated_data.get('automation') - task = execute_automation.delay( + task = execute_account_automation_task.delay( pid=str(automation.pk), trigger=Trigger.manual, tp=self.tp ) return Response({'task': task.id}, status=status.HTTP_201_CREATED) diff --git a/apps/accounts/automations/change_secret/host/posix/main.yml b/apps/accounts/automations/change_secret/host/posix/main.yml index 1a4e6a6a4..b4e6aede6 100644 --- a/apps/accounts/automations/change_secret/host/posix/main.yml +++ b/apps/accounts/automations/change_secret/host/posix/main.yml @@ -3,10 +3,6 @@ tasks: - name: Test privileged account ansible.builtin.ping: - # - # - name: print variables - # debug: - # msg: "Username: {{ account.username }}, Secret: {{ account.secret }}, Secret type: {{ secret_type }}" - name: Change password ansible.builtin.user: @@ -26,8 +22,8 @@ regexp: "{{ kwargs.regexp }}" state: absent when: - - secret_type == "ssh_key" - - kwargs.strategy == "set_jms" + - secret_type == "ssh_key" + - kwargs.strategy == "set_jms" - name: Change SSH key ansible.builtin.authorized_key: diff --git a/apps/accounts/models/automations/backup_account.py b/apps/accounts/models/automations/backup_account.py index 3c213b00d..fba3b3149 100644 --- a/apps/accounts/models/automations/backup_account.py +++ b/apps/accounts/models/automations/backup_account.py @@ -7,11 +7,11 @@ from celery import current_task from django.db import models from django.db.models import F from django.utils.translation import ugettext_lazy as _ -from common.utils import lazyproperty from common.const.choices import Trigger from common.db.encoder import ModelJSONFieldEncoder from common.utils import get_logger +from common.utils import lazyproperty from ops.mixin import PeriodTaskModelMixin from orgs.mixins.models import OrgModelMixin, JMSOrgBaseModel @@ -36,9 +36,9 @@ class AccountBackupAutomation(PeriodTaskModelMixin, JMSOrgBaseModel): verbose_name = _('Account backup plan') def get_register_task(self): - from ...tasks import execute_account_backup_plan + from ...tasks import execute_account_backup_task name = "account_backup_plan_period_{}".format(str(self.id)[:8]) - task = execute_account_backup_plan.name + task = execute_account_backup_task.name args = (str(self.id), Trigger.timing) kwargs = {} return name, task, args, kwargs diff --git a/apps/accounts/models/automations/base.py b/apps/accounts/models/automations/base.py index 30c5df760..9477a7fdb 100644 --- a/apps/accounts/models/automations/base.py +++ b/apps/accounts/models/automations/base.py @@ -1,6 +1,6 @@ from django.utils.translation import gettext_lazy as _ -from accounts.tasks import execute_automation +from accounts.tasks import execute_account_automation_task from assets.models.automations import ( BaseAutomation as AssetBaseAutomation, AutomationExecution as AssetAutomationExecution @@ -16,7 +16,7 @@ class AccountBaseAutomation(AssetBaseAutomation): @property def execute_task(self): - return execute_automation + return execute_account_automation_task @property def execution_model(self): diff --git a/apps/accounts/serializers/account/account.py b/apps/accounts/serializers/account/account.py index 1e22a2f16..c8d281be3 100644 --- a/apps/accounts/serializers/account/account.py +++ b/apps/accounts/serializers/account/account.py @@ -3,7 +3,7 @@ from rest_framework import serializers from accounts.const import SecretType, Source from accounts.models import Account, AccountTemplate -from accounts.tasks import push_accounts_to_assets +from accounts.tasks import push_accounts_to_assets_task from assets.const import Category, AllTypes from assets.models import Asset from common.serializers import SecretReadableMixin, BulkModelSerializer @@ -43,7 +43,7 @@ class AccountSerializerCreateValidateMixin: def push_account(instance, push_now): if not push_now: return - push_accounts_to_assets.delay([instance.id], [instance.asset_id]) + push_accounts_to_assets_task.delay([instance.id], [instance.asset_id]) def create(self, validated_data): push_now = validated_data.pop('push_now', None) @@ -140,6 +140,8 @@ class AccountHistorySerializer(serializers.ModelSerializer): class AccountTaskSerializer(serializers.Serializer): ACTION_CHOICES = ( ('test', 'test'), + ('verify', 'verify'), + ('push', 'push'), ) action = serializers.ChoiceField(choices=ACTION_CHOICES, write_only=True) task = serializers.CharField(read_only=True) diff --git a/apps/accounts/tasks/automation.py b/apps/accounts/tasks/automation.py index bed1de77c..2b9f99235 100644 --- a/apps/accounts/tasks/automation.py +++ b/apps/accounts/tasks/automation.py @@ -24,7 +24,7 @@ def task_activity_callback(self, pid, trigger, tp): queue='ansible', verbose_name=_('Account execute automation'), activity_callback=task_activity_callback ) -def execute_automation(pid, trigger, tp): +def execute_account_automation_task(pid, trigger, tp): model = AutomationTypes.get_type_model(tp) with tmp_to_root_org(): instance = get_object_or_none(model, pk=pid) diff --git a/apps/accounts/tasks/backup_account.py b/apps/accounts/tasks/backup_account.py index 446ce0374..1f4e46d83 100644 --- a/apps/accounts/tasks/backup_account.py +++ b/apps/accounts/tasks/backup_account.py @@ -10,6 +10,7 @@ logger = get_logger(__file__) def task_activity_callback(self, pid, trigger): + from accounts.models import AccountBackupAutomation with tmp_to_root_org(): plan = get_object_or_none(AccountBackupAutomation, pk=pid) if not plan: @@ -22,7 +23,7 @@ def task_activity_callback(self, pid, trigger): @shared_task(verbose_name=_('Execute account backup plan'), activity_callback=task_activity_callback) -def execute_account_backup_plan(pid, trigger): +def execute_account_backup_task(pid, trigger): from accounts.models import AccountBackupAutomation with tmp_to_root_org(): plan = get_object_or_none(AccountBackupAutomation, pk=pid) diff --git a/apps/accounts/tasks/gather_accounts.py b/apps/accounts/tasks/gather_accounts.py index d0b322b10..cf2283e6f 100644 --- a/apps/accounts/tasks/gather_accounts.py +++ b/apps/accounts/tasks/gather_accounts.py @@ -9,7 +9,7 @@ from assets.models import Node from common.utils import get_logger from orgs.utils import org_aware_func -__all__ = ['gather_asset_accounts'] +__all__ = ['gather_asset_accounts_task'] logger = get_logger(__name__) @@ -29,7 +29,7 @@ def gather_asset_accounts_util(nodes, task_name): queue="ansible", verbose_name=_('Gather asset accounts'), activity_callback=lambda self, node_ids, task_name=None: (node_ids, None) ) -def gather_asset_accounts(node_ids, task_name=None): +def gather_asset_accounts_task(node_ids, task_name=None): if task_name is None: task_name = gettext_noop("Gather assets accounts") diff --git a/apps/accounts/tasks/push_account.py b/apps/accounts/tasks/push_account.py index 7a24e3b45..a1c4b6f7c 100644 --- a/apps/accounts/tasks/push_account.py +++ b/apps/accounts/tasks/push_account.py @@ -4,43 +4,38 @@ from django.utils.translation import gettext_noop, ugettext_lazy as _ from accounts.const import AutomationTypes from accounts.tasks.common import automation_execute_start from common.utils import get_logger -from orgs.utils import org_aware_func logger = get_logger(__file__) __all__ = [ - 'push_accounts_to_assets', + 'push_accounts_to_assets_task', ] -def push_util(account, assets, task_name): +def push_util(account, asset_ids, task_name): task_snapshot = { 'secret': account.secret, 'secret_type': account.secret_type, 'accounts': [account.username], - 'assets': [str(asset.id) for asset in assets], + 'assets': asset_ids, } tp = AutomationTypes.push_account automation_execute_start(task_name, tp, task_snapshot) -@org_aware_func("assets") -def push_accounts_to_assets_util(accounts, assets): - from accounts.models import PushAccountAutomation - - task_name = gettext_noop("Push accounts to assets") - task_name = PushAccountAutomation.generate_unique_name(task_name) - for account in accounts: - push_util(account, assets, task_name) - - @shared_task( queue="ansible", verbose_name=_('Push accounts to assets'), activity_callback=lambda self, account_ids, asset_ids: (account_ids, None) ) -def push_accounts_to_assets(account_ids, asset_ids): +def push_accounts_to_assets_task(account_ids, asset_ids): + from accounts.models import PushAccountAutomation from assets.models import Asset from accounts.models import Account assets = Asset.objects.filter(id__in=asset_ids) accounts = Account.objects.filter(id__in=account_ids) - return push_accounts_to_assets_util(accounts, assets) + + task_name = gettext_noop("Push accounts to assets") + task_name = PushAccountAutomation.generate_unique_name(task_name) + + for account in accounts: + push_util(account, assets, task_name) diff --git a/apps/accounts/tasks/verify_account.py b/apps/accounts/tasks/verify_account.py index dcb0cb58f..f5221d975 100644 --- a/apps/accounts/tasks/verify_account.py +++ b/apps/accounts/tasks/verify_account.py @@ -1,6 +1,6 @@ from celery import shared_task -from django.utils.translation import gettext_noop from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext_noop from accounts.const import AutomationTypes from accounts.tasks.common import automation_execute_start @@ -10,7 +10,7 @@ from orgs.utils import org_aware_func logger = get_logger(__name__) __all__ = [ - 'verify_accounts_connectivity' + 'verify_accounts_connectivity_task' ] @@ -42,7 +42,7 @@ def verify_accounts_connectivity_util(accounts, assets, task_name): queue="ansible", verbose_name=_('Verify asset account availability'), activity_callback=lambda self, account_ids, asset_ids: (account_ids, None) ) -def verify_accounts_connectivity(account_ids, asset_ids): +def verify_accounts_connectivity_task(account_ids, asset_ids): from assets.models import Asset from accounts.models import Account, VerifyAccountAutomation assets = Asset.objects.filter(id__in=asset_ids) diff --git a/apps/accounts/urls.py b/apps/accounts/urls.py index 8a28bc0d7..59a70b3cf 100644 --- a/apps/accounts/urls.py +++ b/apps/accounts/urls.py @@ -25,17 +25,22 @@ router.register(r'push-account-executions', api.PushAccountExecutionViewSet, 'pu router.register(r'push-account-records', api.PushAccountRecordViewSet, 'push-account-record') urlpatterns = [ - path('accounts/tasks/', api.AccountTaskCreateAPI.as_view(), name='account-task-create'), - path('account-secrets//histories/', api.AccountHistoriesSecretAPI.as_view(), name='account-secret-history'), + path('accounts/tasks/', api.AccountsTaskCreateAPI.as_view(), name='account-task-create'), + path('account-secrets//histories/', api.AccountHistoriesSecretAPI.as_view(), + name='account-secret-history'), - path('change-secret//asset/remove/', api.ChangSecretRemoveAssetApi.as_view(), name='change-secret-remove-asset'), + path('change-secret//asset/remove/', api.ChangSecretRemoveAssetApi.as_view(), + name='change-secret-remove-asset'), path('change-secret//asset/add/', api.ChangSecretAddAssetApi.as_view(), name='change-secret-add-asset'), - path('change-secret//nodes/', api.ChangSecretNodeAddRemoveApi.as_view(), name='change-secret-add-or-remove-node'), + path('change-secret//nodes/', api.ChangSecretNodeAddRemoveApi.as_view(), + name='change-secret-add-or-remove-node'), path('change-secret//assets/', api.ChangSecretAssetsListApi.as_view(), name='change-secret-assets'), - path('push-account//asset/remove/', api.PushAccountRemoveAssetApi.as_view(), name='push-account-remove-asset'), + path('push-account//asset/remove/', api.PushAccountRemoveAssetApi.as_view(), + name='push-account-remove-asset'), path('push-accountt//asset/add/', api.PushAccountAddAssetApi.as_view(), name='push-account-add-asset'), - path('push-account//nodes/', api.PushAccountNodeAddRemoveApi.as_view(), name='push-account-add-or-remove-node'), + path('push-account//nodes/', api.PushAccountNodeAddRemoveApi.as_view(), + name='push-account-add-or-remove-node'), path('push-account//assets/', api.PushAccountAssetsListApi.as_view(), name='push-account-assets'), ] diff --git a/apps/assets/api/asset/asset.py b/apps/assets/api/asset/asset.py index 630a24552..f51bdbb94 100644 --- a/apps/assets/api/asset/asset.py +++ b/apps/assets/api/asset/asset.py @@ -6,7 +6,7 @@ from django.utils.translation import gettext as _ from rest_framework.decorators import action from rest_framework.response import Response -from accounts.tasks import push_accounts_to_assets, verify_accounts_connectivity +from accounts.tasks import push_accounts_to_assets_task, verify_accounts_connectivity_task from assets import serializers from assets.filters import IpInFilterBackend, LabelFilterBackend, NodeFilterBackend from assets.models import Asset, Gateway @@ -205,9 +205,9 @@ class AssetTaskCreateApi(AssetsTaskMixin, generics.CreateAPIView): asset_ids = [asset.id] account_ids = accounts.values_list("id", flat=True) if action == "push_account": - task = push_accounts_to_assets.delay(account_ids, asset_ids) + task = push_accounts_to_assets_task.delay(account_ids, asset_ids) elif action == "test_account": - task = verify_accounts_connectivity.delay(account_ids, asset_ids) + task = verify_accounts_connectivity_task.delay(account_ids, asset_ids) else: task = None return task diff --git a/apps/assets/models/automations/base.py b/apps/assets/models/automations/base.py index 423ba9d09..9ddeb5bf2 100644 --- a/apps/assets/models/automations/base.py +++ b/apps/assets/models/automations/base.py @@ -6,7 +6,7 @@ from django.utils.translation import ugettext_lazy as _ from assets.models.asset import Asset from assets.models.node import Node -from assets.tasks import execute_automation +from assets.tasks import execute_asset_automation_task from common.const.choices import Trigger from common.db.fields import EncryptJsonDictTextField from ops.mixin import PeriodTaskModelMixin @@ -49,7 +49,7 @@ class BaseAutomation(PeriodTaskModelMixin, JMSOrgBaseModel): @property def execute_task(self): - return execute_automation + return execute_asset_automation_task def get_register_task(self): name = f"automation_{self.type}_strategy_period_{str(self.id)[:8]}" diff --git a/apps/assets/tasks/automation.py b/apps/assets/tasks/automation.py index 4e7d340c2..02e946ede 100644 --- a/apps/assets/tasks/automation.py +++ b/apps/assets/tasks/automation.py @@ -1,9 +1,9 @@ from celery import shared_task from django.utils.translation import gettext_lazy as _ -from orgs.utils import tmp_to_root_org, tmp_to_org -from common.utils import get_logger, get_object_or_none from assets.const import AutomationTypes +from common.utils import get_logger, get_object_or_none +from orgs.utils import tmp_to_root_org, tmp_to_org logger = get_logger(__file__) @@ -24,7 +24,7 @@ def task_activity_callback(self, pid, trigger, tp): queue='ansible', verbose_name=_('Asset execute automation'), activity_callback=task_activity_callback ) -def execute_automation(pid, trigger, tp): +def execute_asset_automation_task(pid, trigger, tp): model = AutomationTypes.get_type_model(tp) with tmp_to_root_org(): instance = get_object_or_none(model, pk=pid) From c9534bb9c4df7bf920dab52b674f417fdea82152 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 20 Feb 2023 23:50:33 +0800 Subject: [PATCH 2/8] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/api/account/account.py | 2 +- .../models/automations/change_secret.py | 2 +- .../models/automations/push_account.py | 1 - apps/accounts/serializers/account/account.py | 3 ++ .../serializers/automations/push_account.py | 54 ++----------------- apps/accounts/tasks/common.py | 13 ++--- apps/accounts/tasks/gather_accounts.py | 4 +- apps/accounts/tasks/push_account.py | 31 ++++++----- apps/accounts/tasks/verify_account.py | 4 +- 9 files changed, 33 insertions(+), 81 deletions(-) diff --git a/apps/accounts/api/account/account.py b/apps/accounts/api/account/account.py index 3a5e6b45e..dd57761c2 100644 --- a/apps/accounts/api/account/account.py +++ b/apps/accounts/api/account/account.py @@ -92,7 +92,7 @@ class AccountsTaskCreateAPI(CreateAPIView): def perform_create(self, serializer): data = serializer.validated_data - accounts = self.get_accounts() + accounts = data.get('accounts') account_ids = accounts.values_list('id', flat=True) asset_ids = [account.asset_id for account in accounts] diff --git a/apps/accounts/models/automations/change_secret.py b/apps/accounts/models/automations/change_secret.py index d52fc2cae..76ae9b4f2 100644 --- a/apps/accounts/models/automations/change_secret.py +++ b/apps/accounts/models/automations/change_secret.py @@ -16,11 +16,11 @@ class ChangeSecretMixin(models.Model): choices=SecretType.choices, max_length=16, default=SecretType.PASSWORD, verbose_name=_('Secret type') ) + secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret')) secret_strategy = models.CharField( choices=SecretStrategy.choices, max_length=16, default=SecretStrategy.custom, verbose_name=_('Secret strategy') ) - secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret')) password_rules = models.JSONField(default=dict, verbose_name=_('Password rules')) ssh_key_change_strategy = models.CharField( choices=SSHKeyStrategy.choices, max_length=16, diff --git a/apps/accounts/models/automations/push_account.py b/apps/accounts/models/automations/push_account.py index 4e4d95d9d..411e8cb12 100644 --- a/apps/accounts/models/automations/push_account.py +++ b/apps/accounts/models/automations/push_account.py @@ -9,7 +9,6 @@ __all__ = ['PushAccountAutomation'] class PushAccountAutomation(ChangeSecretMixin, AccountBaseAutomation): - accounts = None triggers = models.JSONField(max_length=16, default=list, verbose_name=_('Triggers')) username = models.CharField(max_length=128, verbose_name=_('Username')) action = models.CharField(max_length=16, verbose_name=_('Action')) diff --git a/apps/accounts/serializers/account/account.py b/apps/accounts/serializers/account/account.py index c8d281be3..1f9c143bd 100644 --- a/apps/accounts/serializers/account/account.py +++ b/apps/accounts/serializers/account/account.py @@ -144,4 +144,7 @@ class AccountTaskSerializer(serializers.Serializer): ('push', 'push'), ) action = serializers.ChoiceField(choices=ACTION_CHOICES, write_only=True) + accounts = serializers.PrimaryKeyRelatedField( + queryset=Account.objects, required=False, allow_empty=True, many=True + ) task = serializers.CharField(read_only=True) diff --git a/apps/accounts/serializers/automations/push_account.py b/apps/accounts/serializers/automations/push_account.py index aad6041ba..07ebaa2d0 100644 --- a/apps/accounts/serializers/automations/push_account.py +++ b/apps/accounts/serializers/automations/push_account.py @@ -7,58 +7,12 @@ from .change_secret import ( class PushAccountAutomationSerializer(ChangeSecretAutomationSerializer): - # dynamic_username = serializers.BooleanField(label=_('Dynamic username'), default=False) - # triggers = TreeChoicesField( - # choice_cls=TriggerChoice, label=_('Triggers'), - # default=TriggerChoice.all(), - # ) - # action = LabeledChoiceField( - # choices=PushAccountActionChoice.choices, label=_('Action'), - # default=PushAccountActionChoice.create_and_push - # ) - class Meta(ChangeSecretAutomationSerializer.Meta): model = PushAccountAutomation - fields = copy.copy(ChangeSecretAutomationSerializer.Meta.fields) - fields.remove('recipients') - - # fields = ChangeSecretAutomationSerializer.Meta.fields + [ - # 'dynamic_username', 'triggers', 'action' - # ] - - # def validate_username(self, value): - # if self.initial_data.get('dynamic_username'): - # value = '@USER' - # queryset = self.Meta.model.objects.filter(username=value) - # if self.instance: - # queryset = queryset.exclude(id=self.instance.id) - # if queryset.exists(): - # raise serializers.ValidationError(_('Username already exists')) - # return value - # - # def validate_dynamic_username(self, value): - # if not value: - # return value - # queryset = self.Meta.model.objects.filter(username='@USER') - # if self.instance: - # queryset = queryset.exclude(id=self.instance.id) - # if queryset.exists(): - # raise serializers.ValidationError(_('Dynamic username already exists')) - # return value - # - # def validate_triggers(self, value): - # # Now triggers readonly, set all - # return TriggerChoice.all() - # - # def get_field_names(self, declared_fields, info): - # fields = super().get_field_names(declared_fields, info) - # excludes = [ - # 'recipients', 'is_periodic', 'interval', 'crontab', - # 'periodic_display', 'assets', 'nodes' - # ] - # fields = [f for f in fields if f not in excludes] - # fields[fields.index('accounts')] = 'username' - # return fields + fields = [ + n for n in ChangeSecretAutomationSerializer.Meta.fields + if n not in ['recipients'] + ] class PushAccountUpdateAssetSerializer(ChangeSecretUpdateAssetSerializer): diff --git a/apps/accounts/tasks/common.py b/apps/accounts/tasks/common.py index 5c8aeedf5..52f2d13b4 100644 --- a/apps/accounts/tasks/common.py +++ b/apps/accounts/tasks/common.py @@ -4,17 +4,14 @@ from assets.tasks.common import generate_automation_execution_data from common.const.choices import Trigger -def automation_execute_start(task_name, tp, task_snapshot=None): +def quickstart_automation_by_snapshot(task_name, tp, task_snapshot=None): from accounts.models import AutomationExecution data = generate_automation_execution_data(task_name, tp, task_snapshot) - while True: - try: - _id = data['id'] - AutomationExecution.objects.get(id=_id) - data['id'] = str(uuid.uuid4()) - except AutomationExecution.DoesNotExist: - break + pk = data['id'] + if AutomationExecution.objects.exists(id=pk): + data['id'] = str(uuid.uuid4()) + execution = AutomationExecution.objects.create( trigger=Trigger.manual, **data ) diff --git a/apps/accounts/tasks/gather_accounts.py b/apps/accounts/tasks/gather_accounts.py index cf2283e6f..ceead3f9d 100644 --- a/apps/accounts/tasks/gather_accounts.py +++ b/apps/accounts/tasks/gather_accounts.py @@ -4,7 +4,7 @@ from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_noop from accounts.const import AutomationTypes -from accounts.tasks.common import automation_execute_start +from accounts.tasks.common import quickstart_automation_by_snapshot from assets.models import Node from common.utils import get_logger from orgs.utils import org_aware_func @@ -22,7 +22,7 @@ def gather_asset_accounts_util(nodes, task_name): 'nodes': [str(node.id) for node in nodes], } tp = AutomationTypes.verify_account - automation_execute_start(task_name, tp, task_snapshot) + quickstart_automation_by_snapshot(task_name, tp, task_snapshot) @shared_task( diff --git a/apps/accounts/tasks/push_account.py b/apps/accounts/tasks/push_account.py index a1c4b6f7c..ab7832b2f 100644 --- a/apps/accounts/tasks/push_account.py +++ b/apps/accounts/tasks/push_account.py @@ -1,8 +1,9 @@ from celery import shared_task +from collections import defaultdict from django.utils.translation import gettext_noop, ugettext_lazy as _ from accounts.const import AutomationTypes -from accounts.tasks.common import automation_execute_start +from accounts.tasks.common import quickstart_automation_by_snapshot from common.utils import get_logger logger = get_logger(__file__) @@ -11,31 +12,29 @@ __all__ = [ ] -def push_util(account, asset_ids, task_name): - task_snapshot = { - 'secret': account.secret, - 'secret_type': account.secret_type, - 'accounts': [account.username], - 'assets': asset_ids, - } - tp = AutomationTypes.push_account - automation_execute_start(task_name, tp, task_snapshot) - - @shared_task( queue="ansible", verbose_name=_('Push accounts to assets'), activity_callback=lambda self, account_ids, asset_ids: (account_ids, None) ) -def push_accounts_to_assets_task(account_ids, asset_ids): +def push_accounts_to_assets_task(account_ids): from accounts.models import PushAccountAutomation - from assets.models import Asset from accounts.models import Account - assets = Asset.objects.filter(id__in=asset_ids) accounts = Account.objects.filter(id__in=account_ids) task_name = gettext_noop("Push accounts to assets") task_name = PushAccountAutomation.generate_unique_name(task_name) + account_asset_mapper = defaultdict(set) for account in accounts: - push_util(account, assets, task_name) + account_asset_mapper[account.username].add(account.asset) + + for username, assets in account_asset_mapper.items(): + task_snapshot = { + 'secret': account.secret, + 'secret_type': account.secret_type, + 'accounts': [account.username], + 'assets': asset_ids, + } + tp = AutomationTypes.push_account + quickstart_automation_by_snapshot(task_name, tp, task_snapshot) \ No newline at end of file diff --git a/apps/accounts/tasks/verify_account.py b/apps/accounts/tasks/verify_account.py index f5221d975..8bb656e29 100644 --- a/apps/accounts/tasks/verify_account.py +++ b/apps/accounts/tasks/verify_account.py @@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_noop from accounts.const import AutomationTypes -from accounts.tasks.common import automation_execute_start +from accounts.tasks.common import quickstart_automation_by_snapshot from assets.const import GATEWAY_NAME from common.utils import get_logger from orgs.utils import org_aware_func @@ -22,7 +22,7 @@ def verify_connectivity_util(assets, tp, accounts, task_name): 'accounts': account_usernames, 'assets': [str(asset.id) for asset in assets], } - automation_execute_start(task_name, tp, task_snapshot) + quickstart_automation_by_snapshot(task_name, tp, task_snapshot) @org_aware_func("assets") From b49b7125b2a49b717fffa3e0f259769b39a47bd5 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 21 Feb 2023 08:34:31 +0800 Subject: [PATCH 3/8] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E6=94=B6?= =?UTF-8?q?=E9=9B=86=E7=94=A8=E6=88=B7=E4=B8=AD=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/models/__init__.py | 1 - .../models/automations/gather_account.py | 28 ++++++++++++++++- apps/accounts/models/gathered_account.py | 30 ------------------- 3 files changed, 27 insertions(+), 32 deletions(-) delete mode 100644 apps/accounts/models/gathered_account.py diff --git a/apps/accounts/models/__init__.py b/apps/accounts/models/__init__.py index 46de8344e..c40ee786d 100644 --- a/apps/accounts/models/__init__.py +++ b/apps/accounts/models/__init__.py @@ -1,4 +1,3 @@ from .base import * from .account import * from .automations import * -from .gathered_account import * diff --git a/apps/accounts/models/automations/gather_account.py b/apps/accounts/models/automations/gather_account.py index 1dd5500f7..ced7995c7 100644 --- a/apps/accounts/models/automations/gather_account.py +++ b/apps/accounts/models/automations/gather_account.py @@ -1,9 +1,35 @@ from django.utils.translation import ugettext_lazy as _ +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +from orgs.mixins.models import JMSOrgBaseModel from accounts.const import AutomationTypes from .base import AccountBaseAutomation -__all__ = ['GatherAccountsAutomation'] +__all__ = ['GatherAccountsAutomation', 'GatheredAccount'] + + +class GatheredAccount(JMSOrgBaseModel): + present = models.BooleanField(default=True, verbose_name=_("Present")) + date_last_login = models.DateTimeField(null=True, verbose_name=_("Date last login")) + asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_("Asset")) + username = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=_('Username')) + address_last_login = models.CharField(max_length=39, default='', verbose_name=_("Address last login")) + + @property + def address(self): + return self.asset.address + + class Meta: + verbose_name = _('Gather account') + unique_together = [ + ('username', 'asset'), + ] + ordering = ['asset'] + + def __str__(self): + return '{}: {}'.format(self.asset, self.username) class GatherAccountsAutomation(AccountBaseAutomation): diff --git a/apps/accounts/models/gathered_account.py b/apps/accounts/models/gathered_account.py deleted file mode 100644 index e61487d61..000000000 --- a/apps/accounts/models/gathered_account.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# -from django.db import models -from django.utils.translation import ugettext_lazy as _ - -from orgs.mixins.models import JMSOrgBaseModel - -__all__ = ['GatheredAccount'] - - -class GatheredAccount(JMSOrgBaseModel): - present = models.BooleanField(default=True, verbose_name=_("Present")) - date_last_login = models.DateTimeField(null=True, verbose_name=_("Date last login")) - asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_("Asset")) - username = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=_('Username')) - address_last_login = models.CharField(max_length=39, default='', verbose_name=_("Address last login")) - - @property - def address(self): - return self.asset.address - - class Meta: - verbose_name = _('Gather account') - unique_together = [ - ('username', 'asset'), - ] - ordering = ['asset'] - - def __str__(self): - return '{}: {}'.format(self.asset, self.username) From e67a8765136bc304ebb19e7529e6f7591574b965 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 21 Feb 2023 13:00:04 +0800 Subject: [PATCH 4/8] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/api/account/__init__.py | 3 +- apps/accounts/api/account/account.py | 42 ++----------------- apps/accounts/api/account/gathered_account.py | 42 ------------------- apps/accounts/api/account/task.py | 37 ++++++++++++++++ apps/accounts/api/automations/__init__.py | 1 + .../api/{account => automations}/backup.py | 0 .../api/automations/gather_accounts.py | 40 +++++++++++++++++- apps/accounts/automations/base/manager.py | 8 ++-- .../automations/change_secret/manager.py | 2 +- .../automations/push_account/manager.py | 2 +- apps/accounts/tasks/common.py | 2 +- apps/accounts/tasks/push_account.py | 10 +---- apps/accounts/tasks/verify_account.py | 23 ++++++---- apps/assets/api/node.py | 6 +-- apps/assets/automations/base/manager.py | 2 + .../automations/ping_gateway/manager.py | 2 +- .../migrations/0111_alter_asset_options.py | 17 ++++++++ apps/assets/models/asset/common.py | 4 +- apps/assets/models/domain.py | 4 +- apps/ops/ansible/inventory.py | 2 +- apps/ops/signal_handlers.py | 16 +++++++ 21 files changed, 147 insertions(+), 118 deletions(-) delete mode 100644 apps/accounts/api/account/gathered_account.py create mode 100644 apps/accounts/api/account/task.py rename apps/accounts/api/{account => automations}/backup.py (100%) create mode 100644 apps/assets/migrations/0111_alter_asset_options.py diff --git a/apps/accounts/api/account/__init__.py b/apps/accounts/api/account/__init__.py index ea5ab0cd1..f6d8376a6 100644 --- a/apps/accounts/api/account/__init__.py +++ b/apps/accounts/api/account/__init__.py @@ -1,4 +1,3 @@ from .account import * -from .backup import * +from .task import * from .template import * -from .gathered_account import * diff --git a/apps/accounts/api/account/account.py b/apps/accounts/api/account/account.py index dd57761c2..631669acc 100644 --- a/apps/accounts/api/account/account.py +++ b/apps/accounts/api/account/account.py @@ -1,12 +1,11 @@ from django.shortcuts import get_object_or_404 from rest_framework.decorators import action -from rest_framework.generics import CreateAPIView, ListAPIView +from rest_framework.generics import ListAPIView from rest_framework.response import Response from accounts import serializers from accounts.filters import AccountFilterSet from accounts.models import Account -from accounts.tasks import verify_accounts_connectivity_task, push_accounts_to_assets_task from assets.models import Asset from authentication.const import ConfirmType from common.permissions import UserConfirmation @@ -15,7 +14,7 @@ from orgs.mixins.api import OrgBulkModelViewSet __all__ = [ 'AccountViewSet', 'AccountSecretsViewSet', - 'AccountsTaskCreateAPI', 'AccountHistoriesSecretAPI' + 'AccountHistoriesSecretAPI' ] from rbac.permissions import RBACPermission @@ -37,6 +36,7 @@ class AccountViewSet(OrgBulkModelViewSet): def su_from_accounts(self, request, *args, **kwargs): account_id = request.query_params.get('account') asset_id = request.query_params.get('asset') + if account_id: account = get_object_or_404(Account, pk=account_id) accounts = account.get_su_from_accounts() @@ -75,39 +75,3 @@ class AccountHistoriesSecretAPI(RecordViewLogMixin, ListAPIView): def get_queryset(self): return self.model.objects.filter(id=self.kwargs.get('pk')) - - -class AccountsTaskCreateAPI(CreateAPIView): - serializer_class = serializers.AccountTaskSerializer - search_fields = AccountViewSet.search_fields - filterset_class = AccountViewSet.filterset_class - - def check_permissions(self, request): - return request.user.has_perm('assets.test_assetconnectivity') - - def get_accounts(self): - queryset = Account.objects.all() - queryset = self.filter_queryset(queryset) - return queryset - - def perform_create(self, serializer): - data = serializer.validated_data - accounts = data.get('accounts') - account_ids = accounts.values_list('id', flat=True) - asset_ids = [account.asset_id for account in accounts] - - if data['action'] == 'push': - task = push_accounts_to_assets_task.delay(account_ids, asset_ids) - else: - task = verify_accounts_connectivity_task.delay(account_ids, asset_ids) - - data = getattr(serializer, '_data', {}) - data["task"] = task.id - setattr(serializer, '_data', data) - return task - - def get_exception_handler(self): - def handler(e, context): - return Response({"error": str(e)}, status=400) - - return handler diff --git a/apps/accounts/api/account/gathered_account.py b/apps/accounts/api/account/gathered_account.py deleted file mode 100644 index e47befac4..000000000 --- a/apps/accounts/api/account/gathered_account.py +++ /dev/null @@ -1,42 +0,0 @@ -from rest_framework import status -from rest_framework.decorators import action -from rest_framework.response import Response -from django.utils.translation import ugettext_lazy as _ - -from accounts import serializers -from accounts.const import Source -from accounts.models import GatheredAccount -from accounts.filters import GatheredAccountFilterSet -from orgs.mixins.api import OrgBulkModelViewSet - -__all__ = [ - 'GatheredAccountViewSet', -] - - -class GatheredAccountViewSet(OrgBulkModelViewSet): - model = GatheredAccount - search_fields = ('username',) - filterset_class = GatheredAccountFilterSet - serializer_classes = { - 'default': serializers.GatheredAccountSerializer, - } - rbac_perms = { - 'sync_account': 'assets.add_gatheredaccount', - } - - @action(methods=['post'], detail=True, url_path='sync') - def sync_account(self, request, *args, **kwargs): - gathered_account = super().get_object() - asset = gathered_account.asset - username = gathered_account.username - accounts = asset.accounts.filter(username=username) - if accounts.exists(): - accounts.update(source=Source.COLLECTED) - else: - asset.accounts.model.objects.create( - asset=asset, username=username, - name=f'{username}-{_("Collected")}', - source=Source.COLLECTED - ) - return Response(status=status.HTTP_201_CREATED) diff --git a/apps/accounts/api/account/task.py b/apps/accounts/api/account/task.py new file mode 100644 index 000000000..85a3831e2 --- /dev/null +++ b/apps/accounts/api/account/task.py @@ -0,0 +1,37 @@ +from rest_framework.generics import CreateAPIView +from rest_framework.response import Response + +from accounts import serializers +from accounts.tasks import verify_accounts_connectivity_task, push_accounts_to_assets_task + +__all__ = [ + 'AccountsTaskCreateAPI', +] + + +class AccountsTaskCreateAPI(CreateAPIView): + serializer_class = serializers.AccountTaskSerializer + + def check_permissions(self, request): + return request.user.has_perm('assets.test_assetconnectivity') + + def perform_create(self, serializer): + data = serializer.validated_data + accounts = data.get('accounts', []) + account_ids = [a.id for a in accounts] + + if data['action'] == 'push': + task = push_accounts_to_assets_task.delay(account_ids) + else: + task = verify_accounts_connectivity_task.delay(account_ids) + + data = getattr(serializer, '_data', {}) + data["task"] = task.id + setattr(serializer, '_data', data) + return task + + def get_exception_handler(self): + def handler(e, context): + return Response({"error": str(e)}, status=400) + + return handler diff --git a/apps/accounts/api/automations/__init__.py b/apps/accounts/api/automations/__init__.py index 2b0aa0029..a03da88b0 100644 --- a/apps/accounts/api/automations/__init__.py +++ b/apps/accounts/api/automations/__init__.py @@ -1,3 +1,4 @@ +from .backup import * from .base import * from .change_secret import * from .gather_accounts import * diff --git a/apps/accounts/api/account/backup.py b/apps/accounts/api/automations/backup.py similarity index 100% rename from apps/accounts/api/account/backup.py rename to apps/accounts/api/automations/backup.py diff --git a/apps/accounts/api/automations/gather_accounts.py b/apps/accounts/api/automations/gather_accounts.py index 59f55c60e..3abca94dd 100644 --- a/apps/accounts/api/automations/gather_accounts.py +++ b/apps/accounts/api/automations/gather_accounts.py @@ -1,13 +1,22 @@ # -*- coding: utf-8 -*- # +from django.utils.translation import ugettext_lazy as _ +from rest_framework import status +from rest_framework.decorators import action +from rest_framework.response import Response + from accounts import serializers from accounts.const import AutomationTypes +from accounts.const import Source +from accounts.filters import GatheredAccountFilterSet from accounts.models import GatherAccountsAutomation +from accounts.models import GatheredAccount from orgs.mixins.api import OrgBulkModelViewSet from .base import AutomationExecutionViewSet __all__ = [ - 'GatherAccountsAutomationViewSet', 'GatherAccountsExecutionViewSet' + 'GatherAccountsAutomationViewSet', 'GatherAccountsExecutionViewSet', + 'GatheredAccountViewSet' ] @@ -31,3 +40,32 @@ class GatherAccountsExecutionViewSet(AutomationExecutionViewSet): queryset = super().get_queryset() queryset = queryset.filter(automation__type=self.tp) return queryset + + +class GatheredAccountViewSet(OrgBulkModelViewSet): + model = GatheredAccount + search_fields = ('username',) + filterset_class = GatheredAccountFilterSet + serializer_classes = { + 'default': serializers.GatheredAccountSerializer, + } + rbac_perms = { + 'sync_account': 'assets.add_gatheredaccount', + } + + @action(methods=['post'], detail=True, url_path='sync') + def sync_account(self, request, *args, **kwargs): + gathered_account = super().get_object() + asset = gathered_account.asset + username = gathered_account.username + accounts = asset.accounts.filter(username=username) + + if accounts.exists(): + accounts.update(source=Source.COLLECTED) + else: + asset.accounts.model.objects.create( + asset=asset, username=username, + name=f'{username}-{_("Collected")}', + source=Source.COLLECTED + ) + return Response(status=status.HTTP_201_CREATED) diff --git a/apps/accounts/automations/base/manager.py b/apps/accounts/automations/base/manager.py index 4e06217b3..6251c93a2 100644 --- a/apps/accounts/automations/base/manager.py +++ b/apps/accounts/automations/base/manager.py @@ -17,19 +17,19 @@ class VerifyHostCallbackMixin: def host_callback(self, host, asset=None, account=None, automation=None, path_dir=None, **kwargs): host = super().host_callback( - host, asset=asset, account=account, automation=automation, - path_dir=path_dir, **kwargs + host, asset=asset, account=account, + automation=automation, path_dir=path_dir, **kwargs ) if host.get('error'): return host accounts = asset.accounts.all() accounts = self.get_accounts(account, accounts) - inventory_hosts = [] + for account in accounts: h = deepcopy(host) - h['name'] += '_' + account.username + h['name'] += '(' + account.username + ')' self.host_account_mapper[h['name']] = account secret = account.secret diff --git a/apps/accounts/automations/change_secret/manager.py b/apps/accounts/automations/change_secret/manager.py index 971877c5f..4a8e548a3 100644 --- a/apps/accounts/automations/change_secret/manager.py +++ b/apps/accounts/automations/change_secret/manager.py @@ -93,7 +93,7 @@ class ChangeSecretManager(AccountBasePlaybookManager): host['secret_type'] = self.secret_type for account in accounts: h = deepcopy(host) - h['name'] += '_' + account.username + h['name'] += '(' + account.username + ')' new_secret = self.get_secret() recorder = ChangeSecretRecord( diff --git a/apps/accounts/automations/push_account/manager.py b/apps/accounts/automations/push_account/manager.py index c974106a6..12d89e7ed 100644 --- a/apps/accounts/automations/push_account/manager.py +++ b/apps/accounts/automations/push_account/manager.py @@ -63,7 +63,7 @@ class PushAccountManager(ChangeSecretManager, AccountBasePlaybookManager): host['secret_type'] = self.secret_type for account in accounts: h = deepcopy(host) - h['name'] += '_' + account.username + h['name'] += '(' + account.username + ')' new_secret = self.get_secret() self.name_recorder_mapper[h['name']] = { diff --git a/apps/accounts/tasks/common.py b/apps/accounts/tasks/common.py index 52f2d13b4..4582322c3 100644 --- a/apps/accounts/tasks/common.py +++ b/apps/accounts/tasks/common.py @@ -9,7 +9,7 @@ def quickstart_automation_by_snapshot(task_name, tp, task_snapshot=None): data = generate_automation_execution_data(task_name, tp, task_snapshot) pk = data['id'] - if AutomationExecution.objects.exists(id=pk): + if AutomationExecution.objects.filter(id=pk).exists(): data['id'] = str(uuid.uuid4()) execution = AutomationExecution.objects.create( diff --git a/apps/accounts/tasks/push_account.py b/apps/accounts/tasks/push_account.py index ab7832b2f..10dd4ce64 100644 --- a/apps/accounts/tasks/push_account.py +++ b/apps/accounts/tasks/push_account.py @@ -1,5 +1,4 @@ from celery import shared_task -from collections import defaultdict from django.utils.translation import gettext_noop, ugettext_lazy as _ from accounts.const import AutomationTypes @@ -21,20 +20,15 @@ def push_accounts_to_assets_task(account_ids): from accounts.models import Account accounts = Account.objects.filter(id__in=account_ids) - task_name = gettext_noop("Push accounts to assets") task_name = PushAccountAutomation.generate_unique_name(task_name) - account_asset_mapper = defaultdict(set) for account in accounts: - account_asset_mapper[account.username].add(account.asset) - - for username, assets in account_asset_mapper.items(): task_snapshot = { 'secret': account.secret, 'secret_type': account.secret_type, 'accounts': [account.username], - 'assets': asset_ids, + 'assets': [str(account.asset_id)], } tp = AutomationTypes.push_account - quickstart_automation_by_snapshot(task_name, tp, task_snapshot) \ No newline at end of file + quickstart_automation_by_snapshot(task_name, tp, task_snapshot) diff --git a/apps/accounts/tasks/verify_account.py b/apps/accounts/tasks/verify_account.py index 8bb656e29..efc6bb09d 100644 --- a/apps/accounts/tasks/verify_account.py +++ b/apps/accounts/tasks/verify_account.py @@ -26,15 +26,22 @@ def verify_connectivity_util(assets, tp, accounts, task_name): @org_aware_func("assets") -def verify_accounts_connectivity_util(accounts, assets, task_name): - gateway_assets = assets.filter(platform__name=GATEWAY_NAME) +def verify_accounts_connectivity_util(accounts, task_name): + from assets.models import Asset + + asset_ids = [a.asset_id for a in accounts] + assets = Asset.objects.filter(id__in=asset_ids) + + gateways = assets.filter(platform__name=GATEWAY_NAME) verify_connectivity_util( - gateway_assets, AutomationTypes.verify_gateway_account, accounts, task_name + gateways, AutomationTypes.verify_gateway_account, + accounts, task_name ) - non_gateway_assets = assets.exclude(platform__name=GATEWAY_NAME) + common_assets = assets.exclude(platform__name=GATEWAY_NAME) verify_connectivity_util( - non_gateway_assets, AutomationTypes.verify_account, accounts, task_name + common_assets, AutomationTypes.verify_account, + accounts, task_name ) @@ -42,11 +49,9 @@ def verify_accounts_connectivity_util(accounts, assets, task_name): queue="ansible", verbose_name=_('Verify asset account availability'), activity_callback=lambda self, account_ids, asset_ids: (account_ids, None) ) -def verify_accounts_connectivity_task(account_ids, asset_ids): - from assets.models import Asset +def verify_accounts_connectivity_task(account_ids): from accounts.models import Account, VerifyAccountAutomation - assets = Asset.objects.filter(id__in=asset_ids) accounts = Account.objects.filter(id__in=account_ids) task_name = gettext_noop("Verify accounts connectivity") task_name = VerifyAccountAutomation.generate_unique_name(task_name) - return verify_accounts_connectivity_util(accounts, assets, task_name) + return verify_accounts_connectivity_util(accounts, task_name) diff --git a/apps/assets/api/node.py b/apps/assets/api/node.py index 3658a29f1..9a60c636f 100644 --- a/apps/assets/api/node.py +++ b/apps/assets/api/node.py @@ -103,7 +103,7 @@ class NodeAddAssetsApi(generics.UpdateAPIView): instance = None permission_classes = (RBACPermission,) rbac_perms = { - 'PUT': 'assets.add_assettonode', + 'PUT': 'assets.change_assettonode', } def perform_update(self, serializer): @@ -118,7 +118,7 @@ class NodeRemoveAssetsApi(generics.UpdateAPIView): instance = None permission_classes = (RBACPermission,) rbac_perms = { - 'PUT': 'assets.remove_assetfromnode', + 'PUT': 'assets.change_assetfromnode', } def perform_update(self, serializer): @@ -140,7 +140,7 @@ class MoveAssetsToNodeApi(generics.UpdateAPIView): instance = None permission_classes = (RBACPermission,) rbac_perms = { - 'PUT': 'assets.move_assettonode', + 'PUT': 'assets.change_assettonode', } def perform_update(self, serializer): diff --git a/apps/assets/automations/base/manager.py b/apps/assets/automations/base/manager.py index 9c7ac4fd1..0f9949dce 100644 --- a/apps/assets/automations/base/manager.py +++ b/apps/assets/automations/base/manager.py @@ -62,6 +62,8 @@ class BasePlaybookManager: ) if not os.path.exists(path): os.makedirs(path, exist_ok=True, mode=0o755) + if settings.DEBUG_DEV: + logger.debug('Ansible runtime dir: {}'.format(path)) return path @staticmethod diff --git a/apps/assets/automations/ping_gateway/manager.py b/apps/assets/automations/ping_gateway/manager.py index d03e5d22d..b3f243fdb 100644 --- a/apps/assets/automations/ping_gateway/manager.py +++ b/apps/assets/automations/ping_gateway/manager.py @@ -33,7 +33,7 @@ class PingGatewayManager: err = _('No account') return False, err - print('Test account: {}'.format(account)) + print('- ' + _('Asset, {}, using account {}').format(gateway, account)) try: proxy.connect( gateway.address, diff --git a/apps/assets/migrations/0111_alter_asset_options.py b/apps/assets/migrations/0111_alter_asset_options.py new file mode 100644 index 000000000..a1e5c3097 --- /dev/null +++ b/apps/assets/migrations/0111_alter_asset_options.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.14 on 2023-02-21 04:55 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0110_auto_20230220_1051'), + ] + + operations = [ + migrations.AlterModelOptions( + name='asset', + options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetaccount', 'Can push account to asset'), ('test_account', 'Can verify account'), ('match_asset', 'Can match asset'), ('change_assettonode', 'Can change asset nodes')], 'verbose_name': 'Asset'}, + ), + ] diff --git a/apps/assets/models/asset/common.py b/apps/assets/models/asset/common.py index 8fd2d8a2c..4008da5d4 100644 --- a/apps/assets/models/asset/common.py +++ b/apps/assets/models/asset/common.py @@ -284,7 +284,5 @@ class Asset(NodesRelationMixin, AbsConnectivity, JMSOrgBaseModel): ('push_assetaccount', _('Can push account to asset')), ('test_account', _('Can verify account')), ('match_asset', _('Can match asset')), - ('add_assettonode', _('Add asset to node')), - ('move_assettonode', _('Move asset to node')), - ('remove_assetfromnode', _('Remove asset from node')) + ('change_assettonode', _('Can change asset nodes')), ] diff --git a/apps/assets/models/domain.py b/apps/assets/models/domain.py index dfb0e32fe..6dd5e3c4f 100644 --- a/apps/assets/models/domain.py +++ b/apps/assets/models/domain.py @@ -30,11 +30,11 @@ class Domain(JMSOrgBaseModel): def random_gateway(self): gateways = [gw for gw in self.active_gateways if gw.is_connective] + if not gateways: - logger.warn(f'Gateway all bad. domain={self}, gateway_num={len(gateways)}.') gateways = self.active_gateways if not gateways: - logger.warn(f'Not active gateway. domain={self}') + logger.warn(f'Not active gateway, domain={self}, pass') return None return random.choice(gateways) diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 01cdbd87d..5aec90466 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -101,7 +101,7 @@ class JMSInventory: def asset_to_host(self, asset, account, automation, protocols, platform): host = { - 'name': '{}'.format(asset.name), + 'name': '{}'.format(asset.name.replace(' ', '_')), 'jms_asset': { 'id': str(asset.id), 'name': asset.name, 'address': asset.address, 'type': asset.type, 'category': asset.category, diff --git a/apps/ops/signal_handlers.py b/apps/ops/signal_handlers.py index 7d4e15789..faba5c9eb 100644 --- a/apps/ops/signal_handlers.py +++ b/apps/ops/signal_handlers.py @@ -46,9 +46,25 @@ def sync_registered_tasks(*args, **kwargs): @receiver(django_ready) def check_registered_tasks(*args, **kwargs): attrs = ['verbose_name', 'activity_callback'] + ignores = [ + 'users.tasks.check_user_expired_periodic', 'ops.tasks.clean_celery_periodic_tasks', + 'terminal.tasks.delete_terminal_status_period', 'ops.tasks.check_server_performance_period', + 'settings.tasks.ldap.import_ldap_user', 'users.tasks.check_password_expired', + 'assets.tasks.nodes_amount.check_node_assets_amount_task', 'notifications.notifications.publish_task', + 'perms.tasks.check_asset_permission_will_expired', + 'ops.tasks.create_or_update_registered_periodic_tasks', 'perms.tasks.check_asset_permission_expired', + 'settings.tasks.ldap.import_ldap_user_periodic', 'users.tasks.check_password_expired_periodic', + 'common.utils.verify_code.send_async', 'assets.tasks.nodes_amount.check_node_assets_amount_period_task', + 'users.tasks.check_user_expired', 'orgs.tasks.refresh_org_cache_task', + 'terminal.tasks.upload_session_replay_to_external_storage', 'terminal.tasks.clean_orphan_session', + 'audits.tasks.clean_audits_log_period', 'authentication.tasks.clean_django_sessions' + ] + for name, task in app.tasks.items(): if name.startswith('celery.'): continue + if name in ignores: + continue for attr in attrs: if not hasattr(task, attr): print('>>> Task {} has no attribute {}'.format(name, attr)) From f4cc03434ffe9ec32c85de29893ffdc1be6e8778 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 21 Feb 2023 13:11:56 +0800 Subject: [PATCH 5/8] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20rbac=20asset?= =?UTF-8?q?=20nodes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0108_alter_platform_charset.py | 25 ++ .../migrations/0109_alter_asset_options.py | 2 +- .../migrations/0110_auto_20230220_1051.py | 38 --- .../migrations/0111_alter_asset_options.py | 17 -- apps/assets/models/asset/common.py | 2 +- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 282 +++++++++--------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 282 +++++++++--------- apps/rbac/const.py | 2 + 10 files changed, 319 insertions(+), 339 deletions(-) delete mode 100644 apps/assets/migrations/0110_auto_20230220_1051.py delete mode 100644 apps/assets/migrations/0111_alter_asset_options.py diff --git a/apps/assets/migrations/0108_alter_platform_charset.py b/apps/assets/migrations/0108_alter_platform_charset.py index 9fd978466..d413068f1 100644 --- a/apps/assets/migrations/0108_alter_platform_charset.py +++ b/apps/assets/migrations/0108_alter_platform_charset.py @@ -15,4 +15,29 @@ class Migration(migrations.Migration): name='charset', field=models.CharField(choices=[('utf-8', 'UTF-8'), ('gbk', 'GBK')], default='utf-8', max_length=8, verbose_name='Charset'), ), + migrations.AddField( + model_name='platform', + name='created_by', + field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Created by'), + ), + migrations.AddField( + model_name='platform', + name='date_created', + field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created'), + ), + migrations.AddField( + model_name='platform', + name='date_updated', + field=models.DateTimeField(auto_now=True, verbose_name='Date updated'), + ), + migrations.AddField( + model_name='platform', + name='updated_by', + field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Updated by'), + ), + migrations.AlterField( + model_name='platform', + name='comment', + field=models.TextField(blank=True, default='', verbose_name='Comment'), + ), ] diff --git a/apps/assets/migrations/0109_alter_asset_options.py b/apps/assets/migrations/0109_alter_asset_options.py index 3b9bc25a2..859b1ca0c 100644 --- a/apps/assets/migrations/0109_alter_asset_options.py +++ b/apps/assets/migrations/0109_alter_asset_options.py @@ -12,6 +12,6 @@ class Migration(migrations.Migration): operations = [ migrations.AlterModelOptions( name='asset', - options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetaccount', 'Can push account to asset'), ('test_account', 'Can verify account'), ('match_asset', 'Can match asset'), ('add_assettonode', 'Add asset to node'), ('move_assettonode', 'Move asset to node'), ('remove_assetfromnode', 'Remove asset from node')], 'verbose_name': 'Asset'}, + options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetaccount', 'Can push account to asset'), ('test_account', 'Can verify account'), ('match_asset', 'Can match asset'), ('change_assettonode', 'Can change asset nodes')], 'verbose_name': 'Asset'}, ), ] diff --git a/apps/assets/migrations/0110_auto_20230220_1051.py b/apps/assets/migrations/0110_auto_20230220_1051.py deleted file mode 100644 index a94fd7d03..000000000 --- a/apps/assets/migrations/0110_auto_20230220_1051.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 3.2.14 on 2023-02-20 02:51 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0109_alter_asset_options'), - ] - - operations = [ - migrations.AddField( - model_name='platform', - name='created_by', - field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Created by'), - ), - migrations.AddField( - model_name='platform', - name='date_created', - field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created'), - ), - migrations.AddField( - model_name='platform', - name='date_updated', - field=models.DateTimeField(auto_now=True, verbose_name='Date updated'), - ), - migrations.AddField( - model_name='platform', - name='updated_by', - field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Updated by'), - ), - migrations.AlterField( - model_name='platform', - name='comment', - field=models.TextField(blank=True, default='', verbose_name='Comment'), - ), - ] diff --git a/apps/assets/migrations/0111_alter_asset_options.py b/apps/assets/migrations/0111_alter_asset_options.py deleted file mode 100644 index a1e5c3097..000000000 --- a/apps/assets/migrations/0111_alter_asset_options.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2.14 on 2023-02-21 04:55 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0110_auto_20230220_1051'), - ] - - operations = [ - migrations.AlterModelOptions( - name='asset', - options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetaccount', 'Can push account to asset'), ('test_account', 'Can verify account'), ('match_asset', 'Can match asset'), ('change_assettonode', 'Can change asset nodes')], 'verbose_name': 'Asset'}, - ), - ] diff --git a/apps/assets/models/asset/common.py b/apps/assets/models/asset/common.py index 4008da5d4..3e013fa0d 100644 --- a/apps/assets/models/asset/common.py +++ b/apps/assets/models/asset/common.py @@ -284,5 +284,5 @@ class Asset(NodesRelationMixin, AbsConnectivity, JMSOrgBaseModel): ('push_assetaccount', _('Can push account to asset')), ('test_account', _('Can verify account')), ('match_asset', _('Can match asset')), - ('change_assettonode', _('Can change asset nodes')), + ('change_assetnodes', _('Can change asset nodes')), ] diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index f75ed9b82..77a9fd388 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8285be68ee7edb5423cf973c1c96a3659b75b40566c07a1557a17d59fcaf294d -size 136019 +oid sha256:694d0090ced3dd431fd632329c8d081d696baae99b4e7561ccc5abc5343f82ca +size 135571 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 73b8168db..0f9b9d529 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-02-20 15:19+0800\n" +"POT-Creation-Date: 2023-02-21 13:00+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -158,8 +158,9 @@ msgstr "作成してプッシュ" msgid "Only create" msgstr "作成のみ" -#: accounts/models/account.py:47 accounts/models/gathered_account.py:14 -#: accounts/serializers/account/account.py:97 +#: accounts/models/account.py:47 +#: accounts/models/automations/gather_account.py:16 +#: accounts/serializers/account/account.py:95 #: accounts/serializers/account/gathered_account.py:10 #: accounts/serializers/automations/change_secret.py:107 #: accounts/serializers/automations/change_secret.py:127 @@ -175,7 +176,7 @@ msgstr "作成のみ" msgid "Asset" msgstr "資産" -#: accounts/models/account.py:51 accounts/serializers/account/account.py:101 +#: accounts/models/account.py:51 accounts/serializers/account/account.py:99 #: authentication/serializers/connect_token_secret.py:50 msgid "Su from" msgstr "から切り替え" @@ -185,7 +186,7 @@ msgstr "から切り替え" msgid "Version" msgstr "バージョン" -#: accounts/models/account.py:55 accounts/serializers/account/account.py:98 +#: accounts/models/account.py:55 accounts/serializers/account/account.py:96 #: users/models/user.py:768 msgid "Source" msgstr "ソース" @@ -228,7 +229,7 @@ msgstr "アセット アカウント テンプレートのパスワードを変 #: accounts/models/automations/backup_account.py:27 #: accounts/models/automations/change_secret.py:47 -#: accounts/serializers/account/backup.py:32 +#: accounts/serializers/account/backup.py:34 #: accounts/serializers/automations/change_secret.py:56 msgid "Recipient" msgstr "受信者" @@ -240,7 +241,7 @@ msgstr "アカウントバックアップ計画" #: accounts/models/automations/backup_account.py:83 #: assets/models/automations/base.py:114 audits/models.py:55 -#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:119 +#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:122 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:108 #: terminal/models/session/session.py:45 #: tickets/models/ticket/apply_application.py:30 @@ -259,7 +260,7 @@ msgid "Account backup snapshot" msgstr "アカウントのバックアップスナップショット" #: accounts/models/automations/backup_account.py:94 -#: accounts/serializers/account/backup.py:40 +#: accounts/serializers/account/backup.py:42 #: accounts/serializers/automations/base.py:44 #: assets/models/automations/base.py:121 #: assets/serializers/automations/base.py:40 @@ -319,7 +320,7 @@ msgid "Can add push account execution" msgstr "プッシュ アカウントの作成の実行" #: accounts/models/automations/change_secret.py:17 accounts/models/base.py:36 -#: accounts/serializers/account/account.py:134 +#: accounts/serializers/account/account.py:132 #: accounts/serializers/account/base.py:16 #: accounts/serializers/automations/change_secret.py:46 #: authentication/serializers/connect_token_secret.py:41 @@ -327,12 +328,7 @@ msgstr "プッシュ アカウントの作成の実行" msgid "Secret type" msgstr "鍵の種類" -#: accounts/models/automations/change_secret.py:21 -#: accounts/serializers/automations/change_secret.py:40 -msgid "Secret strategy" -msgstr "鍵ポリシー" - -#: accounts/models/automations/change_secret.py:23 +#: accounts/models/automations/change_secret.py:19 #: accounts/models/automations/change_secret.py:72 accounts/models/base.py:38 #: authentication/models/temp_token.py:10 #: authentication/templates/authentication/_access_key_modal.html:31 @@ -340,6 +336,11 @@ msgstr "鍵ポリシー" msgid "Secret" msgstr "ひみつ" +#: accounts/models/automations/change_secret.py:22 +#: accounts/serializers/automations/change_secret.py:40 +msgid "Secret strategy" +msgstr "鍵ポリシー" + #: accounts/models/automations/change_secret.py:24 msgid "Password rules" msgstr "パスワードルール" @@ -362,7 +363,7 @@ msgstr "開始日" #: accounts/models/automations/change_secret.py:74 #: assets/models/automations/base.py:115 ops/models/base.py:56 -#: ops/models/celery.py:64 ops/models/job.py:120 +#: ops/models/celery.py:64 ops/models/job.py:123 #: terminal/models/applet/host.py:109 msgid "Date finished" msgstr "終了日" @@ -376,20 +377,19 @@ msgstr "間違い" msgid "Change secret record" msgstr "パスワード レコードの変更" +#: accounts/models/automations/gather_account.py:14 +msgid "Present" +msgstr "存在する" + #: accounts/models/automations/gather_account.py:15 -#: accounts/tasks/gather_accounts.py:29 -msgid "Gather asset accounts" -msgstr "アカウントのコレクション" +msgid "Date last login" +msgstr "最終ログイン日" -#: accounts/models/automations/push_account.py:13 -msgid "Triggers" -msgstr "トリガー方式" - -#: accounts/models/automations/push_account.py:14 accounts/models/base.py:34 -#: accounts/models/gathered_account.py:15 acls/serializers/base.py:18 -#: acls/serializers/base.py:49 assets/models/_user.py:23 audits/models.py:157 -#: authentication/forms.py:25 authentication/forms.py:27 -#: authentication/models/temp_token.py:9 +#: accounts/models/automations/gather_account.py:17 +#: accounts/models/automations/push_account.py:13 accounts/models/base.py:34 +#: acls/serializers/base.py:18 acls/serializers/base.py:49 +#: assets/models/_user.py:23 audits/models.py:157 authentication/forms.py:25 +#: authentication/forms.py:27 authentication/models/temp_token.py:9 #: authentication/templates/authentication/_msg_different_city.html:9 #: authentication/templates/authentication/_msg_oauth_bind.html:9 #: users/forms/profile.py:32 users/forms/profile.py:112 @@ -398,7 +398,24 @@ msgstr "トリガー方式" msgid "Username" msgstr "ユーザー名" -#: accounts/models/automations/push_account.py:15 acls/models/base.py:81 +#: accounts/models/automations/gather_account.py:18 +msgid "Address last login" +msgstr "最終ログインアドレス" + +#: accounts/models/automations/gather_account.py:25 rbac/tree.py:50 +msgid "Gather account" +msgstr "アカウントを集める" + +#: accounts/models/automations/gather_account.py:41 +#: accounts/tasks/gather_accounts.py:29 +msgid "Gather asset accounts" +msgstr "アカウントのコレクション" + +#: accounts/models/automations/push_account.py:12 +msgid "Triggers" +msgstr "トリガー方式" + +#: accounts/models/automations/push_account.py:14 acls/models/base.py:81 #: acls/serializers/base.py:81 acls/serializers/login_acl.py:25 #: assets/models/cmd_filter.py:81 audits/models.py:65 audits/serializers.py:82 #: authentication/serializers/connect_token_secret.py:109 @@ -406,7 +423,7 @@ msgstr "ユーザー名" msgid "Action" msgstr "アクション" -#: accounts/models/automations/push_account.py:41 +#: accounts/models/automations/push_account.py:40 msgid "Push asset account" msgstr "アカウントプッシュ" @@ -420,14 +437,13 @@ msgstr "アカウントの確認" #: assets/models/asset/common.py:90 assets/models/asset/common.py:102 #: assets/models/cmd_filter.py:21 assets/models/domain.py:18 #: assets/models/group.py:20 assets/models/label.py:18 -#: assets/models/platform.py:20 assets/models/platform.py:74 +#: assets/models/platform.py:21 assets/models/platform.py:76 #: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142 -#: assets/serializers/platform.py:131 +#: assets/serializers/platform.py:132 #: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21 #: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:26 ops/models/playbook.py:23 ops/serializers/job.py:19 -#: ops/serializers/playbook.py:19 orgs/models.py:69 -#: perms/models/asset_permission.py:56 rbac/models/role.py:29 +#: orgs/models.py:69 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:33 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:26 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:90 @@ -450,22 +466,6 @@ msgstr "特権アカウント" msgid "Is active" msgstr "アクティブです。" -#: accounts/models/gathered_account.py:12 -msgid "Present" -msgstr "存在する" - -#: accounts/models/gathered_account.py:13 -msgid "Date last login" -msgstr "最終ログイン日" - -#: accounts/models/gathered_account.py:16 -msgid "Address last login" -msgstr "最終ログインアドレス" - -#: accounts/models/gathered_account.py:23 rbac/tree.py:50 -msgid "Gather account" -msgstr "アカウントを集める" - #: accounts/notifications.py:8 msgid "Notification of account backup route task results" msgstr "アカウントバックアップルートタスクの結果の通知" @@ -507,35 +507,35 @@ msgstr "" "{} -暗号化変更タスクが完了しました: 暗号化パスワードが設定されていません-個人" "情報にアクセスしてください-> ファイル暗号化パスワードを設定してください" -#: accounts/serializers/account/account.py:67 +#: accounts/serializers/account/account.py:65 #: assets/serializers/asset/common.py:66 settings/serializers/auth/sms.py:75 msgid "Template" msgstr "テンプレート" -#: accounts/serializers/account/account.py:70 +#: accounts/serializers/account/account.py:68 #: assets/serializers/asset/common.py:63 msgid "Push now" msgstr "今すぐプッシュ" -#: accounts/serializers/account/account.py:72 +#: accounts/serializers/account/account.py:70 #: accounts/serializers/account/base.py:62 msgid "Has secret" msgstr "エスクローされたパスワード" -#: accounts/serializers/account/account.py:77 applications/models.py:11 -#: assets/models/label.py:21 assets/models/platform.py:75 +#: accounts/serializers/account/account.py:75 applications/models.py:11 +#: assets/models/label.py:21 assets/models/platform.py:77 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 -#: assets/serializers/platform.py:93 assets/serializers/platform.py:132 +#: assets/serializers/platform.py:93 assets/serializers/platform.py:133 #: perms/serializers/user_permission.py:25 settings/models.py:35 #: tickets/models/ticket/apply_application.py:13 msgid "Category" msgstr "カテゴリ" -#: accounts/serializers/account/account.py:78 +#: accounts/serializers/account/account.py:76 #: accounts/serializers/automations/base.py:43 acls/models/command_acl.py:24 #: acls/serializers/command_acl.py:18 applications/models.py:14 #: assets/models/_user.py:50 assets/models/automations/base.py:20 -#: assets/models/cmd_filter.py:74 assets/models/platform.py:76 +#: assets/models/cmd_filter.py:74 assets/models/platform.py:78 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:92 #: audits/serializers.py:48 #: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:37 @@ -550,28 +550,28 @@ msgstr "カテゴリ" msgid "Type" msgstr "タイプ" -#: accounts/serializers/account/account.py:93 +#: accounts/serializers/account/account.py:91 msgid "Asset not found" msgstr "資産が存在しません" -#: accounts/serializers/account/backup.py:30 +#: accounts/serializers/account/backup.py:31 #: accounts/serializers/automations/base.py:36 #: assets/serializers/automations/base.py:34 ops/mixin.py:23 ops/mixin.py:103 #: settings/serializers/auth/ldap.py:66 msgid "Periodic perform" msgstr "定期的なパフォーマンス" -#: accounts/serializers/account/backup.py:31 +#: accounts/serializers/account/backup.py:32 #: accounts/serializers/automations/base.py:37 msgid "Executed amount" msgstr "実行回数" -#: accounts/serializers/account/backup.py:33 +#: accounts/serializers/account/backup.py:35 #: accounts/serializers/automations/change_secret.py:57 msgid "Currently only mail sending is supported" msgstr "現在、メール送信のみがサポートされています" -#: accounts/serializers/account/backup.py:35 +#: accounts/serializers/account/backup.py:37 msgid "Asset type" msgstr "資産タイプ" @@ -644,7 +644,7 @@ msgstr "失敗しました" msgid "Account execute automation" msgstr "アカウント実行の自動化" -#: accounts/tasks/backup_account.py:24 +#: accounts/tasks/backup_account.py:25 msgid "Execute account backup plan" msgstr "アカウントのバックアップ計画を実施する" @@ -652,15 +652,15 @@ msgstr "アカウントのバックアップ計画を実施する" msgid "Gather assets accounts" msgstr "資産の口座番号を収集する" -#: accounts/tasks/push_account.py:30 accounts/tasks/push_account.py:37 +#: accounts/tasks/push_account.py:15 accounts/tasks/push_account.py:23 msgid "Push accounts to assets" msgstr "アカウントをアセットにプッシュ:" -#: accounts/tasks/verify_account.py:42 +#: accounts/tasks/verify_account.py:49 msgid "Verify asset account availability" msgstr "アセット アカウントの可用性を確認する" -#: accounts/tasks/verify_account.py:50 +#: accounts/tasks/verify_account.py:55 msgid "Verify accounts connectivity" msgstr "アカウント接続のテスト" @@ -896,13 +896,13 @@ msgstr "アプリケーション" msgid "Can match application" msgstr "アプリケーションを一致させることができます" -#: assets/api/asset/asset.py:145 +#: assets/api/asset/asset.py:144 msgid "Cannot create asset directly, you should create a host or other" msgstr "" "資産を直接作成することはできません。ホストまたはその他を作成する必要がありま" "す" -#: assets/api/domain.py:61 +#: assets/api/domain.py:60 msgid "Number required" msgstr "必要な数" @@ -922,7 +922,7 @@ msgstr "削除に失敗し、ノードにアセットが含まれています。 msgid "App assets" msgstr "アプリ資産" -#: assets/automations/base/manager.py:104 +#: assets/automations/base/manager.py:106 msgid "{} disabled" msgstr "{} 無効" @@ -931,6 +931,12 @@ msgstr "{} 無効" msgid "No account" msgstr "アカウントなし" +#: assets/automations/ping_gateway/manager.py:36 +#, fuzzy +#| msgid "Assets amount" +msgid "Asset, {}, using account {}" +msgstr "資産額" + #: assets/automations/ping_gateway/manager.py:55 #, python-brace-format msgid "Unable to connect to port {port} on {address}" @@ -1043,11 +1049,10 @@ msgstr "SSHパブリックキー" #: assets/models/_user.py:27 assets/models/cmd_filter.py:40 #: assets/models/cmd_filter.py:88 assets/models/group.py:23 -#: assets/models/platform.py:79 common/db/models.py:37 ops/models/adhoc.py:27 -#: ops/models/job.py:45 ops/models/playbook.py:26 rbac/models/role.py:37 -#: settings/models.py:38 terminal/models/applet/applet.py:35 -#: terminal/models/applet/applet.py:151 terminal/models/applet/host.py:110 -#: terminal/models/component/endpoint.py:24 +#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:45 +#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38 +#: terminal/models/applet/applet.py:35 terminal/models/applet/applet.py:151 +#: terminal/models/applet/host.py:110 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:100 #: terminal/models/session/session.py:47 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:756 @@ -1057,7 +1062,7 @@ msgstr "コメント" #: assets/models/_user.py:28 assets/models/automations/base.py:113 #: assets/models/cmd_filter.py:41 assets/models/group.py:22 -#: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:118 +#: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:121 #: users/models/user.py:943 msgid "Date created" msgstr "作成された日付" @@ -1149,7 +1154,7 @@ msgstr "システムユーザーに一致できます" msgid "Cloud" msgstr "クラウド サービス" -#: assets/models/asset/common.py:91 assets/models/platform.py:21 +#: assets/models/asset/common.py:91 assets/models/platform.py:22 #: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:68 #: xpack/plugins/cloud/serializers/account_attrs.py:73 msgid "Port" @@ -1159,7 +1164,7 @@ msgstr "ポート" msgid "Address" msgstr "アドレス" -#: assets/models/asset/common.py:104 assets/models/platform.py:111 +#: assets/models/asset/common.py:104 assets/models/platform.py:112 #: authentication/serializers/connect_token_secret.py:108 #: perms/serializers/user_permission.py:23 #: xpack/plugins/cloud/serializers/account_attrs.py:187 @@ -1197,16 +1202,8 @@ msgid "Can match asset" msgstr "アセットを一致させることができます" #: assets/models/asset/common.py:287 -msgid "Add asset to node" -msgstr "ノードにアセットを追加する" - -#: assets/models/asset/common.py:288 -msgid "Move asset to node" -msgstr "アセットをノードに移動する" - -#: assets/models/asset/common.py:289 -msgid "Remove asset from node" -msgstr "ノードからアセットを削除" +msgid "Can change asset nodes" +msgstr "資産ノードを変更できます" #: assets/models/asset/database.py:10 assets/serializers/asset/common.py:110 #: settings/serializers/email.py:37 @@ -1262,7 +1259,7 @@ msgid "Asset automation task" msgstr "アセットの自動化タスク" #: assets/models/automations/base.py:112 audits/models.py:177 -#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:111 +#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:114 #: terminal/models/applet/applet.py:150 terminal/models/applet/host.py:107 #: terminal/models/component/status.py:27 terminal/serializers/applet.py:17 #: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283 @@ -1330,7 +1327,7 @@ msgstr "ゲートウェイ" msgid "Asset group" msgstr "資産グループ" -#: assets/models/group.py:34 assets/models/platform.py:18 +#: assets/models/group.py:34 assets/models/platform.py:19 #: xpack/plugins/cloud/providers/nutanix.py:30 msgid "Default" msgstr "デフォルト" @@ -1387,91 +1384,91 @@ msgstr "ノード" msgid "Can match node" msgstr "ノードを一致させることができます" -#: assets/models/platform.py:19 +#: assets/models/platform.py:20 msgid "Required" msgstr "必要" -#: assets/models/platform.py:22 settings/serializers/settings.py:61 +#: assets/models/platform.py:23 settings/serializers/settings.py:61 #: users/templates/users/reset_password.html:29 msgid "Setting" msgstr "設定" -#: assets/models/platform.py:41 audits/const.py:47 settings/models.py:37 +#: assets/models/platform.py:42 audits/const.py:47 settings/models.py:37 #: terminal/serializers/applet_host.py:29 msgid "Enabled" msgstr "有効化" -#: assets/models/platform.py:42 +#: assets/models/platform.py:43 msgid "Ansible config" msgstr "Ansible 構成" -#: assets/models/platform.py:43 assets/serializers/platform.py:60 +#: assets/models/platform.py:44 assets/serializers/platform.py:60 msgid "Ping enabled" msgstr "アセット ディスカバリを有効にする" -#: assets/models/platform.py:44 assets/serializers/platform.py:61 +#: assets/models/platform.py:45 assets/serializers/platform.py:61 msgid "Ping method" msgstr "資産検出方法" -#: assets/models/platform.py:45 assets/models/platform.py:58 +#: assets/models/platform.py:46 assets/models/platform.py:59 #: assets/serializers/platform.py:62 msgid "Gather facts enabled" msgstr "資産情報の収集を有効にする" -#: assets/models/platform.py:46 assets/models/platform.py:60 +#: assets/models/platform.py:47 assets/models/platform.py:61 #: assets/serializers/platform.py:63 msgid "Gather facts method" msgstr "情報収集の方法" -#: assets/models/platform.py:47 assets/serializers/platform.py:66 +#: assets/models/platform.py:48 assets/serializers/platform.py:66 msgid "Change secret enabled" msgstr "パスワードの変更が有効" -#: assets/models/platform.py:49 assets/serializers/platform.py:67 +#: assets/models/platform.py:50 assets/serializers/platform.py:67 msgid "Change secret method" msgstr "パスワード変更モード" -#: assets/models/platform.py:51 assets/serializers/platform.py:68 +#: assets/models/platform.py:52 assets/serializers/platform.py:68 msgid "Push account enabled" msgstr "アカウントのプッシュを有効にする" -#: assets/models/platform.py:53 assets/serializers/platform.py:69 +#: assets/models/platform.py:54 assets/serializers/platform.py:69 msgid "Push account method" msgstr "アカウントプッシュ方式" -#: assets/models/platform.py:55 assets/serializers/platform.py:64 +#: assets/models/platform.py:56 assets/serializers/platform.py:64 msgid "Verify account enabled" msgstr "アカウントの確認をオンにする" -#: assets/models/platform.py:57 assets/serializers/platform.py:65 +#: assets/models/platform.py:58 assets/serializers/platform.py:65 msgid "Verify account method" msgstr "アカウント認証方法" -#: assets/models/platform.py:77 tickets/models/ticket/general.py:300 +#: assets/models/platform.py:79 tickets/models/ticket/general.py:300 msgid "Meta" msgstr "メタ" -#: assets/models/platform.py:78 +#: assets/models/platform.py:80 msgid "Internal" msgstr "ビルトイン" -#: assets/models/platform.py:82 assets/serializers/platform.py:90 +#: assets/models/platform.py:83 assets/serializers/platform.py:90 msgid "Charset" msgstr "シャーセット" -#: assets/models/platform.py:84 assets/serializers/platform.py:117 +#: assets/models/platform.py:85 assets/serializers/platform.py:118 msgid "Domain enabled" msgstr "ドメインを有効にする" -#: assets/models/platform.py:86 assets/serializers/platform.py:116 +#: assets/models/platform.py:87 assets/serializers/platform.py:117 msgid "Su enabled" msgstr "アカウントの切り替えを有効にする" -#: assets/models/platform.py:87 assets/serializers/platform.py:100 +#: assets/models/platform.py:88 assets/serializers/platform.py:100 msgid "Su method" msgstr "アカウントの切り替え方法" -#: assets/models/platform.py:89 assets/serializers/platform.py:97 +#: assets/models/platform.py:90 assets/serializers/platform.py:97 msgid "Automation" msgstr "オートメーション" @@ -1620,7 +1617,7 @@ msgstr "アカウントの収集方法" msgid "Primary" msgstr "主要" -#: assets/serializers/platform.py:118 +#: assets/serializers/platform.py:119 msgid "Default Domain" msgstr "デフォルト ドメイン" @@ -1628,7 +1625,7 @@ msgstr "デフォルト ドメイン" msgid "Test assets connectivity " msgstr "アセット接続のテスト。" -#: assets/signal_handlers/asset.py:35 +#: assets/signal_handlers/asset.py:36 msgid "Gather asset hardware info" msgstr "資産ハードウェア情報の収集" @@ -1781,8 +1778,8 @@ msgstr "セッションログ" msgid "Login log" msgstr "ログインログ" -#: audits/const.py:42 ops/signal_handlers.py:86 -#: terminal/models/applet/host.py:111 terminal/models/component/task.py:24 +#: audits/const.py:42 terminal/models/applet/host.py:111 +#: terminal/models/component/task.py:24 msgid "Task" msgstr "タスク" @@ -1981,7 +1978,7 @@ msgstr "ACL アクションはレビューです" msgid "Current user not support mfa type: {}" msgstr "現在のユーザーはmfaタイプをサポートしていません: {}" -#: authentication/api/password.py:31 terminal/api/session/session.py:244 +#: authentication/api/password.py:31 terminal/api/session/session.py:247 #: users/views/profile/reset.py:44 msgid "User does not exist: {}" msgstr "ユーザーが存在しない: {}" @@ -3341,7 +3338,7 @@ msgid "Args" msgstr "アルグ" #: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53 -#: ops/models/job.py:38 ops/models/job.py:117 ops/models/playbook.py:25 +#: ops/models/job.py:38 ops/models/job.py:120 ops/models/playbook.py:25 #: terminal/models/session/sharing.py:23 msgid "Creator" msgstr "作成者" @@ -3358,12 +3355,12 @@ msgstr "最後の実行" msgid "Date last run" msgstr "最終実行日" -#: ops/models/base.py:51 ops/models/job.py:115 +#: ops/models/base.py:51 ops/models/job.py:118 #: xpack/plugins/cloud/models.py:162 msgid "Result" msgstr "結果" -#: ops/models/base.py:52 ops/models/job.py:116 +#: ops/models/base.py:52 ops/models/job.py:119 msgid "Summary" msgstr "概要" @@ -3427,23 +3424,23 @@ msgstr "ユーザーとして実行" msgid "Runas policy" msgstr "ユーザー ポリシー" -#: ops/models/job.py:103 +#: ops/models/job.py:106 msgid "Job" msgstr "ジョブ#ジョブ#" -#: ops/models/job.py:114 +#: ops/models/job.py:117 msgid "Parameters" msgstr "パラメータ" -#: ops/models/job.py:122 +#: ops/models/job.py:125 msgid "Material" msgstr "" -#: ops/models/job.py:124 +#: ops/models/job.py:127 msgid "Material Type" msgstr "" -#: ops/models/job.py:361 +#: ops/models/job.py:364 msgid "Job Execution" msgstr "ジョブ実行" @@ -3559,18 +3556,18 @@ msgstr "ジョブのID" msgid "Name of the job" msgstr "ジョブの名前" -#: orgs/api.py:63 +#: orgs/api.py:62 msgid "The current organization ({}) cannot be deleted" msgstr "現在の組織 ({}) は削除できません" -#: orgs/api.py:68 +#: orgs/api.py:67 msgid "" "LDAP synchronization is set to the current organization. Please switch to " "another organization before deleting" msgstr "" "LDAP 同期は現在の組織に設定されます。削除する前に別の組織に切り替えてください" -#: orgs/api.py:78 +#: orgs/api.py:77 msgid "The organization have resource ({}) cannot be deleted" msgstr "組織のリソース ({}) は削除できません" @@ -5337,15 +5334,15 @@ msgstr "テスト失敗: アカウントが無効" msgid "Have online sessions" msgstr "オンラインセッションを持つ" -#: terminal/api/session/session.py:236 +#: terminal/api/session/session.py:239 msgid "Session does not exist: {}" msgstr "セッションが存在しません: {}" -#: terminal/api/session/session.py:239 +#: terminal/api/session/session.py:242 msgid "Session is finished or the protocol not supported" msgstr "セッションが終了したか、プロトコルがサポートされていません" -#: terminal/api/session/session.py:252 +#: terminal/api/session/session.py:255 msgid "User does not have permission" msgstr "ユーザーに権限がありません" @@ -6245,7 +6242,7 @@ msgstr "無効な承認アクション" msgid "This user is not authorized to approve this ticket" msgstr "このユーザーはこの作業指示を承認する権限がありません" -#: users/api/user.py:179 +#: users/api/user.py:178 msgid "Could not reset self otp, use profile reset instead" msgstr "自己otpをリセットできませんでした、代わりにプロファイルリセットを使用" @@ -7289,14 +7286,6 @@ msgstr "実行回数" msgid "Instance count" msgstr "インスタンス数" -#: xpack/plugins/cloud/tasks.py:27 -msgid "Run sync instance task" -msgstr "同期インスタンス タスクを実行する" - -#: xpack/plugins/cloud/tasks.py:41 -msgid "Period clean sync instance task execution" -msgstr "同期インスタンス タスクの実行記録を定期的にクリアする" - #: xpack/plugins/cloud/utils.py:69 msgid "Account unavailable" msgstr "利用できないアカウント" @@ -7364,3 +7353,18 @@ msgstr "究極のエディション" #: xpack/plugins/license/models.py:85 msgid "Community edition" msgstr "コミュニティ版" + +#~ msgid "Add asset to node" +#~ msgstr "ノードにアセットを追加する" + +#~ msgid "Move asset to node" +#~ msgstr "アセットをノードに移動する" + +#~ msgid "Remove asset from node" +#~ msgstr "ノードからアセットを削除" + +#~ msgid "Run sync instance task" +#~ msgstr "同期インスタンス タスクを実行する" + +#~ msgid "Period clean sync instance task execution" +#~ msgstr "同期インスタンス タスクの実行記録を定期的にクリアする" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 20a3f93dd..6feff0df0 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e078689bb42c8b769f77944c3498f367562da35346fcd0c6c2766c85e5107d1b -size 111727 +oid sha256:c18587f19a5d5723a65592162020f8e43b1f69572ec437a83ba914d636f0f32b +size 111452 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 88c19aeae..829aaee91 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-02-20 15:19+0800\n" +"POT-Creation-Date: 2023-02-21 13:00+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -157,8 +157,9 @@ msgstr "创建并推送" msgid "Only create" msgstr "仅创建" -#: accounts/models/account.py:47 accounts/models/gathered_account.py:14 -#: accounts/serializers/account/account.py:97 +#: accounts/models/account.py:47 +#: accounts/models/automations/gather_account.py:16 +#: accounts/serializers/account/account.py:95 #: accounts/serializers/account/gathered_account.py:10 #: accounts/serializers/automations/change_secret.py:107 #: accounts/serializers/automations/change_secret.py:127 @@ -174,7 +175,7 @@ msgstr "仅创建" msgid "Asset" msgstr "资产" -#: accounts/models/account.py:51 accounts/serializers/account/account.py:101 +#: accounts/models/account.py:51 accounts/serializers/account/account.py:99 #: authentication/serializers/connect_token_secret.py:50 msgid "Su from" msgstr "切换自" @@ -184,7 +185,7 @@ msgstr "切换自" msgid "Version" msgstr "版本" -#: accounts/models/account.py:55 accounts/serializers/account/account.py:98 +#: accounts/models/account.py:55 accounts/serializers/account/account.py:96 #: users/models/user.py:768 msgid "Source" msgstr "来源" @@ -227,7 +228,7 @@ msgstr "可以更改资产账号模版密码" #: accounts/models/automations/backup_account.py:27 #: accounts/models/automations/change_secret.py:47 -#: accounts/serializers/account/backup.py:32 +#: accounts/serializers/account/backup.py:34 #: accounts/serializers/automations/change_secret.py:56 msgid "Recipient" msgstr "收件人" @@ -239,7 +240,7 @@ msgstr "账号备份计划" #: accounts/models/automations/backup_account.py:83 #: assets/models/automations/base.py:114 audits/models.py:55 -#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:119 +#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:122 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:108 #: terminal/models/session/session.py:45 #: tickets/models/ticket/apply_application.py:30 @@ -258,7 +259,7 @@ msgid "Account backup snapshot" msgstr "账号备份快照" #: accounts/models/automations/backup_account.py:94 -#: accounts/serializers/account/backup.py:40 +#: accounts/serializers/account/backup.py:42 #: accounts/serializers/automations/base.py:44 #: assets/models/automations/base.py:121 #: assets/serializers/automations/base.py:40 @@ -318,7 +319,7 @@ msgid "Can add push account execution" msgstr "创建推送账号执行" #: accounts/models/automations/change_secret.py:17 accounts/models/base.py:36 -#: accounts/serializers/account/account.py:134 +#: accounts/serializers/account/account.py:132 #: accounts/serializers/account/base.py:16 #: accounts/serializers/automations/change_secret.py:46 #: authentication/serializers/connect_token_secret.py:41 @@ -326,12 +327,7 @@ msgstr "创建推送账号执行" msgid "Secret type" msgstr "密文类型" -#: accounts/models/automations/change_secret.py:21 -#: accounts/serializers/automations/change_secret.py:40 -msgid "Secret strategy" -msgstr "密文策略" - -#: accounts/models/automations/change_secret.py:23 +#: accounts/models/automations/change_secret.py:19 #: accounts/models/automations/change_secret.py:72 accounts/models/base.py:38 #: authentication/models/temp_token.py:10 #: authentication/templates/authentication/_access_key_modal.html:31 @@ -339,6 +335,11 @@ msgstr "密文策略" msgid "Secret" msgstr "密钥" +#: accounts/models/automations/change_secret.py:22 +#: accounts/serializers/automations/change_secret.py:40 +msgid "Secret strategy" +msgstr "密文策略" + #: accounts/models/automations/change_secret.py:24 msgid "Password rules" msgstr "密码规则" @@ -361,7 +362,7 @@ msgstr "开始日期" #: accounts/models/automations/change_secret.py:74 #: assets/models/automations/base.py:115 ops/models/base.py:56 -#: ops/models/celery.py:64 ops/models/job.py:120 +#: ops/models/celery.py:64 ops/models/job.py:123 #: terminal/models/applet/host.py:109 msgid "Date finished" msgstr "结束日期" @@ -375,20 +376,19 @@ msgstr "错误" msgid "Change secret record" msgstr "改密记录" +#: accounts/models/automations/gather_account.py:14 +msgid "Present" +msgstr "存在" + #: accounts/models/automations/gather_account.py:15 -#: accounts/tasks/gather_accounts.py:29 -msgid "Gather asset accounts" -msgstr "收集账号" +msgid "Date last login" +msgstr "最后登录日期" -#: accounts/models/automations/push_account.py:13 -msgid "Triggers" -msgstr "触发方式" - -#: accounts/models/automations/push_account.py:14 accounts/models/base.py:34 -#: accounts/models/gathered_account.py:15 acls/serializers/base.py:18 -#: acls/serializers/base.py:49 assets/models/_user.py:23 audits/models.py:157 -#: authentication/forms.py:25 authentication/forms.py:27 -#: authentication/models/temp_token.py:9 +#: accounts/models/automations/gather_account.py:17 +#: accounts/models/automations/push_account.py:13 accounts/models/base.py:34 +#: acls/serializers/base.py:18 acls/serializers/base.py:49 +#: assets/models/_user.py:23 audits/models.py:157 authentication/forms.py:25 +#: authentication/forms.py:27 authentication/models/temp_token.py:9 #: authentication/templates/authentication/_msg_different_city.html:9 #: authentication/templates/authentication/_msg_oauth_bind.html:9 #: users/forms/profile.py:32 users/forms/profile.py:112 @@ -397,7 +397,24 @@ msgstr "触发方式" msgid "Username" msgstr "用户名" -#: accounts/models/automations/push_account.py:15 acls/models/base.py:81 +#: accounts/models/automations/gather_account.py:18 +msgid "Address last login" +msgstr "最后登录地址" + +#: accounts/models/automations/gather_account.py:25 rbac/tree.py:50 +msgid "Gather account" +msgstr "收集账号" + +#: accounts/models/automations/gather_account.py:41 +#: accounts/tasks/gather_accounts.py:29 +msgid "Gather asset accounts" +msgstr "收集账号" + +#: accounts/models/automations/push_account.py:12 +msgid "Triggers" +msgstr "触发方式" + +#: accounts/models/automations/push_account.py:14 acls/models/base.py:81 #: acls/serializers/base.py:81 acls/serializers/login_acl.py:25 #: assets/models/cmd_filter.py:81 audits/models.py:65 audits/serializers.py:82 #: authentication/serializers/connect_token_secret.py:109 @@ -405,7 +422,7 @@ msgstr "用户名" msgid "Action" msgstr "动作" -#: accounts/models/automations/push_account.py:41 +#: accounts/models/automations/push_account.py:40 msgid "Push asset account" msgstr "账号推送" @@ -419,14 +436,13 @@ msgstr "账号验证" #: assets/models/asset/common.py:90 assets/models/asset/common.py:102 #: assets/models/cmd_filter.py:21 assets/models/domain.py:18 #: assets/models/group.py:20 assets/models/label.py:18 -#: assets/models/platform.py:20 assets/models/platform.py:74 +#: assets/models/platform.py:21 assets/models/platform.py:76 #: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142 -#: assets/serializers/platform.py:131 +#: assets/serializers/platform.py:132 #: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21 #: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:26 ops/models/playbook.py:23 ops/serializers/job.py:19 -#: ops/serializers/playbook.py:19 orgs/models.py:69 -#: perms/models/asset_permission.py:56 rbac/models/role.py:29 +#: orgs/models.py:69 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:33 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:26 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:90 @@ -449,22 +465,6 @@ msgstr "特权账号" msgid "Is active" msgstr "激活" -#: accounts/models/gathered_account.py:12 -msgid "Present" -msgstr "存在" - -#: accounts/models/gathered_account.py:13 -msgid "Date last login" -msgstr "最后登录日期" - -#: accounts/models/gathered_account.py:16 -msgid "Address last login" -msgstr "最后登录地址" - -#: accounts/models/gathered_account.py:23 rbac/tree.py:50 -msgid "Gather account" -msgstr "收集账号" - #: accounts/notifications.py:8 msgid "Notification of account backup route task results" msgstr "账号备份任务结果通知" @@ -503,35 +503,35 @@ msgstr "" "{} - 改密任务已完成: 未设置加密密码 - 请前往个人信息 -> 文件加密密码中设置加" "密密码" -#: accounts/serializers/account/account.py:67 +#: accounts/serializers/account/account.py:65 #: assets/serializers/asset/common.py:66 settings/serializers/auth/sms.py:75 msgid "Template" msgstr "模板" -#: accounts/serializers/account/account.py:70 +#: accounts/serializers/account/account.py:68 #: assets/serializers/asset/common.py:63 msgid "Push now" msgstr "立即推送" -#: accounts/serializers/account/account.py:72 +#: accounts/serializers/account/account.py:70 #: accounts/serializers/account/base.py:62 msgid "Has secret" msgstr "已托管密码" -#: accounts/serializers/account/account.py:77 applications/models.py:11 -#: assets/models/label.py:21 assets/models/platform.py:75 +#: accounts/serializers/account/account.py:75 applications/models.py:11 +#: assets/models/label.py:21 assets/models/platform.py:77 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 -#: assets/serializers/platform.py:93 assets/serializers/platform.py:132 +#: assets/serializers/platform.py:93 assets/serializers/platform.py:133 #: perms/serializers/user_permission.py:25 settings/models.py:35 #: tickets/models/ticket/apply_application.py:13 msgid "Category" msgstr "类别" -#: accounts/serializers/account/account.py:78 +#: accounts/serializers/account/account.py:76 #: accounts/serializers/automations/base.py:43 acls/models/command_acl.py:24 #: acls/serializers/command_acl.py:18 applications/models.py:14 #: assets/models/_user.py:50 assets/models/automations/base.py:20 -#: assets/models/cmd_filter.py:74 assets/models/platform.py:76 +#: assets/models/cmd_filter.py:74 assets/models/platform.py:78 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:92 #: audits/serializers.py:48 #: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:37 @@ -546,28 +546,28 @@ msgstr "类别" msgid "Type" msgstr "类型" -#: accounts/serializers/account/account.py:93 +#: accounts/serializers/account/account.py:91 msgid "Asset not found" msgstr "资产不存在" -#: accounts/serializers/account/backup.py:30 +#: accounts/serializers/account/backup.py:31 #: accounts/serializers/automations/base.py:36 #: assets/serializers/automations/base.py:34 ops/mixin.py:23 ops/mixin.py:103 #: settings/serializers/auth/ldap.py:66 msgid "Periodic perform" msgstr "定时执行" -#: accounts/serializers/account/backup.py:31 +#: accounts/serializers/account/backup.py:32 #: accounts/serializers/automations/base.py:37 msgid "Executed amount" msgstr "执行次数" -#: accounts/serializers/account/backup.py:33 +#: accounts/serializers/account/backup.py:35 #: accounts/serializers/automations/change_secret.py:57 msgid "Currently only mail sending is supported" msgstr "当前只支持邮件发送" -#: accounts/serializers/account/backup.py:35 +#: accounts/serializers/account/backup.py:37 msgid "Asset type" msgstr "资产类型" @@ -640,7 +640,7 @@ msgstr "失败" msgid "Account execute automation" msgstr "账号执行自动化" -#: accounts/tasks/backup_account.py:24 +#: accounts/tasks/backup_account.py:25 msgid "Execute account backup plan" msgstr "执行账号备份计划" @@ -648,15 +648,15 @@ msgstr "执行账号备份计划" msgid "Gather assets accounts" msgstr "收集资产上的账号" -#: accounts/tasks/push_account.py:30 accounts/tasks/push_account.py:37 +#: accounts/tasks/push_account.py:15 accounts/tasks/push_account.py:23 msgid "Push accounts to assets" msgstr "推送账号到资产" -#: accounts/tasks/verify_account.py:42 +#: accounts/tasks/verify_account.py:49 msgid "Verify asset account availability" msgstr "验证资产账号可用性" -#: accounts/tasks/verify_account.py:50 +#: accounts/tasks/verify_account.py:55 msgid "Verify accounts connectivity" msgstr "测试账号可连接性" @@ -890,11 +890,11 @@ msgstr "应用程序" msgid "Can match application" msgstr "匹配应用" -#: assets/api/asset/asset.py:145 +#: assets/api/asset/asset.py:144 msgid "Cannot create asset directly, you should create a host or other" msgstr "不能直接创建资产, 你应该创建主机或其他资产" -#: assets/api/domain.py:61 +#: assets/api/domain.py:60 msgid "Number required" msgstr "需要为数字" @@ -914,7 +914,7 @@ msgstr "删除失败,节点包含资产" msgid "App assets" msgstr "资产管理" -#: assets/automations/base/manager.py:104 +#: assets/automations/base/manager.py:106 msgid "{} disabled" msgstr "{} 已禁用" @@ -923,6 +923,12 @@ msgstr "{} 已禁用" msgid "No account" msgstr "没有账号" +#: assets/automations/ping_gateway/manager.py:36 +#, fuzzy +#| msgid "Assets amount" +msgid "Asset, {}, using account {}" +msgstr "资产数量" + #: assets/automations/ping_gateway/manager.py:55 #, python-brace-format msgid "Unable to connect to port {port} on {address}" @@ -1035,11 +1041,10 @@ msgstr "SSH公钥" #: assets/models/_user.py:27 assets/models/cmd_filter.py:40 #: assets/models/cmd_filter.py:88 assets/models/group.py:23 -#: assets/models/platform.py:79 common/db/models.py:37 ops/models/adhoc.py:27 -#: ops/models/job.py:45 ops/models/playbook.py:26 rbac/models/role.py:37 -#: settings/models.py:38 terminal/models/applet/applet.py:35 -#: terminal/models/applet/applet.py:151 terminal/models/applet/host.py:110 -#: terminal/models/component/endpoint.py:24 +#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:45 +#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38 +#: terminal/models/applet/applet.py:35 terminal/models/applet/applet.py:151 +#: terminal/models/applet/host.py:110 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:100 #: terminal/models/session/session.py:47 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:756 @@ -1049,7 +1054,7 @@ msgstr "备注" #: assets/models/_user.py:28 assets/models/automations/base.py:113 #: assets/models/cmd_filter.py:41 assets/models/group.py:22 -#: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:118 +#: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:121 #: users/models/user.py:943 msgid "Date created" msgstr "创建日期" @@ -1141,7 +1146,7 @@ msgstr "可以匹配系统用户" msgid "Cloud" msgstr "云服务" -#: assets/models/asset/common.py:91 assets/models/platform.py:21 +#: assets/models/asset/common.py:91 assets/models/platform.py:22 #: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:68 #: xpack/plugins/cloud/serializers/account_attrs.py:73 msgid "Port" @@ -1151,7 +1156,7 @@ msgstr "端口" msgid "Address" msgstr "地址" -#: assets/models/asset/common.py:104 assets/models/platform.py:111 +#: assets/models/asset/common.py:104 assets/models/platform.py:112 #: authentication/serializers/connect_token_secret.py:108 #: perms/serializers/user_permission.py:23 #: xpack/plugins/cloud/serializers/account_attrs.py:187 @@ -1189,16 +1194,8 @@ msgid "Can match asset" msgstr "可以匹配资产" #: assets/models/asset/common.py:287 -msgid "Add asset to node" -msgstr "添加资产到节点" - -#: assets/models/asset/common.py:288 -msgid "Move asset to node" -msgstr "移动资产到节点" - -#: assets/models/asset/common.py:289 -msgid "Remove asset from node" -msgstr "从节点移除资产" +msgid "Can change asset nodes" +msgstr "可以修改资产节点" #: assets/models/asset/database.py:10 assets/serializers/asset/common.py:110 #: settings/serializers/email.py:37 @@ -1254,7 +1251,7 @@ msgid "Asset automation task" msgstr "资产自动化任务" #: assets/models/automations/base.py:112 audits/models.py:177 -#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:111 +#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:114 #: terminal/models/applet/applet.py:150 terminal/models/applet/host.py:107 #: terminal/models/component/status.py:27 terminal/serializers/applet.py:17 #: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283 @@ -1322,7 +1319,7 @@ msgstr "网关" msgid "Asset group" msgstr "资产组" -#: assets/models/group.py:34 assets/models/platform.py:18 +#: assets/models/group.py:34 assets/models/platform.py:19 #: xpack/plugins/cloud/providers/nutanix.py:30 msgid "Default" msgstr "默认" @@ -1379,91 +1376,91 @@ msgstr "节点" msgid "Can match node" msgstr "可以匹配节点" -#: assets/models/platform.py:19 +#: assets/models/platform.py:20 msgid "Required" msgstr "必须的" -#: assets/models/platform.py:22 settings/serializers/settings.py:61 +#: assets/models/platform.py:23 settings/serializers/settings.py:61 #: users/templates/users/reset_password.html:29 msgid "Setting" msgstr "设置" -#: assets/models/platform.py:41 audits/const.py:47 settings/models.py:37 +#: assets/models/platform.py:42 audits/const.py:47 settings/models.py:37 #: terminal/serializers/applet_host.py:29 msgid "Enabled" msgstr "启用" -#: assets/models/platform.py:42 +#: assets/models/platform.py:43 msgid "Ansible config" msgstr "Ansible 配置" -#: assets/models/platform.py:43 assets/serializers/platform.py:60 +#: assets/models/platform.py:44 assets/serializers/platform.py:60 msgid "Ping enabled" msgstr "启用资产探活" -#: assets/models/platform.py:44 assets/serializers/platform.py:61 +#: assets/models/platform.py:45 assets/serializers/platform.py:61 msgid "Ping method" msgstr "资产探活方式" -#: assets/models/platform.py:45 assets/models/platform.py:58 +#: assets/models/platform.py:46 assets/models/platform.py:59 #: assets/serializers/platform.py:62 msgid "Gather facts enabled" msgstr "启用收集资产信息" -#: assets/models/platform.py:46 assets/models/platform.py:60 +#: assets/models/platform.py:47 assets/models/platform.py:61 #: assets/serializers/platform.py:63 msgid "Gather facts method" msgstr "收集信息方式" -#: assets/models/platform.py:47 assets/serializers/platform.py:66 +#: assets/models/platform.py:48 assets/serializers/platform.py:66 msgid "Change secret enabled" msgstr "启用改密" -#: assets/models/platform.py:49 assets/serializers/platform.py:67 +#: assets/models/platform.py:50 assets/serializers/platform.py:67 msgid "Change secret method" msgstr "改密方式" -#: assets/models/platform.py:51 assets/serializers/platform.py:68 +#: assets/models/platform.py:52 assets/serializers/platform.py:68 msgid "Push account enabled" msgstr "启用账号推送" -#: assets/models/platform.py:53 assets/serializers/platform.py:69 +#: assets/models/platform.py:54 assets/serializers/platform.py:69 msgid "Push account method" msgstr "账号推送方式" -#: assets/models/platform.py:55 assets/serializers/platform.py:64 +#: assets/models/platform.py:56 assets/serializers/platform.py:64 msgid "Verify account enabled" msgstr "开启账号验证" -#: assets/models/platform.py:57 assets/serializers/platform.py:65 +#: assets/models/platform.py:58 assets/serializers/platform.py:65 msgid "Verify account method" msgstr "账号验证方式" -#: assets/models/platform.py:77 tickets/models/ticket/general.py:300 +#: assets/models/platform.py:79 tickets/models/ticket/general.py:300 msgid "Meta" msgstr "元数据" -#: assets/models/platform.py:78 +#: assets/models/platform.py:80 msgid "Internal" msgstr "内置" -#: assets/models/platform.py:82 assets/serializers/platform.py:90 +#: assets/models/platform.py:83 assets/serializers/platform.py:90 msgid "Charset" msgstr "编码" -#: assets/models/platform.py:84 assets/serializers/platform.py:117 +#: assets/models/platform.py:85 assets/serializers/platform.py:118 msgid "Domain enabled" msgstr "启用网域" -#: assets/models/platform.py:86 assets/serializers/platform.py:116 +#: assets/models/platform.py:87 assets/serializers/platform.py:117 msgid "Su enabled" msgstr "启用账号切换" -#: assets/models/platform.py:87 assets/serializers/platform.py:100 +#: assets/models/platform.py:88 assets/serializers/platform.py:100 msgid "Su method" msgstr "账号切换方式" -#: assets/models/platform.py:89 assets/serializers/platform.py:97 +#: assets/models/platform.py:90 assets/serializers/platform.py:97 msgid "Automation" msgstr "自动化" @@ -1612,7 +1609,7 @@ msgstr "收集账号方式" msgid "Primary" msgstr "主要的" -#: assets/serializers/platform.py:118 +#: assets/serializers/platform.py:119 msgid "Default Domain" msgstr "默认网域" @@ -1620,7 +1617,7 @@ msgstr "默认网域" msgid "Test assets connectivity " msgstr "测试资产可连接性" -#: assets/signal_handlers/asset.py:35 +#: assets/signal_handlers/asset.py:36 msgid "Gather asset hardware info" msgstr "收集资产硬件信息" @@ -1771,8 +1768,8 @@ msgstr "会话日志" msgid "Login log" msgstr "登录日志" -#: audits/const.py:42 ops/signal_handlers.py:86 -#: terminal/models/applet/host.py:111 terminal/models/component/task.py:24 +#: audits/const.py:42 terminal/models/applet/host.py:111 +#: terminal/models/component/task.py:24 msgid "Task" msgstr "任务" @@ -1971,7 +1968,7 @@ msgstr "ACL 动作是复核" msgid "Current user not support mfa type: {}" msgstr "当前用户不支持 MFA 类型: {}" -#: authentication/api/password.py:31 terminal/api/session/session.py:244 +#: authentication/api/password.py:31 terminal/api/session/session.py:247 #: users/views/profile/reset.py:44 msgid "User does not exist: {}" msgstr "用户不存在: {}" @@ -3306,7 +3303,7 @@ msgid "Args" msgstr "参数" #: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53 -#: ops/models/job.py:38 ops/models/job.py:117 ops/models/playbook.py:25 +#: ops/models/job.py:38 ops/models/job.py:120 ops/models/playbook.py:25 #: terminal/models/session/sharing.py:23 msgid "Creator" msgstr "创建者" @@ -3323,12 +3320,12 @@ msgstr "最后执行" msgid "Date last run" msgstr "最后运行日期" -#: ops/models/base.py:51 ops/models/job.py:115 +#: ops/models/base.py:51 ops/models/job.py:118 #: xpack/plugins/cloud/models.py:162 msgid "Result" msgstr "结果" -#: ops/models/base.py:52 ops/models/job.py:116 +#: ops/models/base.py:52 ops/models/job.py:119 msgid "Summary" msgstr "汇总" @@ -3392,23 +3389,23 @@ msgstr "运行用户" msgid "Runas policy" msgstr "用户策略" -#: ops/models/job.py:103 +#: ops/models/job.py:106 msgid "Job" msgstr "作业" -#: ops/models/job.py:114 +#: ops/models/job.py:117 msgid "Parameters" msgstr "参数" -#: ops/models/job.py:122 +#: ops/models/job.py:125 msgid "Material" msgstr "" -#: ops/models/job.py:124 +#: ops/models/job.py:127 msgid "Material Type" msgstr "" -#: ops/models/job.py:361 +#: ops/models/job.py:364 msgid "Job Execution" msgstr "作业执行" @@ -3524,17 +3521,17 @@ msgstr "Job ID" msgid "Name of the job" msgstr "Job 名称" -#: orgs/api.py:63 +#: orgs/api.py:62 msgid "The current organization ({}) cannot be deleted" msgstr "当前组织 ({}) 不能被删除" -#: orgs/api.py:68 +#: orgs/api.py:67 msgid "" "LDAP synchronization is set to the current organization. Please switch to " "another organization before deleting" msgstr "LDAP 同步设置组织为当前组织,请切换其他组织后再进行删除操作" -#: orgs/api.py:78 +#: orgs/api.py:77 msgid "The organization have resource ({}) cannot be deleted" msgstr "组织存在资源 ({}) 不能被删除" @@ -5265,15 +5262,15 @@ msgstr "测试失败: 账号无效" msgid "Have online sessions" msgstr "有在线会话" -#: terminal/api/session/session.py:236 +#: terminal/api/session/session.py:239 msgid "Session does not exist: {}" msgstr "会话不存在: {}" -#: terminal/api/session/session.py:239 +#: terminal/api/session/session.py:242 msgid "Session is finished or the protocol not supported" msgstr "会话已经完成或协议不支持" -#: terminal/api/session/session.py:252 +#: terminal/api/session/session.py:255 msgid "User does not have permission" msgstr "用户没有权限" @@ -6165,7 +6162,7 @@ msgstr "无效的审批动作" msgid "This user is not authorized to approve this ticket" msgstr "此用户无权审批此工单" -#: users/api/user.py:179 +#: users/api/user.py:178 msgid "Could not reset self otp, use profile reset instead" msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置" @@ -7194,14 +7191,6 @@ msgstr "执行次数" msgid "Instance count" msgstr "实例个数" -#: xpack/plugins/cloud/tasks.py:27 -msgid "Run sync instance task" -msgstr "执行同步实例任务" - -#: xpack/plugins/cloud/tasks.py:41 -msgid "Period clean sync instance task execution" -msgstr "定期清除同步实例任务执行记录" - #: xpack/plugins/cloud/utils.py:69 msgid "Account unavailable" msgstr "账号无效" @@ -7270,6 +7259,21 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "Add asset to node" +#~ msgstr "添加资产到节点" + +#~ msgid "Move asset to node" +#~ msgstr "移动资产到节点" + +#~ msgid "Remove asset from node" +#~ msgstr "从节点移除资产" + +#~ msgid "Run sync instance task" +#~ msgstr "执行同步实例任务" + +#~ msgid "Period clean sync instance task execution" +#~ msgstr "定期清除同步实例任务执行记录" + #~ msgid "Clean audits log" #~ msgstr "清理审计日志" diff --git a/apps/rbac/const.py b/apps/rbac/const.py index cb9fa96c6..a70e87db8 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -49,6 +49,8 @@ exclude_permissions = ( ('assets', 'gatherfactsautomation', '*', '*'), ('assets', 'commandfilter', '*', '*'), ('assets', 'commandfilterrule', '*', '*'), + ('assets', 'asset', 'add,move', 'assettonode'), + ('assets', 'asset', 'remove', 'assetfromnode'), ('accounts', 'historicalaccount', '*', '*'), ('accounts', 'accountbaseautomation', '*', '*'), From 0001ffba1b0e07962ebfcecb04651d3eef89c6ec Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 21 Feb 2023 13:39:28 +0800 Subject: [PATCH 6/8] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20rbac?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/migrations/0001_initial.py | 1 - .../migrations/0007_alter_account_options.py | 2 +- .../migrations/0008_alter_account_options.py | 17 ++++++++++++++++ apps/accounts/models/account.py | 2 ++ apps/assets/api/asset/asset.py | 4 ++-- .../migrations/0110_alter_asset_options.py | 17 ++++++++++++++++ .../migrations/0111_alter_asset_options.py | 17 ++++++++++++++++ apps/assets/models/asset/common.py | 2 -- apps/assets/serializers/asset/common.py | 2 +- apps/locale/ja/LC_MESSAGES/django.mo | 4 ++-- apps/locale/ja/LC_MESSAGES/django.po | 20 +++++++++++-------- apps/locale/zh/LC_MESSAGES/django.mo | 4 ++-- apps/locale/zh/LC_MESSAGES/django.po | 20 +++++++++++-------- .../0011_remove_redundant_permission.py | 2 +- 14 files changed, 86 insertions(+), 28 deletions(-) create mode 100644 apps/accounts/migrations/0008_alter_account_options.py create mode 100644 apps/assets/migrations/0110_alter_asset_options.py create mode 100644 apps/assets/migrations/0111_alter_asset_options.py diff --git a/apps/accounts/migrations/0001_initial.py b/apps/accounts/migrations/0001_initial.py index 6e211a7fc..b8fe35670 100644 --- a/apps/accounts/migrations/0001_initial.py +++ b/apps/accounts/migrations/0001_initial.py @@ -50,7 +50,6 @@ class Migration(migrations.Migration): options={ 'verbose_name': 'Account', 'permissions': [('view_accountsecret', 'Can view asset account secret'), - ('change_accountsecret', 'Can change asset account secret'), ('view_historyaccount', 'Can view asset history account'), ('view_historyaccountsecret', 'Can view asset history account secret')], 'unique_together': {('username', 'asset', 'secret_type'), ('name', 'asset')}, diff --git a/apps/accounts/migrations/0007_alter_account_options.py b/apps/accounts/migrations/0007_alter_account_options.py index 73193e9a4..4ec798a21 100644 --- a/apps/accounts/migrations/0007_alter_account_options.py +++ b/apps/accounts/migrations/0007_alter_account_options.py @@ -12,6 +12,6 @@ class Migration(migrations.Migration): 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')], 'verbose_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'}, ), ] diff --git a/apps/accounts/migrations/0008_alter_account_options.py b/apps/accounts/migrations/0008_alter_account_options.py new file mode 100644 index 000000000..949840740 --- /dev/null +++ b/apps/accounts/migrations/0008_alter_account_options.py @@ -0,0 +1,17 @@ +# 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'}, + ), + ] diff --git a/apps/accounts/models/account.py b/apps/accounts/models/account.py index ed5fb72fa..7367c53de 100644 --- a/apps/accounts/models/account.py +++ b/apps/accounts/models/account.py @@ -64,6 +64,8 @@ class Account(AbsConnectivity, BaseAccount): ('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')), ] @lazyproperty diff --git a/apps/assets/api/asset/asset.py b/apps/assets/api/asset/asset.py index f51bdbb94..5b6b9084b 100644 --- a/apps/assets/api/asset/asset.py +++ b/apps/assets/api/asset/asset.py @@ -180,9 +180,9 @@ class AssetTaskCreateApi(AssetsTaskMixin, generics.CreateAPIView): def check_permissions(self, request): action_perm_require = { "refresh": "assets.refresh_assethardwareinfo", - "push_account": "accounts.add_pushaccountexecution", + "push_account": "accounts.push_account", "test": "assets.test_assetconnectivity", - "test_account": "assets.test_account", + "test_account": "accounts.verify_account", } _action = request.data.get("action") perm_required = action_perm_require.get(_action) diff --git a/apps/assets/migrations/0110_alter_asset_options.py b/apps/assets/migrations/0110_alter_asset_options.py new file mode 100644 index 000000000..6d0e2a7aa --- /dev/null +++ b/apps/assets/migrations/0110_alter_asset_options.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.14 on 2023-02-21 05:11 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0109_alter_asset_options'), + ] + + operations = [ + migrations.AlterModelOptions( + name='asset', + options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetaccount', 'Can push account to asset'), ('test_account', 'Can verify account'), ('match_asset', 'Can match asset'), ('change_assetnodes', 'Can change asset nodes')], 'verbose_name': 'Asset'}, + ), + ] diff --git a/apps/assets/migrations/0111_alter_asset_options.py b/apps/assets/migrations/0111_alter_asset_options.py new file mode 100644 index 000000000..5a54d6830 --- /dev/null +++ b/apps/assets/migrations/0111_alter_asset_options.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.14 on 2023-02-21 05:22 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0110_alter_asset_options'), + ] + + operations = [ + migrations.AlterModelOptions( + name='asset', + options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('match_asset', 'Can match asset'), ('change_assetnodes', 'Can change asset nodes')], 'verbose_name': 'Asset'}, + ), + ] diff --git a/apps/assets/models/asset/common.py b/apps/assets/models/asset/common.py index 3e013fa0d..8460556c4 100644 --- a/apps/assets/models/asset/common.py +++ b/apps/assets/models/asset/common.py @@ -281,8 +281,6 @@ class Asset(NodesRelationMixin, AbsConnectivity, JMSOrgBaseModel): permissions = [ ('refresh_assethardwareinfo', _('Can refresh asset hardware info')), ('test_assetconnectivity', _('Can test asset connectivity')), - ('push_assetaccount', _('Can push account to asset')), - ('test_account', _('Can verify account')), ('match_asset', _('Can match asset')), ('change_assetnodes', _('Can change asset nodes')), ] diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 0d4939086..9c31ee695 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -83,7 +83,7 @@ class AssetAccountSerializer( def validate_push_now(self, value): request = self.context['request'] - if not request.user.has_perms('assets.push_assetaccount'): + if not request.user.has_perms('accounts.push_account'): return False return value diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 77a9fd388..f2bf6d5da 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:694d0090ced3dd431fd632329c8d081d696baae99b4e7561ccc5abc5343f82ca -size 135571 +oid sha256:ad88d17921655f6102ae29c8f1e34c65eac8eb5217a8ba14d189035db156789a +size 135647 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 0f9b9d529..48382f434 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-02-21 13:00+0800\n" +"POT-Creation-Date: 2023-02-21 13:14+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -215,15 +215,23 @@ msgstr "資産履歴アカウントを表示できます" msgid "Can view asset history account secret" msgstr "資産履歴アカウントパスワードを表示できます" -#: accounts/models/account.py:111 +#: accounts/models/account.py:67 assets/models/asset/common.py:285 +msgid "Can verify account" +msgstr "アカウントを確認できます" + +#: accounts/models/account.py:68 +msgid "Can push account" +msgstr "アカウントをプッシュできます" + +#: accounts/models/account.py:113 msgid "Account template" msgstr "アカウント テンプレート" -#: accounts/models/account.py:116 +#: accounts/models/account.py:118 msgid "Can view asset account template secret" msgstr "アセット アカウント テンプレートのパスワードを表示できます" -#: accounts/models/account.py:117 +#: accounts/models/account.py:119 msgid "Can change asset account template secret" msgstr "アセット アカウント テンプレートのパスワードを変更できます" @@ -1193,10 +1201,6 @@ msgstr "資産接続をテストできます" msgid "Can push account to asset" msgstr "アカウントをアセットにプッシュできます" -#: assets/models/asset/common.py:285 -msgid "Can verify account" -msgstr "アカウントを確認できます" - #: assets/models/asset/common.py:286 msgid "Can match asset" msgstr "アセットを一致させることができます" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 6feff0df0..1da0d3cf9 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c18587f19a5d5723a65592162020f8e43b1f69572ec437a83ba914d636f0f32b -size 111452 +oid sha256:e044950aeb211a81af9d2530f0468b5aa0ffc3acfffd899fbacb78a769b5de59 +size 111504 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 829aaee91..98d9bfb7f 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-02-21 13:00+0800\n" +"POT-Creation-Date: 2023-02-21 13:14+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -214,15 +214,23 @@ msgstr "可以查看资产历史账号" msgid "Can view asset history account secret" msgstr "可以查看资产历史账号密码" -#: accounts/models/account.py:111 +#: accounts/models/account.py:67 assets/models/asset/common.py:285 +msgid "Can verify account" +msgstr "可以验证账号" + +#: accounts/models/account.py:68 +msgid "Can push account" +msgstr "可以推送账号" + +#: accounts/models/account.py:113 msgid "Account template" msgstr "账号模版" -#: accounts/models/account.py:116 +#: accounts/models/account.py:118 msgid "Can view asset account template secret" msgstr "可以查看资产账号模版密码" -#: accounts/models/account.py:117 +#: accounts/models/account.py:119 msgid "Can change asset account template secret" msgstr "可以更改资产账号模版密码" @@ -1185,10 +1193,6 @@ msgstr "可以测试资产连接性" msgid "Can push account to asset" msgstr "可以推送账号到资产" -#: assets/models/asset/common.py:285 -msgid "Can verify account" -msgstr "可以验证账号" - #: assets/models/asset/common.py:286 msgid "Can match asset" msgstr "可以匹配资产" diff --git a/apps/rbac/migrations/0011_remove_redundant_permission.py b/apps/rbac/migrations/0011_remove_redundant_permission.py index d84e86ab3..d8a874f19 100644 --- a/apps/rbac/migrations/0011_remove_redundant_permission.py +++ b/apps/rbac/migrations/0011_remove_redundant_permission.py @@ -27,7 +27,7 @@ def migrate_remove_redundant_permission(apps, *args): perm_model = apps.get_model('auth', 'Permission') perm_model.objects.filter(codename__in=[ - 'view_permusergroupasset', 'view_permuserasset', 'push_assetsystemuser', 'change_accountsecret' + 'view_permusergroupasset', 'view_permuserasset', 'push_assetsystemuser', ]).delete() From df9e533b3cfa566d2b6ad2afba39fada677d0db8 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 21 Feb 2023 13:40:48 +0800 Subject: [PATCH 7/8] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20rabc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/node.py | 6 +++--- apps/rbac/const.py | 2 ++ apps/rbac/migrations/0011_remove_redundant_permission.py | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/assets/api/node.py b/apps/assets/api/node.py index 9a60c636f..47ac0b4e6 100644 --- a/apps/assets/api/node.py +++ b/apps/assets/api/node.py @@ -103,7 +103,7 @@ class NodeAddAssetsApi(generics.UpdateAPIView): instance = None permission_classes = (RBACPermission,) rbac_perms = { - 'PUT': 'assets.change_assettonode', + 'PUT': 'assets.change_assetnodes', } def perform_update(self, serializer): @@ -118,7 +118,7 @@ class NodeRemoveAssetsApi(generics.UpdateAPIView): instance = None permission_classes = (RBACPermission,) rbac_perms = { - 'PUT': 'assets.change_assetfromnode', + 'PUT': 'assets.change_assetnodes', } def perform_update(self, serializer): @@ -140,7 +140,7 @@ class MoveAssetsToNodeApi(generics.UpdateAPIView): instance = None permission_classes = (RBACPermission,) rbac_perms = { - 'PUT': 'assets.change_assettonode', + 'PUT': 'assets.change_assetnodes', } def perform_update(self, serializer): diff --git a/apps/rbac/const.py b/apps/rbac/const.py index a70e87db8..1c0f594f9 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -51,6 +51,8 @@ exclude_permissions = ( ('assets', 'commandfilterrule', '*', '*'), ('assets', 'asset', 'add,move', 'assettonode'), ('assets', 'asset', 'remove', 'assetfromnode'), + ('assets', 'asset', 'test', 'account'), + ('assets', 'asset', 'push', 'assetaccount'), ('accounts', 'historicalaccount', '*', '*'), ('accounts', 'accountbaseautomation', '*', '*'), diff --git a/apps/rbac/migrations/0011_remove_redundant_permission.py b/apps/rbac/migrations/0011_remove_redundant_permission.py index d8a874f19..6febd432c 100644 --- a/apps/rbac/migrations/0011_remove_redundant_permission.py +++ b/apps/rbac/migrations/0011_remove_redundant_permission.py @@ -18,7 +18,8 @@ def migrate_remove_redundant_permission(apps, *args): model.objects.filter(app_label='assets', model__in=[ 'authbook', 'historicalauthbook', 'test_gateway', - 'accountbackupplan', 'accountbackupplanexecution', 'gathereduser', 'systemuser' + 'accountbackupplan', 'accountbackupplanexecution', + 'gathereduser', 'systemuser' ]).delete() model.objects.filter(app_label='perms', model__in=[ @@ -28,6 +29,7 @@ def migrate_remove_redundant_permission(apps, *args): perm_model = apps.get_model('auth', 'Permission') perm_model.objects.filter(codename__in=[ 'view_permusergroupasset', 'view_permuserasset', 'push_assetsystemuser', + 'add_assettonode', 'move_assettonode', 'remove_assetfromnode', ]).delete() From 3df411fd610d02967694d985d359416b26261983 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 21 Feb 2023 13:47:47 +0800 Subject: [PATCH 8/8] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E6=9D=83?= =?UTF-8?q?=E9=99=90=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/api/account/task.py | 7 ++++++- apps/locale/ja/LC_MESSAGES/django.mo | 4 ++-- apps/locale/zh/LC_MESSAGES/django.mo | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/accounts/api/account/task.py b/apps/accounts/api/account/task.py index 85a3831e2..050e69052 100644 --- a/apps/accounts/api/account/task.py +++ b/apps/accounts/api/account/task.py @@ -13,7 +13,12 @@ class AccountsTaskCreateAPI(CreateAPIView): serializer_class = serializers.AccountTaskSerializer def check_permissions(self, request): - return request.user.has_perm('assets.test_assetconnectivity') + act = request.data.get('action') + if act == 'push': + code = 'accounts.push_account' + else: + code = 'accounts.verify_account' + return request.user.has_perm(code) def perform_create(self, serializer): data = serializer.validated_data diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index f2bf6d5da..9380816b8 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad88d17921655f6102ae29c8f1e34c65eac8eb5217a8ba14d189035db156789a -size 135647 +oid sha256:014483808a830a01f5432fdc44bc34f7f392e53a160ffa97eb377dbb49e0ec9a +size 135547 diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 1da0d3cf9..70960ba2c 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e044950aeb211a81af9d2530f0468b5aa0ffc3acfffd899fbacb78a769b5de59 -size 111504 +oid sha256:1c1524b6173a2613845d9450d84ef8ca9cf1be6d0f7cdae2a89f6131d6abc1f1 +size 111449