perf: 解决冲突

pull/9689/head
jiangweidong 2023-02-22 21:56:40 +08:00
commit 07c23c5341
28 changed files with 481 additions and 328 deletions

View File

@ -74,5 +74,17 @@ class AccountHistoriesSecretAPI(RecordViewLogMixin, ListAPIView):
'list': 'accounts.view_accountsecret', 'list': 'accounts.view_accountsecret',
} }
def get_object(self):
return get_object_or_404(Account, pk=self.kwargs.get('pk'))
def get_queryset(self): def get_queryset(self):
return self.model.objects.filter(id=self.kwargs.get('pk')) account = self.get_object()
histories = account.history.all()
last_history = account.history.first()
if not last_history:
return histories
if account.secret == last_history.secret \
and account.secret_type == last_history.secret_type:
histories = histories.exclude(history_id=last_history.history_id)
return histories

View File

@ -24,7 +24,7 @@ class AccountsTaskCreateAPI(CreateAPIView):
def perform_create(self, serializer): def perform_create(self, serializer):
data = serializer.validated_data data = serializer.validated_data
accounts = data.get('accounts', []) accounts = data.get('accounts', [])
account_ids = [a.id for a in accounts] account_ids = [str(a.id) for a in accounts]
if data['action'] == 'push': if data['action'] == 'push':
task = push_accounts_to_assets_task.delay(account_ids) task = push_accounts_to_assets_task.delay(account_ids)

View File

@ -57,9 +57,9 @@ class VerifyAccountManager(AccountBasePlaybookManager):
'secret': secret, 'secret': secret,
'private_key_path': private_key_path 'private_key_path': private_key_path
} }
if account.platform.type == 'oracle':
h['account']['mode'] = 'sysdba' if account.privileged else None
inventory_hosts.append(h) inventory_hosts.append(h)
# print("Host: ")
# print(self.json_dumps(inventory_hosts))
return inventory_hosts return inventory_hosts
@classmethod @classmethod

View File

@ -90,6 +90,10 @@ class Account(AbsConnectivity, BaseAccount):
""" @INPUT 手动登录的账号(any) """ """ @INPUT 手动登录的账号(any) """
return cls(name=AliasAccount.INPUT.label, username=AliasAccount.INPUT.value, secret=None) return cls(name=AliasAccount.INPUT.label, username=AliasAccount.INPUT.value, secret=None)
@lazyproperty
def versions(self):
return self.history.count()
@classmethod @classmethod
def get_user_account(cls): def get_user_account(cls):
""" @USER 动态用户的账号(self) """ """ @USER 动态用户的账号(self) """

View File

@ -43,7 +43,7 @@ class AccountSerializerCreateValidateMixin:
def push_account(instance, push_now): def push_account(instance, push_now):
if not push_now: if not push_now:
return return
push_accounts_to_assets_task.delay([instance.id]) push_accounts_to_assets_task.delay([str(instance.id)])
def create(self, validated_data): def create(self, validated_data):
push_now = validated_data.pop('push_now', None) push_now = validated_data.pop('push_now', None)
@ -102,8 +102,8 @@ class AccountSerializer(AccountSerializerCreateMixin, BaseAccountSerializer):
class Meta(BaseAccountSerializer.Meta): class Meta(BaseAccountSerializer.Meta):
model = Account model = Account
fields = BaseAccountSerializer.Meta.fields + [ fields = BaseAccountSerializer.Meta.fields + [
'su_from', 'asset', 'template', 'su_from', 'asset', 'template', 'version',
'push_now', 'source', 'connectivity' 'push_now', 'source', 'connectivity',
] ]
extra_kwargs = { extra_kwargs = {
**BaseAccountSerializer.Meta.extra_kwargs, **BaseAccountSerializer.Meta.extra_kwargs,
@ -118,7 +118,8 @@ class AccountSerializer(AccountSerializerCreateMixin, BaseAccountSerializer):
@classmethod @classmethod
def setup_eager_loading(cls, queryset): def setup_eager_loading(cls, queryset):
""" Perform necessary eager loading of data. """ """ Perform necessary eager loading of data. """
queryset = queryset.prefetch_related('asset', 'asset__platform') queryset = queryset \
.prefetch_related('asset', 'asset__platform')
return queryset return queryset

View File

@ -38,7 +38,7 @@ class BaseAutomationSerializer(PeriodTaskSerializerMixin, BulkOrgResourceModelSe
} }
def validate_name(self, name): def validate_name(self, name):
if self.instance: if self.instance and self.instance.name == name:
return name return name
if BaseAutomation.objects.filter(name=name, type=self.model_type).exists(): if BaseAutomation.objects.filter(name=name, type=self.model_type).exists():
raise serializers.ValidationError(_('Name already exists')) raise serializers.ValidationError(_('Name already exists'))

View File

@ -1,3 +1,15 @@
from django.db.models.signals import pre_save
from django.dispatch import receiver
from common.utils import get_logger from common.utils import get_logger
from .models import Account
logger = get_logger(__name__) logger = get_logger(__name__)
@receiver(pre_save, sender=Account)
def on_account_pre_save(sender, instance, created=False, **kwargs):
if created:
instance.version = 1
else:
instance.version = instance.history.count()

View File

@ -204,8 +204,8 @@ class AssetTaskCreateApi(AssetsTaskMixin, generics.CreateAPIView):
if not accounts: if not accounts:
accounts = asset.accounts.all() accounts = asset.accounts.all()
asset_ids = [asset.id] account_ids = accounts.values_list('id', flat=True)
account_ids = accounts.values_list("id", flat=True) account_ids = [str(_id) for _id in account_ids]
if action == "push_account": if action == "push_account":
task = push_accounts_to_assets_task.delay(account_ids) task = push_accounts_to_assets_task.delay(account_ids)
elif action == "test_account": elif action == "test_account":

View File

@ -1,9 +1,8 @@
from jumpserver.utils import has_valid_xpack_license from assets.const import AllTypes
from assets.models import Platform
from assets.serializers import PlatformSerializer
from common.api import JMSModelViewSet from common.api import JMSModelViewSet
from common.serializers import GroupedChoiceSerializer from common.serializers import GroupedChoiceSerializer
from assets.models import Platform
from assets.const import AllTypes
from assets.serializers import PlatformSerializer
__all__ = ['AssetPlatformViewSet'] __all__ = ['AssetPlatformViewSet']

View File

@ -33,7 +33,7 @@ def test_assets_connectivity_task(asset_ids, org_id, task_name=None):
def test_assets_connectivity_manual(assets): def test_assets_connectivity_manual(assets):
task_name = gettext_noop("Test assets connectivity ") task_name = gettext_noop("Test assets connectivity ")
asset_ids = [i.id for i in assets] asset_ids = [str(i.id) for i in assets]
org_id = str(current_org.id) org_id = str(current_org.id)
return test_assets_connectivity_task.delay(asset_ids, org_id, task_name) return test_assets_connectivity_task.delay(asset_ids, org_id, task_name)
@ -41,5 +41,6 @@ def test_assets_connectivity_manual(assets):
def test_node_assets_connectivity_manual(node): def test_node_assets_connectivity_manual(node):
task_name = gettext_noop("Test if the assets under the node are connectable ") task_name = gettext_noop("Test if the assets under the node are connectable ")
asset_ids = node.get_all_asset_ids() asset_ids = node.get_all_asset_ids()
asset_ids = [str(i) for i in asset_ids]
org_id = str(current_org.id) org_id = str(current_org.id)
return test_assets_connectivity_task.delay(asset_ids, org_id, task_name) return test_assets_connectivity_task.delay(asset_ids, org_id, task_name)

View File

@ -16,9 +16,6 @@ __all__ = [
class PaginatedResponseMixin: class PaginatedResponseMixin:
paginate_queryset: Callable
get_serializer: Callable
get_paginated_response: Callable
def get_paginated_response_from_queryset(self, queryset): def get_paginated_response_from_queryset(self, queryset):
page = self.paginate_queryset(queryset) page = self.paginate_queryset(queryset)

View File

@ -101,9 +101,9 @@ class DateTimeMixin:
@lazyproperty @lazyproperty
def operate_logs_queryset(self): def operate_logs_queryset(self):
from audits.api import OperateLogViewSet
t = self.days_to_datetime t = self.days_to_datetime
queryset = OperateLog.objects.filter(datetime__gte=t) queryset = OperateLogViewSet().get_queryset().filter(datetime__gte=t)
queryset = self.get_logs_queryset(queryset, 'user')
return queryset return queryset
@lazyproperty @lazyproperty

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-21 22:44+0800\n" "POT-Creation-Date: 2023-02-22 21:23+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -28,7 +28,7 @@ msgstr "パラメータ 'action' は [{}] でなければなりません。"
#: authentication/confirm/password.py:9 authentication/forms.py:32 #: authentication/confirm/password.py:9 authentication/forms.py:32
#: authentication/templates/authentication/login.html:274 #: authentication/templates/authentication/login.html:274
#: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:47 #: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:47
#: users/forms/profile.py:22 users/serializers/user.py:99 #: users/forms/profile.py:22 users/serializers/user.py:101
#: users/templates/users/_msg_user_created.html:13 #: users/templates/users/_msg_user_created.html:13
#: users/templates/users/user_password_verify.html:18 #: users/templates/users/user_password_verify.html:18
#: xpack/plugins/cloud/serializers/account_attrs.py:28 #: xpack/plugins/cloud/serializers/account_attrs.py:28
@ -172,7 +172,7 @@ msgstr "作成のみ"
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:27 #: perms/models/asset_permission.py:64 perms/serializers/permission.py:27
#: terminal/backends/command/models.py:20 terminal/models/session/session.py:32 #: terminal/backends/command/models.py:20 terminal/models/session/session.py:32
#: terminal/notifications.py:95 terminal/serializers/command.py:17 #: terminal/notifications.py:95 terminal/serializers/command.py:17
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 #: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:220
msgid "Asset" msgid "Asset"
msgstr "資産" msgstr "資産"
@ -223,15 +223,15 @@ msgstr "アカウントを確認できます"
msgid "Can push account" msgid "Can push account"
msgstr "アカウントをプッシュできます" msgstr "アカウントをプッシュできます"
#: accounts/models/account.py:113 #: accounts/models/account.py:109
msgid "Account template" msgid "Account template"
msgstr "アカウント テンプレート" msgstr "アカウント テンプレート"
#: accounts/models/account.py:118 #: accounts/models/account.py:114
msgid "Can view asset account template secret" msgid "Can view asset account template secret"
msgstr "アセット アカウント テンプレートのパスワードを表示できます" msgstr "アセット アカウント テンプレートのパスワードを表示できます"
#: accounts/models/account.py:119 #: accounts/models/account.py:115
msgid "Can change asset account template secret" msgid "Can change asset account template secret"
msgstr "アセット アカウント テンプレートのパスワードを変更できます" msgstr "アセット アカウント テンプレートのパスワードを変更できます"
@ -249,7 +249,7 @@ msgstr "アカウントバックアップ計画"
#: accounts/models/automations/backup_account.py:83 #: accounts/models/automations/backup_account.py:83
#: assets/models/automations/base.py:114 audits/models.py:55 #: assets/models/automations/base.py:114 audits/models.py:55
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:122 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:186
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:109 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:109
#: terminal/models/session/session.py:45 #: terminal/models/session/session.py:45
#: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_application.py:30
@ -269,21 +269,21 @@ msgstr "アカウントのバックアップスナップショット"
#: accounts/models/automations/backup_account.py:94 #: accounts/models/automations/backup_account.py:94
#: accounts/serializers/account/backup.py:42 #: accounts/serializers/account/backup.py:42
#: accounts/serializers/automations/base.py:53 #: accounts/serializers/automations/base.py:55
#: assets/models/automations/base.py:121 #: assets/models/automations/base.py:121
#: assets/serializers/automations/base.py:40 #: assets/serializers/automations/base.py:40
msgid "Trigger mode" msgid "Trigger mode"
msgstr "トリガーモード" msgstr "トリガーモード"
#: accounts/models/automations/backup_account.py:97 audits/models.py:172 #: accounts/models/automations/backup_account.py:97 audits/models.py:172
#: terminal/models/session/sharing.py:107 xpack/plugins/cloud/models.py:168 #: terminal/models/session/sharing.py:107 xpack/plugins/cloud/models.py:176
msgid "Reason" msgid "Reason"
msgstr "理由" msgstr "理由"
#: accounts/models/automations/backup_account.py:99 #: accounts/models/automations/backup_account.py:99
#: accounts/serializers/automations/change_secret.py:110 #: accounts/serializers/automations/change_secret.py:110
#: accounts/serializers/automations/change_secret.py:133 #: accounts/serializers/automations/change_secret.py:133
#: ops/serializers/job.py:64 terminal/serializers/session.py:45 #: ops/serializers/job.py:66 terminal/serializers/session.py:45
msgid "Is success" msgid "Is success"
msgstr "成功は" msgstr "成功は"
@ -328,7 +328,7 @@ msgid "Can add push account execution"
msgstr "プッシュ アカウントの作成の実行" msgstr "プッシュ アカウントの作成の実行"
#: accounts/models/automations/change_secret.py:17 accounts/models/base.py:36 #: accounts/models/automations/change_secret.py:17 accounts/models/base.py:36
#: accounts/serializers/account/account.py:132 #: accounts/serializers/account/account.py:134
#: accounts/serializers/account/base.py:16 #: accounts/serializers/account/base.py:16
#: accounts/serializers/automations/change_secret.py:46 #: accounts/serializers/automations/change_secret.py:46
#: authentication/serializers/connect_token_secret.py:41 #: authentication/serializers/connect_token_secret.py:41
@ -371,7 +371,7 @@ msgstr "開始日"
#: accounts/models/automations/change_secret.py:74 #: accounts/models/automations/change_secret.py:74
#: assets/models/automations/base.py:115 ops/models/base.py:56 #: assets/models/automations/base.py:115 ops/models/base.py:56
#: ops/models/celery.py:64 ops/models/job.py:123 #: ops/models/celery.py:64 ops/models/job.py:187
#: terminal/models/applet/host.py:110 #: terminal/models/applet/host.py:110
msgid "Date finished" msgid "Date finished"
msgstr "終了日" msgstr "終了日"
@ -450,7 +450,7 @@ msgstr "アカウントの確認"
#: assets/serializers/platform.py:91 assets/serializers/platform.py:136 #: assets/serializers/platform.py:91 assets/serializers/platform.py:136
#: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21 #: 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/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/models/job.py:90 ops/models/playbook.py:23 ops/serializers/job.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 #: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:27 terminal/models/component/endpoint.py:12 #: terminal/models/applet/applet.py:27 terminal/models/component/endpoint.py:12
@ -470,7 +470,7 @@ msgstr "特権アカウント"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22 #: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:107 #: authentication/serializers/connect_token_secret.py:107
#: terminal/models/applet/applet.py:32 users/serializers/user.py:159 #: terminal/models/applet/applet.py:32 users/serializers/user.py:161
msgid "Is active" msgid "Is active"
msgstr "アクティブです。" msgstr "アクティブです。"
@ -540,16 +540,16 @@ msgid "Category"
msgstr "カテゴリ" msgstr "カテゴリ"
#: accounts/serializers/account/account.py:76 #: accounts/serializers/account/account.py:76
#: accounts/serializers/automations/base.py:52 acls/models/command_acl.py:24 #: accounts/serializers/automations/base.py:54 acls/models/command_acl.py:24
#: acls/serializers/command_acl.py:18 applications/models.py:14 #: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:78 #: assets/models/cmd_filter.py:74 assets/models/platform.py:78
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96
#: audits/serializers.py:48 #: audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:37 #: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:101
#: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:31 #: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:31
#: terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:28 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:22 terminal/serializers/storage.py:224 #: terminal/serializers/session.py:22 terminal/serializers/storage.py:224
#: terminal/serializers/storage.py:236 tickets/models/comment.py:26 #: terminal/serializers/storage.py:236 tickets/models/comment.py:26
#: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16 #: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16
@ -592,14 +592,14 @@ msgid "Key password"
msgstr "キーパスワード" msgstr "キーパスワード"
#: accounts/serializers/account/base.py:79 #: accounts/serializers/account/base.py:79
#: assets/serializers/asset/common.py:288 #: assets/serializers/asset/common.py:290
msgid "Spec info" msgid "Spec info"
msgstr "特別情報" msgstr "特別情報"
#: accounts/serializers/automations/base.py:22 #: accounts/serializers/automations/base.py:22
#: assets/models/automations/base.py:19 #: assets/models/automations/base.py:19
#: assets/serializers/automations/base.py:20 ops/models/base.py:17 #: assets/serializers/automations/base.py:20 ops/models/base.py:17
#: ops/models/job.py:39 #: ops/models/job.py:103 ops/serializers/job.py:20
#: terminal/templates/terminal/_msg_command_execute_alert.html:16 #: terminal/templates/terminal/_msg_command_execute_alert.html:16
msgid "Assets" msgid "Assets"
msgstr "資産" msgstr "資産"
@ -611,11 +611,11 @@ msgstr "資産"
msgid "Nodes" msgid "Nodes"
msgstr "ノード" msgstr "ノード"
#: accounts/serializers/automations/base.py:42 #: accounts/serializers/automations/base.py:44
msgid "Name already exists" msgid "Name already exists"
msgstr "名前は既に存在します。" msgstr "名前は既に存在します。"
#: accounts/serializers/automations/base.py:51 #: accounts/serializers/automations/base.py:53
#: assets/models/automations/base.py:117 #: assets/models/automations/base.py:117
#: assets/serializers/automations/base.py:39 #: assets/serializers/automations/base.py:39
msgid "Automation snapshot" msgid "Automation snapshot"
@ -747,12 +747,12 @@ msgstr "アクティブ"
#: terminal/notifications.py:96 terminal/notifications.py:144 #: terminal/notifications.py:96 terminal/notifications.py:144
#: terminal/serializers/command.py:16 tickets/models/comment.py:21 #: terminal/serializers/command.py:16 tickets/models/comment.py:21
#: users/const.py:14 users/models/user.py:911 users/models/user.py:942 #: users/const.py:14 users/models/user.py:911 users/models/user.py:942
#: users/serializers/group.py:19 #: users/serializers/group.py:18
msgid "User" msgid "User"
msgstr "ユーザー" msgstr "ユーザー"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60 #: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
#: ops/serializers/job.py:63 terminal/const.py:67 #: ops/serializers/job.py:65 terminal/const.py:67
#: terminal/models/session/session.py:43 terminal/serializers/command.py:18 #: terminal/models/session/session.py:43 terminal/serializers/command.py:18
#: terminal/templates/terminal/_msg_command_alert.html:12 #: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10 #: terminal/templates/terminal/_msg_command_execute_alert.html:10
@ -934,7 +934,7 @@ msgstr "削除に失敗し、ノードにアセットが含まれています。
msgid "App assets" msgid "App assets"
msgstr "アプリ資産" msgstr "アプリ資産"
#: assets/automations/base/manager.py:107 #: assets/automations/base/manager.py:114
msgid "{} disabled" msgid "{} disabled"
msgstr "{} 無効" msgstr "{} 無効"
@ -988,7 +988,7 @@ msgstr "資産情報の収集"
#: assets/const/category.py:11 assets/models/asset/host.py:8 #: assets/const/category.py:11 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67
#: terminal/models/component/endpoint.py:13 #: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17
#: xpack/plugins/cloud/serializers/account_attrs.py:72 #: xpack/plugins/cloud/serializers/account_attrs.py:72
msgid "Host" msgid "Host"
msgstr "ホスト" msgstr "ホスト"
@ -1065,20 +1065,20 @@ msgstr "SSHパブリックキー"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40 #: assets/models/_user.py:27 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 assets/models/group.py:23 #: assets/models/cmd_filter.py:88 assets/models/group.py:23
#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:45 #: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:109
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38 #: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:155 #: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:158
#: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24 #: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100 #: terminal/models/component/endpoint.py:100
#: terminal/models/session/session.py:47 tickets/models/comment.py:32 #: terminal/models/session/session.py:47 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:756 #: tickets/models/ticket/general.py:297 users/models/user.py:756
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 #: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:119
msgid "Comment" msgid "Comment"
msgstr "コメント" msgstr "コメント"
#: assets/models/_user.py:28 assets/models/automations/base.py:113 #: assets/models/_user.py:28 assets/models/automations/base.py:113
#: assets/models/cmd_filter.py:41 assets/models/group.py:22 #: 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:121 #: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:185
#: users/models/user.py:943 #: users/models/user.py:943
msgid "Date created" msgid "Date created"
msgstr "作成された日付" msgstr "作成された日付"
@ -1091,7 +1091,7 @@ msgstr "更新日"
#: assets/models/_user.py:30 assets/models/cmd_filter.py:44 #: assets/models/_user.py:30 assets/models/cmd_filter.py:44
#: assets/models/cmd_filter.py:91 assets/models/group.py:21 #: assets/models/cmd_filter.py:91 assets/models/group.py:21
#: common/db/models.py:33 users/models/user.py:763 #: common/db/models.py:33 users/models/user.py:763
#: users/serializers/group.py:33 #: users/serializers/group.py:31
msgid "Created by" msgid "Created by"
msgstr "によって作成された" msgstr "によって作成された"
@ -1183,7 +1183,7 @@ msgstr "アドレス"
#: assets/models/asset/common.py:104 assets/models/platform.py:112 #: assets/models/asset/common.py:104 assets/models/platform.py:112
#: authentication/serializers/connect_token_secret.py:108 #: authentication/serializers/connect_token_secret.py:108
#: perms/serializers/user_permission.py:23 #: perms/serializers/user_permission.py:23
#: xpack/plugins/cloud/serializers/account_attrs.py:187 #: xpack/plugins/cloud/serializers/account_attrs.py:179
msgid "Platform" msgid "Platform"
msgstr "プラットフォーム" msgstr "プラットフォーム"
@ -1254,7 +1254,7 @@ msgid "Submit selector"
msgstr "ボタンセレクターを確認する" msgstr "ボタンセレクターを確認する"
#: assets/models/automations/base.py:17 assets/models/cmd_filter.py:38 #: assets/models/automations/base.py:17 assets/models/cmd_filter.py:38
#: assets/serializers/asset/common.py:287 rbac/tree.py:36 #: assets/serializers/asset/common.py:289 rbac/tree.py:36
msgid "Accounts" msgid "Accounts"
msgstr "アカウント" msgstr "アカウント"
@ -1267,13 +1267,13 @@ msgid "Asset automation task"
msgstr "アセットの自動化タスク" msgstr "アセットの自動化タスク"
#: assets/models/automations/base.py:112 audits/models.py:177 #: assets/models/automations/base.py:112 audits/models.py:177
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:114 #: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:178
#: terminal/models/applet/applet.py:154 terminal/models/applet/host.py:108 #: terminal/models/applet/applet.py:157 terminal/models/applet/host.py:108
#: terminal/models/component/status.py:27 terminal/serializers/applet.py:17 #: terminal/models/component/status.py:27 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283 #: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13 #: tickets/serializers/super_ticket.py:13
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 #: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:172
#: xpack/plugins/cloud/models.py:216 #: xpack/plugins/cloud/models.py:224
msgid "Status" msgid "Status"
msgstr "ステータス" msgstr "ステータス"
@ -1492,7 +1492,8 @@ msgstr "自動充填"
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:99 #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:99
#: authentication/serializers/connect_token_secret.py:28 #: authentication/serializers/connect_token_secret.py:28
#: authentication/serializers/connect_token_secret.py:66 #: authentication/serializers/connect_token_secret.py:66
#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:99 #: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:107
#: xpack/plugins/cloud/serializers/task.py:38
msgid "Protocols" msgid "Protocols"
msgstr "プロトコル" msgstr "プロトコル"
@ -1512,15 +1513,13 @@ msgstr "ポート番号が範囲外です (1-65535)"
msgid "Protocol is required: {}" msgid "Protocol is required: {}"
msgstr "プロトコルが必要です: {}" msgstr "プロトコルが必要です: {}"
#: assets/serializers/asset/common.py:289 #: assets/serializers/asset/common.py:291
msgid "Auto info" msgid "Auto info"
msgstr "自動情報" msgstr "自動情報"
#: assets/serializers/asset/database.py:25 common/serializers/fields.py:100 #: assets/serializers/asset/database.py:25 common/serializers/fields.py:100
#: tickets/serializers/ticket/common.py:58 #: tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56 #: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
#: xpack/plugins/cloud/serializers/account_attrs.py:143
msgid "This field is required." msgid "This field is required."
msgstr "このフィールドは必須です。" msgstr "このフィールドは必須です。"
@ -2465,7 +2464,7 @@ msgstr "すぐに期限切れ"
#: authentication/serializers/connect_token_secret.py:148 #: authentication/serializers/connect_token_secret.py:148
#: authentication/templates/authentication/_access_key_modal.html:30 #: authentication/templates/authentication/_access_key_modal.html:30
#: perms/models/perm_node.py:21 users/serializers/group.py:35 #: perms/models/perm_node.py:21 users/serializers/group.py:33
msgid "ID" msgid "ID"
msgstr "ID" msgstr "ID"
@ -2487,7 +2486,7 @@ msgstr "アクション"
#: authentication/serializers/connection_token.py:41 #: authentication/serializers/connection_token.py:41
#: perms/serializers/permission.py:31 perms/serializers/permission.py:61 #: perms/serializers/permission.py:31 perms/serializers/permission.py:61
#: users/serializers/user.py:93 users/serializers/user.py:162 #: users/serializers/user.py:93 users/serializers/user.py:164
msgid "Is expired" msgid "Is expired"
msgstr "期限切れです" msgstr "期限切れです"
@ -2507,7 +2506,8 @@ msgid "The {} cannot be empty"
msgstr "{} 空にしてはならない" msgstr "{} 空にしてはならない"
#: authentication/serializers/token.py:79 perms/serializers/permission.py:30 #: authentication/serializers/token.py:79 perms/serializers/permission.py:30
#: perms/serializers/permission.py:62 users/serializers/user.py:160 #: perms/serializers/permission.py:62 users/serializers/user.py:94
#: users/serializers/user.py:162
msgid "Is valid" msgid "Is valid"
msgstr "有効です" msgstr "有効です"
@ -3235,6 +3235,10 @@ msgstr "タスクは存在しません"
msgid "Task {} args or kwargs error" msgid "Task {} args or kwargs error"
msgstr "タスク実行パラメータエラー" msgstr "タスク実行パラメータエラー"
#: ops/api/playbook.py:83
msgid "Unsupported file content"
msgstr "サポートされていないファイルの内容"
#: ops/apps.py:9 ops/notifications.py:16 rbac/tree.py:56 #: ops/apps.py:9 ops/notifications.py:16 rbac/tree.py:56
msgid "App ops" msgid "App ops"
msgstr "アプリ操作" msgstr "アプリ操作"
@ -3275,7 +3279,7 @@ msgstr "VCS"
msgid "Adhoc" msgid "Adhoc"
msgstr "コマンド#コマンド#" msgstr "コマンド#コマンド#"
#: ops/const.py:39 ops/models/job.py:35 #: ops/const.py:39 ops/models/job.py:99
msgid "Playbook" msgid "Playbook"
msgstr "Playbook" msgstr "Playbook"
@ -3336,17 +3340,17 @@ msgstr "定期的または定期的に設定を行う必要があります"
msgid "Pattern" msgid "Pattern"
msgstr "パターン" msgstr "パターン"
#: ops/models/adhoc.py:24 ops/models/job.py:30 #: ops/models/adhoc.py:24 ops/models/job.py:94
msgid "Module" msgid "Module"
msgstr "モジュール" msgstr "モジュール"
#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:29 #: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:93
#: terminal/models/component/task.py:16 #: terminal/models/component/task.py:16
msgid "Args" msgid "Args"
msgstr "アルグ" msgstr "アルグ"
#: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53 #: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53
#: ops/models/job.py:38 ops/models/job.py:120 ops/models/playbook.py:25 #: ops/models/job.py:102 ops/models/job.py:184 ops/models/playbook.py:25
#: terminal/models/session/sharing.py:23 #: terminal/models/session/sharing.py:23
msgid "Creator" msgid "Creator"
msgstr "作成者" msgstr "作成者"
@ -3363,12 +3367,12 @@ msgstr "最後の実行"
msgid "Date last run" msgid "Date last run"
msgstr "最終実行日" msgstr "最終実行日"
#: ops/models/base.py:51 ops/models/job.py:118 #: ops/models/base.py:51 ops/models/job.py:182
#: xpack/plugins/cloud/models.py:162 #: xpack/plugins/cloud/models.py:170
msgid "Result" msgid "Result"
msgstr "結果" msgstr "結果"
#: ops/models/base.py:52 ops/models/job.py:119 #: ops/models/base.py:52 ops/models/job.py:183
msgid "Summary" msgid "Summary"
msgstr "概要" msgstr "概要"
@ -3408,47 +3412,47 @@ msgstr "発売日"
msgid "Celery Task Execution" msgid "Celery Task Execution"
msgstr "Celery タスク実行" msgstr "Celery タスク実行"
#: ops/models/job.py:32 #: ops/models/job.py:96
msgid "Chdir" msgid "Chdir"
msgstr "実行ディレクトリ" msgstr "実行ディレクトリ"
#: ops/models/job.py:33 #: ops/models/job.py:97
msgid "Timeout (Seconds)" msgid "Timeout (Seconds)"
msgstr "タイムアウト(秒)" msgstr "タイムアウト(秒)"
#: ops/models/job.py:40 #: ops/models/job.py:104
msgid "Use Parameter Define" msgid "Use Parameter Define"
msgstr "パラメータ定義を使用する" msgstr "パラメータ定義を使用する"
#: ops/models/job.py:41 #: ops/models/job.py:105
msgid "Parameters define" msgid "Parameters define"
msgstr "パラメータ定義" msgstr "パラメータ定義"
#: ops/models/job.py:42 #: ops/models/job.py:106
msgid "Runas" msgid "Runas"
msgstr "ユーザーとして実行" msgstr "ユーザーとして実行"
#: ops/models/job.py:44 #: ops/models/job.py:108
msgid "Runas policy" msgid "Runas policy"
msgstr "ユーザー ポリシー" msgstr "ユーザー ポリシー"
#: ops/models/job.py:106 #: ops/models/job.py:170
msgid "Job" msgid "Job"
msgstr "ジョブ#ジョブ#" msgstr "ジョブ#ジョブ#"
#: ops/models/job.py:117 #: ops/models/job.py:181
msgid "Parameters" msgid "Parameters"
msgstr "パラメータ" msgstr "パラメータ"
#: ops/models/job.py:125 #: ops/models/job.py:189
msgid "Material" msgid "Material"
msgstr "" msgstr ""
#: ops/models/job.py:127 #: ops/models/job.py:191
msgid "Material Type" msgid "Material Type"
msgstr "" msgstr ""
#: ops/models/job.py:364 #: ops/models/job.py:442
msgid "Job Execution" msgid "Job Execution"
msgstr "ジョブ実行" msgstr "ジョブ実行"
@ -3492,15 +3496,15 @@ msgstr "{max_threshold} を超えるCPUロード: => {value}"
msgid "Run after save" msgid "Run after save"
msgstr "保存後に実行" msgstr "保存後に実行"
#: ops/serializers/job.py:62 #: ops/serializers/job.py:64
msgid "Job type" msgid "Job type"
msgstr "タスクの種類" msgstr "タスクの種類"
#: ops/serializers/job.py:65 terminal/serializers/session.py:49 #: ops/serializers/job.py:67 terminal/serializers/session.py:49
msgid "Is finished" msgid "Is finished"
msgstr "終了しました" msgstr "終了しました"
#: ops/serializers/job.py:66 #: ops/serializers/job.py:68
msgid "Time cost" msgid "Time cost"
msgstr "時を過ごす" msgstr "時を過ごす"
@ -3726,7 +3730,7 @@ msgstr "内部の役割は、破壊することはできません"
msgid "The role has been bound to users, can't be destroy" msgid "The role has been bound to users, can't be destroy"
msgstr "ロールはユーザーにバインドされており、破壊することはできません" msgstr "ロールはユーザーにバインドされており、破壊することはできません"
#: rbac/api/role.py:82 #: rbac/api/role.py:83
msgid "Internal role, can't be update" msgid "Internal role, can't be update"
msgstr "内部ロール、更新できません" msgstr "内部ロール、更新できません"
@ -3835,7 +3839,7 @@ msgstr "システムロールバインディング"
msgid "Perms" msgid "Perms"
msgstr "パーマ" msgstr "パーマ"
#: rbac/serializers/role.py:27 users/serializers/group.py:34 #: rbac/serializers/role.py:27 users/serializers/group.py:32
msgid "Users amount" msgid "Users amount"
msgstr "ユーザー数" msgstr "ユーザー数"
@ -3904,7 +3908,8 @@ msgid "My assets"
msgstr "私の資産" msgstr "私の資産"
#: rbac/tree.py:57 terminal/models/applet/applet.py:43 #: rbac/tree.py:57 terminal/models/applet/applet.py:43
#: terminal/models/applet/applet.py:151 terminal/models/applet/host.py:28 #: terminal/models/applet/applet.py:154 terminal/models/applet/host.py:28
#: terminal/serializers/applet.py:15
msgid "Applet" msgid "Applet"
msgstr "リモートアプリケーション" msgstr "リモートアプリケーション"
@ -4403,7 +4408,7 @@ msgid "SSO auth key TTL"
msgstr "Token有効期間" msgstr "Token有効期間"
#: settings/serializers/auth/sso.py:17 #: settings/serializers/auth/sso.py:17
#: xpack/plugins/cloud/serializers/account_attrs.py:184 #: xpack/plugins/cloud/serializers/account_attrs.py:176
msgid "Unit: second" msgid "Unit: second"
msgstr "単位: 秒" msgstr "単位: 秒"
@ -5444,7 +5449,7 @@ msgstr "ホスト"
msgid "Applet pkg not valid, Missing file {}" msgid "Applet pkg not valid, Missing file {}"
msgstr "無効なアプレット パッケージ、ファイル {} がありません" msgstr "無効なアプレット パッケージ、ファイル {} がありません"
#: terminal/models/applet/applet.py:153 terminal/models/applet/host.py:34 #: terminal/models/applet/applet.py:156 terminal/models/applet/host.py:34
#: terminal/models/applet/host.py:106 #: terminal/models/applet/host.py:106
msgid "Hosting" msgid "Hosting"
msgstr "ホスト マシン" msgstr "ホスト マシン"
@ -5687,7 +5692,7 @@ msgstr "レベル"
msgid "Batch danger command alert" msgid "Batch danger command alert"
msgstr "一括危険コマンド警告" msgstr "一括危険コマンド警告"
#: terminal/serializers/applet.py:27 #: terminal/serializers/applet.py:28
msgid "Icon" msgid "Icon"
msgstr "アイコン" msgstr "アイコン"
@ -5816,7 +5821,7 @@ msgstr "アクセスキー"
msgid "Access key secret" msgid "Access key secret"
msgstr "アクセスキーシークレット" msgstr "アクセスキーシークレット"
#: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:209 #: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:217
msgid "Region" msgid "Region"
msgstr "リージョン" msgstr "リージョン"
@ -6250,7 +6255,7 @@ msgstr "無効な承認アクション"
msgid "This user is not authorized to approve this ticket" msgid "This user is not authorized to approve this ticket"
msgstr "このユーザーはこの作業指示を承認する権限がありません" msgstr "このユーザーはこの作業指示を承認する権限がありません"
#: users/api/user.py:178 #: users/api/user.py:179
msgid "Could not reset self otp, use profile reset instead" msgid "Could not reset self otp, use profile reset instead"
msgstr "自己otpをリセットできませんでした、代わりにプロファイルリセットを使用" msgstr "自己otpをリセットできませんでした、代わりにプロファイルリセットを使用"
@ -6369,7 +6374,7 @@ msgstr "公開キー"
msgid "Force enable" msgid "Force enable"
msgstr "強制有効" msgstr "強制有効"
#: users/models/user.py:729 users/serializers/user.py:161 #: users/models/user.py:729 users/serializers/user.py:163
msgid "Is service account" msgid "Is service account"
msgstr "サービスアカウントです" msgstr "サービスアカウントです"
@ -6398,7 +6403,7 @@ msgid "Secret key"
msgstr "秘密キー" msgstr "秘密キー"
#: users/models/user.py:758 users/serializers/profile.py:147 #: users/models/user.py:758 users/serializers/profile.py:147
#: users/serializers/user.py:158 #: users/serializers/user.py:160
msgid "Is first login" msgid "Is first login"
msgstr "最初のログインです" msgstr "最初のログインです"
@ -6505,27 +6510,27 @@ msgstr "MFAフォース有効化"
msgid "Login blocked" msgid "Login blocked"
msgstr "ログインブロック" msgstr "ログインブロック"
#: users/serializers/user.py:95 #: users/serializers/user.py:95 users/serializers/user.py:168
msgid "Can public key authentication"
msgstr "公開鍵認証が可能"
#: users/serializers/user.py:163
msgid "Avatar url"
msgstr "アバターURL"
#: users/serializers/user.py:166
msgid "Is OTP bound" msgid "Is OTP bound"
msgstr "仮想MFAがバインドされているか" msgstr "仮想MFAがバインドされているか"
#: users/serializers/user.py:273 #: users/serializers/user.py:97
msgid "Can public key authentication"
msgstr "公開鍵認証が可能"
#: users/serializers/user.py:165
msgid "Avatar url"
msgstr "アバターURL"
#: users/serializers/user.py:275
msgid "Select users" msgid "Select users"
msgstr "ユーザーの選択" msgstr "ユーザーの選択"
#: users/serializers/user.py:274 #: users/serializers/user.py:276
msgid "For security, only list several users" msgid "For security, only list several users"
msgstr "セキュリティのために、複数のユーザーのみをリストします" msgstr "セキュリティのために、複数のユーザーのみをリストします"
#: users/serializers/user.py:307 #: users/serializers/user.py:309
msgid "name not unique" msgid "name not unique"
msgstr "名前が一意ではない" msgstr "名前が一意ではない"
@ -6947,47 +6952,59 @@ msgstr "リージョン"
msgid "Hostname strategy" msgid "Hostname strategy"
msgstr "ホスト名戦略" msgstr "ホスト名戦略"
#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:40 #: xpack/plugins/cloud/models.py:100
#, fuzzy
#| msgid "Only admin users"
msgid "Unix admin user"
msgstr "管理者のみ"
#: xpack/plugins/cloud/models.py:104
#, fuzzy
#| msgid "Only admin users"
msgid "Windows admin user"
msgstr "管理者のみ"
#: xpack/plugins/cloud/models.py:110 xpack/plugins/cloud/serializers/task.py:41
msgid "IP network segment group" msgid "IP network segment group"
msgstr "IPネットワークセグメントグループ" msgstr "IPネットワークセグメントグループ"
#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:45 #: xpack/plugins/cloud/models.py:113 xpack/plugins/cloud/serializers/task.py:46
msgid "Sync IP type" msgid "Sync IP type"
msgstr "同期IPタイプ" msgstr "同期IPタイプ"
#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:62 #: xpack/plugins/cloud/models.py:116 xpack/plugins/cloud/serializers/task.py:64
msgid "Always update" msgid "Always update"
msgstr "常に更新" msgstr "常に更新"
#: xpack/plugins/cloud/models.py:114 #: xpack/plugins/cloud/models.py:122
msgid "Date last sync" msgid "Date last sync"
msgstr "最終同期日" msgstr "最終同期日"
#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 #: xpack/plugins/cloud/models.py:127 xpack/plugins/cloud/models.py:168
msgid "Sync instance task" msgid "Sync instance task"
msgstr "インスタンスの同期タスク" msgstr "インスタンスの同期タスク"
#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 #: xpack/plugins/cloud/models.py:179 xpack/plugins/cloud/models.py:227
msgid "Date sync" msgid "Date sync"
msgstr "日付の同期" msgstr "日付の同期"
#: xpack/plugins/cloud/models.py:175 #: xpack/plugins/cloud/models.py:183
msgid "Sync instance task execution" msgid "Sync instance task execution"
msgstr "インスタンスタスクの同期実行" msgstr "インスタンスタスクの同期実行"
#: xpack/plugins/cloud/models.py:199 #: xpack/plugins/cloud/models.py:207
msgid "Sync task" msgid "Sync task"
msgstr "同期タスク" msgstr "同期タスク"
#: xpack/plugins/cloud/models.py:203 #: xpack/plugins/cloud/models.py:211
msgid "Sync instance task history" msgid "Sync instance task history"
msgstr "インスタンスタスク履歴の同期" msgstr "インスタンスタスク履歴の同期"
#: xpack/plugins/cloud/models.py:206 #: xpack/plugins/cloud/models.py:214
msgid "Instance" msgid "Instance"
msgstr "インスタンス" msgstr "インスタンス"
#: xpack/plugins/cloud/models.py:223 #: xpack/plugins/cloud/models.py:231
msgid "Sync instance detail" msgid "Sync instance detail"
msgstr "同期インスタンスの詳細" msgstr "同期インスタンスの詳細"
@ -7201,52 +7218,52 @@ msgstr "テナントID"
msgid "Subscription ID" msgid "Subscription ID"
msgstr "サブスクリプションID" msgstr "サブスクリプションID"
#: xpack/plugins/cloud/serializers/account_attrs.py:98 #: xpack/plugins/cloud/serializers/account_attrs.py:95
#: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:100
#: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:116
#: xpack/plugins/cloud/serializers/account_attrs.py:149 #: xpack/plugins/cloud/serializers/account_attrs.py:141
msgid "API Endpoint" msgid "API Endpoint"
msgstr "APIエンドポイント" msgstr "APIエンドポイント"
#: xpack/plugins/cloud/serializers/account_attrs.py:109 #: xpack/plugins/cloud/serializers/account_attrs.py:106
msgid "Auth url" msgid "Auth url"
msgstr "認証アドレス" msgstr "認証アドレス"
#: xpack/plugins/cloud/serializers/account_attrs.py:110 #: xpack/plugins/cloud/serializers/account_attrs.py:107
msgid "eg: http://openstack.example.com:5000/v3" msgid "eg: http://openstack.example.com:5000/v3"
msgstr "例えば: http://openstack.example.com:5000/v3" msgstr "例えば: http://openstack.example.com:5000/v3"
#: xpack/plugins/cloud/serializers/account_attrs.py:113 #: xpack/plugins/cloud/serializers/account_attrs.py:110
msgid "User domain" msgid "User domain"
msgstr "ユーザードメイン" msgstr "ユーザードメイン"
#: xpack/plugins/cloud/serializers/account_attrs.py:120 #: xpack/plugins/cloud/serializers/account_attrs.py:117
msgid "Cert File" msgid "Cert File"
msgstr "証明書ファイル" msgstr "証明書ファイル"
#: xpack/plugins/cloud/serializers/account_attrs.py:121 #: xpack/plugins/cloud/serializers/account_attrs.py:118
msgid "Key File" msgid "Key File"
msgstr "キーファイル" msgstr "キーファイル"
#: xpack/plugins/cloud/serializers/account_attrs.py:137 #: xpack/plugins/cloud/serializers/account_attrs.py:134
msgid "Service account key" msgid "Service account key"
msgstr "サービスアカウントキー" msgstr "サービスアカウントキー"
#: xpack/plugins/cloud/serializers/account_attrs.py:138 #: xpack/plugins/cloud/serializers/account_attrs.py:135
msgid "The file is in JSON format" msgid "The file is in JSON format"
msgstr "ファイルはJSON形式です。" msgstr "ファイルはJSON形式です。"
#: xpack/plugins/cloud/serializers/account_attrs.py:156 #: xpack/plugins/cloud/serializers/account_attrs.py:148
msgid "IP address invalid `{}`, {}" msgid "IP address invalid `{}`, {}"
msgstr "IPアドレスが無効: '{}', {}" msgstr "IPアドレスが無効: '{}', {}"
#: xpack/plugins/cloud/serializers/account_attrs.py:162 #: xpack/plugins/cloud/serializers/account_attrs.py:154
msgid "" msgid ""
"Format for comma-delimited string,Such as: 192.168.1.0/24, " "Format for comma-delimited string,Such as: 192.168.1.0/24, "
"10.0.0.0-10.0.0.255" "10.0.0.0-10.0.0.255"
msgstr "形式はコンマ区切りの文字列です192.168.1.0/24,10.0.0.0-10.0.0.255" msgstr "形式はコンマ区切りの文字列です192.168.1.0/24,10.0.0.0-10.0.0.255"
#: xpack/plugins/cloud/serializers/account_attrs.py:166 #: xpack/plugins/cloud/serializers/account_attrs.py:158
msgid "" msgid ""
"The port is used to detect the validity of the IP address. When the " "The port is used to detect the validity of the IP address. When the "
"synchronization task is executed, only the valid IP address will be " "synchronization task is executed, only the valid IP address will be "
@ -7256,19 +7273,19 @@ msgstr ""
"実行されると、有効な IP アドレスのみが同期されます。 <br>ポートが0の場合、す" "実行されると、有効な IP アドレスのみが同期されます。 <br>ポートが0の場合、す"
"べてのIPアドレスが有効です。" "べてのIPアドレスが有効です。"
#: xpack/plugins/cloud/serializers/account_attrs.py:174 #: xpack/plugins/cloud/serializers/account_attrs.py:166
msgid "Hostname prefix" msgid "Hostname prefix"
msgstr "ホスト名プレフィックス" msgstr "ホスト名プレフィックス"
#: xpack/plugins/cloud/serializers/account_attrs.py:177 #: xpack/plugins/cloud/serializers/account_attrs.py:169
msgid "IP segment" msgid "IP segment"
msgstr "IP セグメント" msgstr "IP セグメント"
#: xpack/plugins/cloud/serializers/account_attrs.py:181 #: xpack/plugins/cloud/serializers/account_attrs.py:173
msgid "Test port" msgid "Test port"
msgstr "テストポート" msgstr "テストポート"
#: xpack/plugins/cloud/serializers/account_attrs.py:184 #: xpack/plugins/cloud/serializers/account_attrs.py:176
msgid "Test timeout" msgid "Test timeout"
msgstr "テストタイムアウト" msgstr "テストタイムアウト"
@ -7294,13 +7311,11 @@ msgstr "実行回数"
msgid "Instance count" msgid "Instance count"
msgstr "インスタンス数" msgstr "インスタンス数"
#: xpack/plugins/cloud/tasks.py:27 #: xpack/plugins/cloud/serializers/task.py:63
msgid "Run sync instance task" #, fuzzy
msgstr "同期インスタンス タスクを実行する" #| msgid "Only admin users"
msgid "Linux admin user"
#: xpack/plugins/cloud/tasks.py:41 msgstr "管理者のみ"
msgid "Period clean sync instance task execution"
msgstr "同期インスタンス タスクの実行記録を定期的にクリアする"
#: xpack/plugins/cloud/utils.py:69 #: xpack/plugins/cloud/utils.py:69
msgid "Account unavailable" msgid "Account unavailable"
@ -7370,6 +7385,12 @@ msgstr "究極のエディション"
msgid "Community edition" msgid "Community edition"
msgstr "コミュニティ版" msgstr "コミュニティ版"
#~ msgid "Run sync instance task"
#~ msgstr "同期インスタンス タスクを実行する"
#~ msgid "Period clean sync instance task execution"
#~ msgstr "同期インスタンス タスクの実行記録を定期的にクリアする"
#~ msgid "Can push account to asset" #~ msgid "Can push account to asset"
#~ msgstr "アカウントをアセットにプッシュできます" #~ msgstr "アカウントをアセットにプッシュできます"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n" "Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-21 22:44+0800\n" "POT-Creation-Date: 2023-02-22 21:23+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n" "Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -27,7 +27,7 @@ msgstr "参数 'action' 必须是 [{}]"
#: authentication/confirm/password.py:9 authentication/forms.py:32 #: authentication/confirm/password.py:9 authentication/forms.py:32
#: authentication/templates/authentication/login.html:274 #: authentication/templates/authentication/login.html:274
#: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:47 #: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:47
#: users/forms/profile.py:22 users/serializers/user.py:99 #: users/forms/profile.py:22 users/serializers/user.py:101
#: users/templates/users/_msg_user_created.html:13 #: users/templates/users/_msg_user_created.html:13
#: users/templates/users/user_password_verify.html:18 #: users/templates/users/user_password_verify.html:18
#: xpack/plugins/cloud/serializers/account_attrs.py:28 #: xpack/plugins/cloud/serializers/account_attrs.py:28
@ -171,7 +171,7 @@ msgstr "仅创建"
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:27 #: perms/models/asset_permission.py:64 perms/serializers/permission.py:27
#: terminal/backends/command/models.py:20 terminal/models/session/session.py:32 #: terminal/backends/command/models.py:20 terminal/models/session/session.py:32
#: terminal/notifications.py:95 terminal/serializers/command.py:17 #: terminal/notifications.py:95 terminal/serializers/command.py:17
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 #: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:220
msgid "Asset" msgid "Asset"
msgstr "资产" msgstr "资产"
@ -222,15 +222,15 @@ msgstr "可以验证账号"
msgid "Can push account" msgid "Can push account"
msgstr "可以推送账号" msgstr "可以推送账号"
#: accounts/models/account.py:113 #: accounts/models/account.py:109
msgid "Account template" msgid "Account template"
msgstr "账号模版" msgstr "账号模版"
#: accounts/models/account.py:118 #: accounts/models/account.py:114
msgid "Can view asset account template secret" msgid "Can view asset account template secret"
msgstr "可以查看资产账号模版密码" msgstr "可以查看资产账号模版密码"
#: accounts/models/account.py:119 #: accounts/models/account.py:115
msgid "Can change asset account template secret" msgid "Can change asset account template secret"
msgstr "可以更改资产账号模版密码" msgstr "可以更改资产账号模版密码"
@ -248,7 +248,7 @@ msgstr "账号备份计划"
#: accounts/models/automations/backup_account.py:83 #: accounts/models/automations/backup_account.py:83
#: assets/models/automations/base.py:114 audits/models.py:55 #: assets/models/automations/base.py:114 audits/models.py:55
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:122 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:186
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:109 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:109
#: terminal/models/session/session.py:45 #: terminal/models/session/session.py:45
#: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_application.py:30
@ -268,21 +268,21 @@ msgstr "账号备份快照"
#: accounts/models/automations/backup_account.py:94 #: accounts/models/automations/backup_account.py:94
#: accounts/serializers/account/backup.py:42 #: accounts/serializers/account/backup.py:42
#: accounts/serializers/automations/base.py:53 #: accounts/serializers/automations/base.py:55
#: assets/models/automations/base.py:121 #: assets/models/automations/base.py:121
#: assets/serializers/automations/base.py:40 #: assets/serializers/automations/base.py:40
msgid "Trigger mode" msgid "Trigger mode"
msgstr "触发模式" msgstr "触发模式"
#: accounts/models/automations/backup_account.py:97 audits/models.py:172 #: accounts/models/automations/backup_account.py:97 audits/models.py:172
#: terminal/models/session/sharing.py:107 xpack/plugins/cloud/models.py:168 #: terminal/models/session/sharing.py:107 xpack/plugins/cloud/models.py:176
msgid "Reason" msgid "Reason"
msgstr "原因" msgstr "原因"
#: accounts/models/automations/backup_account.py:99 #: accounts/models/automations/backup_account.py:99
#: accounts/serializers/automations/change_secret.py:110 #: accounts/serializers/automations/change_secret.py:110
#: accounts/serializers/automations/change_secret.py:133 #: accounts/serializers/automations/change_secret.py:133
#: ops/serializers/job.py:64 terminal/serializers/session.py:45 #: ops/serializers/job.py:66 terminal/serializers/session.py:45
msgid "Is success" msgid "Is success"
msgstr "是否成功" msgstr "是否成功"
@ -327,7 +327,7 @@ msgid "Can add push account execution"
msgstr "创建推送账号执行" msgstr "创建推送账号执行"
#: accounts/models/automations/change_secret.py:17 accounts/models/base.py:36 #: accounts/models/automations/change_secret.py:17 accounts/models/base.py:36
#: accounts/serializers/account/account.py:132 #: accounts/serializers/account/account.py:134
#: accounts/serializers/account/base.py:16 #: accounts/serializers/account/base.py:16
#: accounts/serializers/automations/change_secret.py:46 #: accounts/serializers/automations/change_secret.py:46
#: authentication/serializers/connect_token_secret.py:41 #: authentication/serializers/connect_token_secret.py:41
@ -370,7 +370,7 @@ msgstr "开始日期"
#: accounts/models/automations/change_secret.py:74 #: accounts/models/automations/change_secret.py:74
#: assets/models/automations/base.py:115 ops/models/base.py:56 #: assets/models/automations/base.py:115 ops/models/base.py:56
#: ops/models/celery.py:64 ops/models/job.py:123 #: ops/models/celery.py:64 ops/models/job.py:187
#: terminal/models/applet/host.py:110 #: terminal/models/applet/host.py:110
msgid "Date finished" msgid "Date finished"
msgstr "结束日期" msgstr "结束日期"
@ -449,7 +449,7 @@ msgstr "账号验证"
#: assets/serializers/platform.py:91 assets/serializers/platform.py:136 #: assets/serializers/platform.py:91 assets/serializers/platform.py:136
#: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21 #: 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/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/models/job.py:90 ops/models/playbook.py:23 ops/serializers/job.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 #: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:27 terminal/models/component/endpoint.py:12 #: terminal/models/applet/applet.py:27 terminal/models/component/endpoint.py:12
@ -469,7 +469,7 @@ msgstr "特权账号"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22 #: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:107 #: authentication/serializers/connect_token_secret.py:107
#: terminal/models/applet/applet.py:32 users/serializers/user.py:159 #: terminal/models/applet/applet.py:32 users/serializers/user.py:161
msgid "Is active" msgid "Is active"
msgstr "激活" msgstr "激活"
@ -536,16 +536,16 @@ msgid "Category"
msgstr "类别" msgstr "类别"
#: accounts/serializers/account/account.py:76 #: accounts/serializers/account/account.py:76
#: accounts/serializers/automations/base.py:52 acls/models/command_acl.py:24 #: accounts/serializers/automations/base.py:54 acls/models/command_acl.py:24
#: acls/serializers/command_acl.py:18 applications/models.py:14 #: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:78 #: assets/models/cmd_filter.py:74 assets/models/platform.py:78
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96
#: audits/serializers.py:48 #: audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:37 #: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:101
#: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:31 #: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:31
#: terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:28 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:22 terminal/serializers/storage.py:224 #: terminal/serializers/session.py:22 terminal/serializers/storage.py:224
#: terminal/serializers/storage.py:236 tickets/models/comment.py:26 #: terminal/serializers/storage.py:236 tickets/models/comment.py:26
#: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16 #: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16
@ -588,14 +588,14 @@ msgid "Key password"
msgstr "密钥密码" msgstr "密钥密码"
#: accounts/serializers/account/base.py:79 #: accounts/serializers/account/base.py:79
#: assets/serializers/asset/common.py:288 #: assets/serializers/asset/common.py:290
msgid "Spec info" msgid "Spec info"
msgstr "特殊信息" msgstr "特殊信息"
#: accounts/serializers/automations/base.py:22 #: accounts/serializers/automations/base.py:22
#: assets/models/automations/base.py:19 #: assets/models/automations/base.py:19
#: assets/serializers/automations/base.py:20 ops/models/base.py:17 #: assets/serializers/automations/base.py:20 ops/models/base.py:17
#: ops/models/job.py:39 #: ops/models/job.py:103 ops/serializers/job.py:20
#: terminal/templates/terminal/_msg_command_execute_alert.html:16 #: terminal/templates/terminal/_msg_command_execute_alert.html:16
msgid "Assets" msgid "Assets"
msgstr "资产" msgstr "资产"
@ -607,11 +607,11 @@ msgstr "资产"
msgid "Nodes" msgid "Nodes"
msgstr "节点" msgstr "节点"
#: accounts/serializers/automations/base.py:42 #: accounts/serializers/automations/base.py:44
msgid "Name already exists" msgid "Name already exists"
msgstr "名称已存在" msgstr "名称已存在"
#: accounts/serializers/automations/base.py:51 #: accounts/serializers/automations/base.py:53
#: assets/models/automations/base.py:117 #: assets/models/automations/base.py:117
#: assets/serializers/automations/base.py:39 #: assets/serializers/automations/base.py:39
msgid "Automation snapshot" msgid "Automation snapshot"
@ -743,12 +743,12 @@ msgstr "激活中"
#: terminal/notifications.py:96 terminal/notifications.py:144 #: terminal/notifications.py:96 terminal/notifications.py:144
#: terminal/serializers/command.py:16 tickets/models/comment.py:21 #: terminal/serializers/command.py:16 tickets/models/comment.py:21
#: users/const.py:14 users/models/user.py:911 users/models/user.py:942 #: users/const.py:14 users/models/user.py:911 users/models/user.py:942
#: users/serializers/group.py:19 #: users/serializers/group.py:18
msgid "User" msgid "User"
msgstr "用户" msgstr "用户"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60 #: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
#: ops/serializers/job.py:63 terminal/const.py:67 #: ops/serializers/job.py:65 terminal/const.py:67
#: terminal/models/session/session.py:43 terminal/serializers/command.py:18 #: terminal/models/session/session.py:43 terminal/serializers/command.py:18
#: terminal/templates/terminal/_msg_command_alert.html:12 #: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10 #: terminal/templates/terminal/_msg_command_execute_alert.html:10
@ -926,7 +926,7 @@ msgstr "删除失败,节点包含资产"
msgid "App assets" msgid "App assets"
msgstr "资产管理" msgstr "资产管理"
#: assets/automations/base/manager.py:107 #: assets/automations/base/manager.py:114
msgid "{} disabled" msgid "{} disabled"
msgstr "{} 已禁用" msgstr "{} 已禁用"
@ -980,7 +980,7 @@ msgstr "收集资产信息"
#: assets/const/category.py:11 assets/models/asset/host.py:8 #: assets/const/category.py:11 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67
#: terminal/models/component/endpoint.py:13 #: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17
#: xpack/plugins/cloud/serializers/account_attrs.py:72 #: xpack/plugins/cloud/serializers/account_attrs.py:72
msgid "Host" msgid "Host"
msgstr "主机" msgstr "主机"
@ -1057,20 +1057,20 @@ msgstr "SSH公钥"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40 #: assets/models/_user.py:27 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 assets/models/group.py:23 #: assets/models/cmd_filter.py:88 assets/models/group.py:23
#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:45 #: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:109
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38 #: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:155 #: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:158
#: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24 #: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100 #: terminal/models/component/endpoint.py:100
#: terminal/models/session/session.py:47 tickets/models/comment.py:32 #: terminal/models/session/session.py:47 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:756 #: tickets/models/ticket/general.py:297 users/models/user.py:756
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 #: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:119
msgid "Comment" msgid "Comment"
msgstr "备注" msgstr "备注"
#: assets/models/_user.py:28 assets/models/automations/base.py:113 #: assets/models/_user.py:28 assets/models/automations/base.py:113
#: assets/models/cmd_filter.py:41 assets/models/group.py:22 #: 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:121 #: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:185
#: users/models/user.py:943 #: users/models/user.py:943
msgid "Date created" msgid "Date created"
msgstr "创建日期" msgstr "创建日期"
@ -1083,7 +1083,7 @@ msgstr "更新日期"
#: assets/models/_user.py:30 assets/models/cmd_filter.py:44 #: assets/models/_user.py:30 assets/models/cmd_filter.py:44
#: assets/models/cmd_filter.py:91 assets/models/group.py:21 #: assets/models/cmd_filter.py:91 assets/models/group.py:21
#: common/db/models.py:33 users/models/user.py:763 #: common/db/models.py:33 users/models/user.py:763
#: users/serializers/group.py:33 #: users/serializers/group.py:31
msgid "Created by" msgid "Created by"
msgstr "创建者" msgstr "创建者"
@ -1175,7 +1175,7 @@ msgstr "地址"
#: assets/models/asset/common.py:104 assets/models/platform.py:112 #: assets/models/asset/common.py:104 assets/models/platform.py:112
#: authentication/serializers/connect_token_secret.py:108 #: authentication/serializers/connect_token_secret.py:108
#: perms/serializers/user_permission.py:23 #: perms/serializers/user_permission.py:23
#: xpack/plugins/cloud/serializers/account_attrs.py:187 #: xpack/plugins/cloud/serializers/account_attrs.py:179
msgid "Platform" msgid "Platform"
msgstr "系统平台" msgstr "系统平台"
@ -1246,7 +1246,7 @@ msgid "Submit selector"
msgstr "确认按钮选择器" msgstr "确认按钮选择器"
#: assets/models/automations/base.py:17 assets/models/cmd_filter.py:38 #: assets/models/automations/base.py:17 assets/models/cmd_filter.py:38
#: assets/serializers/asset/common.py:287 rbac/tree.py:36 #: assets/serializers/asset/common.py:289 rbac/tree.py:36
msgid "Accounts" msgid "Accounts"
msgstr "账号管理" msgstr "账号管理"
@ -1259,13 +1259,13 @@ msgid "Asset automation task"
msgstr "资产自动化任务" msgstr "资产自动化任务"
#: assets/models/automations/base.py:112 audits/models.py:177 #: assets/models/automations/base.py:112 audits/models.py:177
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:114 #: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:178
#: terminal/models/applet/applet.py:154 terminal/models/applet/host.py:108 #: terminal/models/applet/applet.py:157 terminal/models/applet/host.py:108
#: terminal/models/component/status.py:27 terminal/serializers/applet.py:17 #: terminal/models/component/status.py:27 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283 #: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13 #: tickets/serializers/super_ticket.py:13
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 #: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:172
#: xpack/plugins/cloud/models.py:216 #: xpack/plugins/cloud/models.py:224
msgid "Status" msgid "Status"
msgstr "状态" msgstr "状态"
@ -1484,7 +1484,8 @@ msgstr "自动代填"
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:99 #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:99
#: authentication/serializers/connect_token_secret.py:28 #: authentication/serializers/connect_token_secret.py:28
#: authentication/serializers/connect_token_secret.py:66 #: authentication/serializers/connect_token_secret.py:66
#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:99 #: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:107
#: xpack/plugins/cloud/serializers/task.py:38
msgid "Protocols" msgid "Protocols"
msgstr "协议组" msgstr "协议组"
@ -1504,15 +1505,13 @@ msgstr "端口超出范围 (1-65535)"
msgid "Protocol is required: {}" msgid "Protocol is required: {}"
msgstr "协议是必填的: {}" msgstr "协议是必填的: {}"
#: assets/serializers/asset/common.py:289 #: assets/serializers/asset/common.py:291
msgid "Auto info" msgid "Auto info"
msgstr "自动化信息" msgstr "自动化信息"
#: assets/serializers/asset/database.py:25 common/serializers/fields.py:100 #: assets/serializers/asset/database.py:25 common/serializers/fields.py:100
#: tickets/serializers/ticket/common.py:58 #: tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56 #: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
#: xpack/plugins/cloud/serializers/account_attrs.py:143
msgid "This field is required." msgid "This field is required."
msgstr "该字段是必填项。" msgstr "该字段是必填项。"
@ -1954,7 +1953,7 @@ msgstr "清理审计会话任务日志"
#: authentication/api/confirm.py:40 #: authentication/api/confirm.py:40
msgid "This action require verify your MFA" msgid "This action require verify your MFA"
msgstr "此操作需要验证您的 MFA" msgstr "该操作需要验证您的 MFA, 请先开启并配置"
#: authentication/api/connection_token.py:268 #: authentication/api/connection_token.py:268
msgid "Account not found" msgid "Account not found"
@ -2443,7 +2442,7 @@ msgstr "立刻过期"
#: authentication/serializers/connect_token_secret.py:148 #: authentication/serializers/connect_token_secret.py:148
#: authentication/templates/authentication/_access_key_modal.html:30 #: authentication/templates/authentication/_access_key_modal.html:30
#: perms/models/perm_node.py:21 users/serializers/group.py:35 #: perms/models/perm_node.py:21 users/serializers/group.py:33
msgid "ID" msgid "ID"
msgstr "ID" msgstr "ID"
@ -2465,7 +2464,7 @@ msgstr "动作"
#: authentication/serializers/connection_token.py:41 #: authentication/serializers/connection_token.py:41
#: perms/serializers/permission.py:31 perms/serializers/permission.py:61 #: perms/serializers/permission.py:31 perms/serializers/permission.py:61
#: users/serializers/user.py:93 users/serializers/user.py:162 #: users/serializers/user.py:93 users/serializers/user.py:164
msgid "Is expired" msgid "Is expired"
msgstr "已过期" msgstr "已过期"
@ -2485,7 +2484,8 @@ msgid "The {} cannot be empty"
msgstr "{} 不能为空" msgstr "{} 不能为空"
#: authentication/serializers/token.py:79 perms/serializers/permission.py:30 #: authentication/serializers/token.py:79 perms/serializers/permission.py:30
#: perms/serializers/permission.py:62 users/serializers/user.py:160 #: perms/serializers/permission.py:62 users/serializers/user.py:94
#: users/serializers/user.py:162
msgid "Is valid" msgid "Is valid"
msgstr "是否有效" msgstr "是否有效"
@ -3200,6 +3200,10 @@ msgstr "任务 {} 不存在"
msgid "Task {} args or kwargs error" msgid "Task {} args or kwargs error"
msgstr "任务 {} 执行参数错误" msgstr "任务 {} 执行参数错误"
#: ops/api/playbook.py:83
msgid "Unsupported file content"
msgstr "不支持的文件内容"
#: ops/apps.py:9 ops/notifications.py:16 rbac/tree.py:56 #: ops/apps.py:9 ops/notifications.py:16 rbac/tree.py:56
msgid "App ops" msgid "App ops"
msgstr "作业中心" msgstr "作业中心"
@ -3240,7 +3244,7 @@ msgstr "VCS"
msgid "Adhoc" msgid "Adhoc"
msgstr "命令" msgstr "命令"
#: ops/const.py:39 ops/models/job.py:35 #: ops/const.py:39 ops/models/job.py:99
msgid "Playbook" msgid "Playbook"
msgstr "Playbook" msgstr "Playbook"
@ -3301,17 +3305,17 @@ msgstr "需要周期或定期设置"
msgid "Pattern" msgid "Pattern"
msgstr "模式" msgstr "模式"
#: ops/models/adhoc.py:24 ops/models/job.py:30 #: ops/models/adhoc.py:24 ops/models/job.py:94
msgid "Module" msgid "Module"
msgstr "模块" msgstr "模块"
#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:29 #: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:93
#: terminal/models/component/task.py:16 #: terminal/models/component/task.py:16
msgid "Args" msgid "Args"
msgstr "参数" msgstr "参数"
#: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53 #: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53
#: ops/models/job.py:38 ops/models/job.py:120 ops/models/playbook.py:25 #: ops/models/job.py:102 ops/models/job.py:184 ops/models/playbook.py:25
#: terminal/models/session/sharing.py:23 #: terminal/models/session/sharing.py:23
msgid "Creator" msgid "Creator"
msgstr "创建者" msgstr "创建者"
@ -3328,12 +3332,12 @@ msgstr "最后执行"
msgid "Date last run" msgid "Date last run"
msgstr "最后运行日期" msgstr "最后运行日期"
#: ops/models/base.py:51 ops/models/job.py:118 #: ops/models/base.py:51 ops/models/job.py:182
#: xpack/plugins/cloud/models.py:162 #: xpack/plugins/cloud/models.py:170
msgid "Result" msgid "Result"
msgstr "结果" msgstr "结果"
#: ops/models/base.py:52 ops/models/job.py:119 #: ops/models/base.py:52 ops/models/job.py:183
msgid "Summary" msgid "Summary"
msgstr "汇总" msgstr "汇总"
@ -3373,47 +3377,47 @@ msgstr "发布日期"
msgid "Celery Task Execution" msgid "Celery Task Execution"
msgstr "Celery 任务执行" msgstr "Celery 任务执行"
#: ops/models/job.py:32 #: ops/models/job.py:96
msgid "Chdir" msgid "Chdir"
msgstr "运行目录" msgstr "运行目录"
#: ops/models/job.py:33 #: ops/models/job.py:97
msgid "Timeout (Seconds)" msgid "Timeout (Seconds)"
msgstr "超时时间(秒)" msgstr "超时时间(秒)"
#: ops/models/job.py:40 #: ops/models/job.py:104
msgid "Use Parameter Define" msgid "Use Parameter Define"
msgstr "使用参数定义" msgstr "使用参数定义"
#: ops/models/job.py:41 #: ops/models/job.py:105
msgid "Parameters define" msgid "Parameters define"
msgstr "参数定义" msgstr "参数定义"
#: ops/models/job.py:42 #: ops/models/job.py:106
msgid "Runas" msgid "Runas"
msgstr "运行用户" msgstr "运行用户"
#: ops/models/job.py:44 #: ops/models/job.py:108
msgid "Runas policy" msgid "Runas policy"
msgstr "用户策略" msgstr "用户策略"
#: ops/models/job.py:106 #: ops/models/job.py:170
msgid "Job" msgid "Job"
msgstr "作业" msgstr "作业"
#: ops/models/job.py:117 #: ops/models/job.py:181
msgid "Parameters" msgid "Parameters"
msgstr "参数" msgstr "参数"
#: ops/models/job.py:125 #: ops/models/job.py:189
msgid "Material" msgid "Material"
msgstr "" msgstr ""
#: ops/models/job.py:127 #: ops/models/job.py:191
msgid "Material Type" msgid "Material Type"
msgstr "" msgstr ""
#: ops/models/job.py:364 #: ops/models/job.py:442
msgid "Job Execution" msgid "Job Execution"
msgstr "作业执行" msgstr "作业执行"
@ -3457,15 +3461,15 @@ msgstr "CPU 使用率超过 {max_threshold}: => {value}"
msgid "Run after save" msgid "Run after save"
msgstr "保存后执行" msgstr "保存后执行"
#: ops/serializers/job.py:62 #: ops/serializers/job.py:64
msgid "Job type" msgid "Job type"
msgstr "任务类型" msgstr "任务类型"
#: ops/serializers/job.py:65 terminal/serializers/session.py:49 #: ops/serializers/job.py:67 terminal/serializers/session.py:49
msgid "Is finished" msgid "Is finished"
msgstr "是否完成" msgstr "是否完成"
#: ops/serializers/job.py:66 #: ops/serializers/job.py:68
msgid "Time cost" msgid "Time cost"
msgstr "花费时间" msgstr "花费时间"
@ -3690,7 +3694,7 @@ msgstr "内部角色,不能删除"
msgid "The role has been bound to users, can't be destroy" msgid "The role has been bound to users, can't be destroy"
msgstr "角色已绑定用户,不能删除" msgstr "角色已绑定用户,不能删除"
#: rbac/api/role.py:82 #: rbac/api/role.py:83
msgid "Internal role, can't be update" msgid "Internal role, can't be update"
msgstr "内部角色,不能更新" msgstr "内部角色,不能更新"
@ -3798,7 +3802,7 @@ msgstr "系统角色绑定"
msgid "Perms" msgid "Perms"
msgstr "权限" msgstr "权限"
#: rbac/serializers/role.py:27 users/serializers/group.py:34 #: rbac/serializers/role.py:27 users/serializers/group.py:32
msgid "Users amount" msgid "Users amount"
msgstr "用户数量" msgstr "用户数量"
@ -3867,7 +3871,8 @@ msgid "My assets"
msgstr "我的资产" msgstr "我的资产"
#: rbac/tree.py:57 terminal/models/applet/applet.py:43 #: rbac/tree.py:57 terminal/models/applet/applet.py:43
#: terminal/models/applet/applet.py:151 terminal/models/applet/host.py:28 #: terminal/models/applet/applet.py:154 terminal/models/applet/host.py:28
#: terminal/serializers/applet.py:15
msgid "Applet" msgid "Applet"
msgstr "远程应用" msgstr "远程应用"
@ -4364,7 +4369,7 @@ msgid "SSO auth key TTL"
msgstr "令牌有效期" msgstr "令牌有效期"
#: settings/serializers/auth/sso.py:17 #: settings/serializers/auth/sso.py:17
#: xpack/plugins/cloud/serializers/account_attrs.py:184 #: xpack/plugins/cloud/serializers/account_attrs.py:176
msgid "Unit: second" msgid "Unit: second"
msgstr "单位: 秒" msgstr "单位: 秒"
@ -5372,7 +5377,7 @@ msgstr "主机"
msgid "Applet pkg not valid, Missing file {}" msgid "Applet pkg not valid, Missing file {}"
msgstr "Applet pkg 无效,缺少文件 {}" msgstr "Applet pkg 无效,缺少文件 {}"
#: terminal/models/applet/applet.py:153 terminal/models/applet/host.py:34 #: terminal/models/applet/applet.py:156 terminal/models/applet/host.py:34
#: terminal/models/applet/host.py:106 #: terminal/models/applet/host.py:106
msgid "Hosting" msgid "Hosting"
msgstr "宿主机" msgstr "宿主机"
@ -5615,7 +5620,7 @@ msgstr "级别"
msgid "Batch danger command alert" msgid "Batch danger command alert"
msgstr "批量危险命令告警" msgstr "批量危险命令告警"
#: terminal/serializers/applet.py:27 #: terminal/serializers/applet.py:28
msgid "Icon" msgid "Icon"
msgstr "图标" msgstr "图标"
@ -5742,7 +5747,7 @@ msgstr "Access key ID(AK)"
msgid "Access key secret" msgid "Access key secret"
msgstr "Access key secret(SK)" msgstr "Access key secret(SK)"
#: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:209 #: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:217
msgid "Region" msgid "Region"
msgstr "地域" msgstr "地域"
@ -6170,7 +6175,7 @@ msgstr "无效的审批动作"
msgid "This user is not authorized to approve this ticket" msgid "This user is not authorized to approve this ticket"
msgstr "此用户无权审批此工单" msgstr "此用户无权审批此工单"
#: users/api/user.py:178 #: users/api/user.py:179
msgid "Could not reset self otp, use profile reset instead" msgid "Could not reset self otp, use profile reset instead"
msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置" msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置"
@ -6289,7 +6294,7 @@ msgstr "SSH公钥"
msgid "Force enable" msgid "Force enable"
msgstr "强制启用" msgstr "强制启用"
#: users/models/user.py:729 users/serializers/user.py:161 #: users/models/user.py:729 users/serializers/user.py:163
msgid "Is service account" msgid "Is service account"
msgstr "服务账号" msgstr "服务账号"
@ -6318,7 +6323,7 @@ msgid "Secret key"
msgstr "Secret key" msgstr "Secret key"
#: users/models/user.py:758 users/serializers/profile.py:147 #: users/models/user.py:758 users/serializers/profile.py:147
#: users/serializers/user.py:158 #: users/serializers/user.py:160
msgid "Is first login" msgid "Is first login"
msgstr "首次登录" msgstr "首次登录"
@ -6425,27 +6430,27 @@ msgstr "强制 MFA"
msgid "Login blocked" msgid "Login blocked"
msgstr "登录被阻塞" msgstr "登录被阻塞"
#: users/serializers/user.py:95 #: users/serializers/user.py:95 users/serializers/user.py:168
msgid "Can public key authentication"
msgstr "公钥认证"
#: users/serializers/user.py:163
msgid "Avatar url"
msgstr "头像路径"
#: users/serializers/user.py:166
msgid "Is OTP bound" msgid "Is OTP bound"
msgstr "是否绑定了虚拟 MFA" msgstr "是否绑定了虚拟 MFA"
#: users/serializers/user.py:273 #: users/serializers/user.py:97
msgid "Can public key authentication"
msgstr "公钥认证"
#: users/serializers/user.py:165
msgid "Avatar url"
msgstr "头像路径"
#: users/serializers/user.py:275
msgid "Select users" msgid "Select users"
msgstr "选择用户" msgstr "选择用户"
#: users/serializers/user.py:274 #: users/serializers/user.py:276
msgid "For security, only list several users" msgid "For security, only list several users"
msgstr "为了安全,仅列出几个用户" msgstr "为了安全,仅列出几个用户"
#: users/serializers/user.py:307 #: users/serializers/user.py:309
msgid "name not unique" msgid "name not unique"
msgstr "名称重复" msgstr "名称重复"
@ -6855,47 +6860,55 @@ msgstr "地域"
msgid "Hostname strategy" msgid "Hostname strategy"
msgstr "主机名策略" msgstr "主机名策略"
#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:40 #: xpack/plugins/cloud/models.py:100
msgid "Unix admin user"
msgstr "Unix 管理员"
#: xpack/plugins/cloud/models.py:104
msgid "Windows admin user"
msgstr "Windows 管理员"
#: xpack/plugins/cloud/models.py:110 xpack/plugins/cloud/serializers/task.py:41
msgid "IP network segment group" msgid "IP network segment group"
msgstr "IP网段组" msgstr "IP网段组"
#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:45 #: xpack/plugins/cloud/models.py:113 xpack/plugins/cloud/serializers/task.py:46
msgid "Sync IP type" msgid "Sync IP type"
msgstr "同步IP类型" msgstr "同步IP类型"
#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:62 #: xpack/plugins/cloud/models.py:116 xpack/plugins/cloud/serializers/task.py:64
msgid "Always update" msgid "Always update"
msgstr "总是更新" msgstr "总是更新"
#: xpack/plugins/cloud/models.py:114 #: xpack/plugins/cloud/models.py:122
msgid "Date last sync" msgid "Date last sync"
msgstr "最后同步日期" msgstr "最后同步日期"
#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 #: xpack/plugins/cloud/models.py:127 xpack/plugins/cloud/models.py:168
msgid "Sync instance task" msgid "Sync instance task"
msgstr "同步实例任务" msgstr "同步实例任务"
#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 #: xpack/plugins/cloud/models.py:179 xpack/plugins/cloud/models.py:227
msgid "Date sync" msgid "Date sync"
msgstr "同步日期" msgstr "同步日期"
#: xpack/plugins/cloud/models.py:175 #: xpack/plugins/cloud/models.py:183
msgid "Sync instance task execution" msgid "Sync instance task execution"
msgstr "同步实例任务执行" msgstr "同步实例任务执行"
#: xpack/plugins/cloud/models.py:199 #: xpack/plugins/cloud/models.py:207
msgid "Sync task" msgid "Sync task"
msgstr "同步任务" msgstr "同步任务"
#: xpack/plugins/cloud/models.py:203 #: xpack/plugins/cloud/models.py:211
msgid "Sync instance task history" msgid "Sync instance task history"
msgstr "同步实例任务历史" msgstr "同步实例任务历史"
#: xpack/plugins/cloud/models.py:206 #: xpack/plugins/cloud/models.py:214
msgid "Instance" msgid "Instance"
msgstr "实例" msgstr "实例"
#: xpack/plugins/cloud/models.py:223 #: xpack/plugins/cloud/models.py:231
msgid "Sync instance detail" msgid "Sync instance detail"
msgstr "同步实例详情" msgstr "同步实例详情"
@ -7109,52 +7122,52 @@ msgstr "租户 ID"
msgid "Subscription ID" msgid "Subscription ID"
msgstr "订阅 ID" msgstr "订阅 ID"
#: xpack/plugins/cloud/serializers/account_attrs.py:98 #: xpack/plugins/cloud/serializers/account_attrs.py:95
#: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:100
#: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:116
#: xpack/plugins/cloud/serializers/account_attrs.py:149 #: xpack/plugins/cloud/serializers/account_attrs.py:141
msgid "API Endpoint" msgid "API Endpoint"
msgstr "API 端点" msgstr "API 端点"
#: xpack/plugins/cloud/serializers/account_attrs.py:109 #: xpack/plugins/cloud/serializers/account_attrs.py:106
msgid "Auth url" msgid "Auth url"
msgstr "认证地址" msgstr "认证地址"
#: xpack/plugins/cloud/serializers/account_attrs.py:110 #: xpack/plugins/cloud/serializers/account_attrs.py:107
msgid "eg: http://openstack.example.com:5000/v3" msgid "eg: http://openstack.example.com:5000/v3"
msgstr "如: http://openstack.example.com:5000/v3" msgstr "如: http://openstack.example.com:5000/v3"
#: xpack/plugins/cloud/serializers/account_attrs.py:113 #: xpack/plugins/cloud/serializers/account_attrs.py:110
msgid "User domain" msgid "User domain"
msgstr "用户域" msgstr "用户域"
#: xpack/plugins/cloud/serializers/account_attrs.py:120 #: xpack/plugins/cloud/serializers/account_attrs.py:117
msgid "Cert File" msgid "Cert File"
msgstr "证书文件" msgstr "证书文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:121 #: xpack/plugins/cloud/serializers/account_attrs.py:118
msgid "Key File" msgid "Key File"
msgstr "密钥文件" msgstr "密钥文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:137 #: xpack/plugins/cloud/serializers/account_attrs.py:134
msgid "Service account key" msgid "Service account key"
msgstr "服务账号密钥" msgstr "服务账号密钥"
#: xpack/plugins/cloud/serializers/account_attrs.py:138 #: xpack/plugins/cloud/serializers/account_attrs.py:135
msgid "The file is in JSON format" msgid "The file is in JSON format"
msgstr "JSON 格式的文件" msgstr "JSON 格式的文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:156 #: xpack/plugins/cloud/serializers/account_attrs.py:148
msgid "IP address invalid `{}`, {}" msgid "IP address invalid `{}`, {}"
msgstr "IP 地址无效: `{}`, {}" msgstr "IP 地址无效: `{}`, {}"
#: xpack/plugins/cloud/serializers/account_attrs.py:162 #: xpack/plugins/cloud/serializers/account_attrs.py:154
msgid "" msgid ""
"Format for comma-delimited string,Such as: 192.168.1.0/24, " "Format for comma-delimited string,Such as: 192.168.1.0/24, "
"10.0.0.0-10.0.0.255" "10.0.0.0-10.0.0.255"
msgstr "格式为逗号分隔的字符串192.168.1.0/24,10.0.0.0-10.0.0.255" msgstr "格式为逗号分隔的字符串192.168.1.0/24,10.0.0.0-10.0.0.255"
#: xpack/plugins/cloud/serializers/account_attrs.py:166 #: xpack/plugins/cloud/serializers/account_attrs.py:158
msgid "" msgid ""
"The port is used to detect the validity of the IP address. When the " "The port is used to detect the validity of the IP address. When the "
"synchronization task is executed, only the valid IP address will be " "synchronization task is executed, only the valid IP address will be "
@ -7163,19 +7176,19 @@ msgstr ""
"端口用来检测 IP 地址的有效性,在同步任务执行时,只会同步有效的 IP 地址。 <br>" "端口用来检测 IP 地址的有效性,在同步任务执行时,只会同步有效的 IP 地址。 <br>"
"如果端口为 0则表示所有 IP 地址均有效。" "如果端口为 0则表示所有 IP 地址均有效。"
#: xpack/plugins/cloud/serializers/account_attrs.py:174 #: xpack/plugins/cloud/serializers/account_attrs.py:166
msgid "Hostname prefix" msgid "Hostname prefix"
msgstr "主机名前缀" msgstr "主机名前缀"
#: xpack/plugins/cloud/serializers/account_attrs.py:177 #: xpack/plugins/cloud/serializers/account_attrs.py:169
msgid "IP segment" msgid "IP segment"
msgstr "IP 网段" msgstr "IP 网段"
#: xpack/plugins/cloud/serializers/account_attrs.py:181 #: xpack/plugins/cloud/serializers/account_attrs.py:173
msgid "Test port" msgid "Test port"
msgstr "测试端口" msgstr "测试端口"
#: xpack/plugins/cloud/serializers/account_attrs.py:184 #: xpack/plugins/cloud/serializers/account_attrs.py:176
msgid "Test timeout" msgid "Test timeout"
msgstr "测试超时时间" msgstr "测试超时时间"
@ -7199,13 +7212,9 @@ msgstr "执行次数"
msgid "Instance count" msgid "Instance count"
msgstr "实例个数" msgstr "实例个数"
#: xpack/plugins/cloud/tasks.py:27 #: xpack/plugins/cloud/serializers/task.py:63
msgid "Run sync instance task" msgid "Linux admin user"
msgstr "执行同步实例任务" msgstr "Linux 管理员"
#: xpack/plugins/cloud/tasks.py:41
msgid "Period clean sync instance task execution"
msgstr "定期清除同步实例任务执行记录"
#: xpack/plugins/cloud/utils.py:69 #: xpack/plugins/cloud/utils.py:69
msgid "Account unavailable" msgid "Account unavailable"
@ -7275,6 +7284,12 @@ msgstr "旗舰版"
msgid "Community edition" msgid "Community edition"
msgstr "社区版" msgstr "社区版"
#~ msgid "Run sync instance task"
#~ msgstr "执行同步实例任务"
#~ msgid "Period clean sync instance task execution"
#~ msgstr "定期清除同步实例任务执行记录"
#~ msgid "Can push account to asset" #~ msgid "Can push account to asset"
#~ msgstr "可以推送账号到资产" #~ msgstr "可以推送账号到资产"
@ -7319,15 +7334,6 @@ msgstr "社区版"
#~ msgid "Periodic clean expired session" #~ msgid "Periodic clean expired session"
#~ msgstr "周期清理过期会话" #~ msgstr "周期清理过期会话"
#~ msgid "Unix admin user"
#~ msgstr "Unix 管理员"
#~ msgid "Windows admin user"
#~ msgstr "Windows 管理员"
#~ msgid "Linux admin user"
#~ msgstr "Linux 管理员"
#~ msgid "AdHoc" #~ msgid "AdHoc"
#~ msgstr "任务各版本" #~ msgstr "任务各版本"

View File

@ -139,8 +139,11 @@ class JMSInventory:
self.make_ssh_account_vars(host, asset, account, automation, protocols, platform, gateway) self.make_ssh_account_vars(host, asset, account, automation, protocols, platform, gateway)
return host return host
def get_asset_accounts(self, asset):
return list(asset.accounts.filter(is_active=True))
def select_account(self, asset): def select_account(self, asset):
accounts = list(asset.accounts.filter(is_active=True)) accounts = self.get_asset_accounts(asset)
if not accounts: if not accounts:
return None return None
account_selected = None account_selected = None

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from orgs.mixins.api import OrgBulkModelViewSet from orgs.mixins.api import OrgBulkModelViewSet
from rbac.permissions import RBACPermission
from ..models import AdHoc from ..models import AdHoc
from ..serializers import ( from ..serializers import (
AdHocSerializer AdHocSerializer
@ -12,7 +13,7 @@ __all__ = [
class AdHocViewSet(OrgBulkModelViewSet): class AdHocViewSet(OrgBulkModelViewSet):
serializer_class = AdHocSerializer serializer_class = AdHocSerializer
permission_classes = () permission_classes = (RBACPermission,)
search_fields = ('name', 'comment') search_fields = ('name', 'comment')
model = AdHoc model = AdHoc

View File

@ -17,6 +17,7 @@ from ops.variables import JMS_JOB_VARIABLE_HELP
from orgs.mixins.api import OrgBulkModelViewSet from orgs.mixins.api import OrgBulkModelViewSet
from orgs.utils import tmp_to_org, get_current_org from orgs.utils import tmp_to_org, get_current_org
from accounts.models import Account from accounts.models import Account
from rbac.permissions import RBACPermission
def set_task_to_serializer_data(serializer, task): def set_task_to_serializer_data(serializer, task):
@ -27,7 +28,7 @@ def set_task_to_serializer_data(serializer, task):
class JobViewSet(OrgBulkModelViewSet): class JobViewSet(OrgBulkModelViewSet):
serializer_class = JobSerializer serializer_class = JobSerializer
permission_classes = () permission_classes = (RBACPermission,)
search_fields = ('name', 'comment') search_fields = ('name', 'comment')
model = Job model = Job
@ -69,7 +70,7 @@ class JobViewSet(OrgBulkModelViewSet):
class JobExecutionViewSet(OrgBulkModelViewSet): class JobExecutionViewSet(OrgBulkModelViewSet):
serializer_class = JobExecutionSerializer serializer_class = JobExecutionSerializer
http_method_names = ('get', 'post', 'head', 'options',) http_method_names = ('get', 'post', 'head', 'options',)
permission_classes = () permission_classes = (RBACPermission,)
model = JobExecution model = JobExecution
search_fields = ('material',) search_fields = ('material',)

View File

@ -8,9 +8,11 @@ from rest_framework import status
from common.exceptions import JMSException from common.exceptions import JMSException
from orgs.mixins.api import OrgBulkModelViewSet from orgs.mixins.api import OrgBulkModelViewSet
from rbac.permissions import RBACPermission
from ..exception import PlaybookNoValidEntry from ..exception import PlaybookNoValidEntry
from ..models import Playbook from ..models import Playbook
from ..serializers.playbook import PlaybookSerializer from ..serializers.playbook import PlaybookSerializer
from django.utils.translation import ugettext_lazy as _
__all__ = ["PlaybookViewSet", "PlaybookFileBrowserAPIView"] __all__ = ["PlaybookViewSet", "PlaybookFileBrowserAPIView"]
@ -26,7 +28,7 @@ def unzip_playbook(src, dist):
class PlaybookViewSet(OrgBulkModelViewSet): class PlaybookViewSet(OrgBulkModelViewSet):
serializer_class = PlaybookSerializer serializer_class = PlaybookSerializer
permission_classes = () permission_classes = (RBACPermission,)
model = Playbook model = Playbook
search_fields = ('name', 'comment') search_fields = ('name', 'comment')
@ -58,8 +60,13 @@ class PlaybookViewSet(OrgBulkModelViewSet):
class PlaybookFileBrowserAPIView(APIView): class PlaybookFileBrowserAPIView(APIView):
rbac_perms = () rbac_perms = ()
permission_classes = () permission_classes = (RBACPermission,)
rbac_perms = {
'GET': 'ops.change_playbooks',
'POST': 'ops.change_playbooks',
'DELETE': 'ops.change_playbooks',
'PATCH': 'ops.change_playbooks',
}
protected_files = ['root', 'main.yml'] protected_files = ['root', 'main.yml']
def get(self, request, **kwargs): def get(self, request, **kwargs):
@ -70,7 +77,10 @@ class PlaybookFileBrowserAPIView(APIView):
if file_key: if file_key:
file_path = os.path.join(work_path, file_key) file_path = os.path.join(work_path, file_key)
with open(file_path, 'r') as f: with open(file_path, 'r') as f:
content = f.read() try:
content = f.read()
except UnicodeDecodeError:
content = _('Unsupported file content')
return Response({'content': content}) return Response({'content': content})
else: else:
expand_key = request.query_params.get('expand', '') expand_key = request.query_params.get('expand', '')
@ -153,6 +163,8 @@ class PlaybookFileBrowserAPIView(APIView):
# rename # rename
if new_name: if new_name:
new_file_path = os.path.join(os.path.dirname(file_path), new_name) new_file_path = os.path.join(os.path.dirname(file_path), new_name)
if new_file_path == file_path:
return Response(status=status.HTTP_200_OK)
if os.path.exists(new_file_path): if os.path.exists(new_file_path):
return Response({'msg': '{} already exists'.format(new_name)}, status=status.HTTP_400_BAD_REQUEST) return Response({'msg': '{} already exists'.format(new_name)}, status=status.HTTP_400_BAD_REQUEST)
os.rename(file_path, new_file_path) os.rename(file_path, new_file_path)
@ -161,7 +173,7 @@ class PlaybookFileBrowserAPIView(APIView):
if not is_directory: if not is_directory:
with open(file_path, 'w') as f: with open(file_path, 'w') as f:
f.write(content) f.write(content)
return Response({'msg': 'ok'}) return Response(status=status.HTTP_200_OK)
def delete(self, request, **kwargs): def delete(self, request, **kwargs):
playbook_id = kwargs.get('pk') playbook_id = kwargs.get('pk')

View File

@ -2,26 +2,90 @@ import json
import logging import logging
import os import os
import uuid import uuid
from collections import defaultdict
from celery import current_task from celery import current_task
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.db.models import Q
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
__all__ = ["Job", "JobExecution"] __all__ = ["Job", "JobExecution", "JMSPermedInventory"]
from simple_history.models import HistoricalRecords from simple_history.models import HistoricalRecords
from accounts.models import Account
from acls.models import CommandFilterACL from acls.models import CommandFilterACL
from assets.models import Asset
from ops.ansible import JMSInventory, AdHocRunner, PlaybookRunner from ops.ansible import JMSInventory, AdHocRunner, PlaybookRunner
from ops.mixin import PeriodTaskModelMixin from ops.mixin import PeriodTaskModelMixin
from ops.variables import * from ops.variables import *
from ops.const import Types, Modules, RunasPolicies, JobStatus from ops.const import Types, Modules, RunasPolicies, JobStatus
from orgs.mixins.models import JMSOrgBaseModel from orgs.mixins.models import JMSOrgBaseModel
from perms.models import AssetPermission
from perms.utils import UserPermAssetUtil
from terminal.notifications import CommandExecutionAlert from terminal.notifications import CommandExecutionAlert
def get_parent_keys(key, include_self=True):
keys = []
split_keys = key.split(':')
for i in range(len(split_keys)):
keys.append(':'.join(split_keys[:i + 1]))
if not include_self:
keys.pop()
return keys
class JMSPermedInventory(JMSInventory):
def __init__(self, assets, account_policy='privileged_first',
account_prefer='root,Administrator', host_callback=None, exclude_localhost=False, user=None):
super().__init__(assets, account_policy, account_prefer, host_callback, exclude_localhost)
self.user = user
self.assets_accounts_mapper = self.get_assets_accounts_mapper()
def get_asset_accounts(self, asset):
return self.assets_accounts_mapper.get(asset.id, [])
def get_assets_accounts_mapper(self):
mapper = defaultdict(set)
asset_ids = self.assets.values_list('id', flat=True)
asset_node_keys = Asset.nodes.through.objects \
.filter(asset_id__in=asset_ids) \
.values_list('asset_id', 'node__key')
node_asset_map = defaultdict(set)
for asset_id, node_key in asset_node_keys:
all_keys = get_parent_keys(node_key)
for key in all_keys:
node_asset_map[key].add(asset_id)
groups = self.user.groups.all()
perms = AssetPermission.objects \
.filter(date_expired__gte=timezone.now()) \
.filter(is_active=True) \
.filter(Q(users=self.user) | Q(user_groups__in=groups)) \
.filter(Q(assets__in=asset_ids) | Q(nodes__key__in=node_asset_map.keys())) \
.values_list('assets', 'nodes__key', 'accounts')
asset_permed_accounts_mapper = defaultdict(set)
for asset_id, node_key, accounts in perms:
if asset_id in asset_ids:
asset_permed_accounts_mapper[asset_id].update(accounts)
for my_asset in node_asset_map[node_key]:
asset_permed_accounts_mapper[my_asset].update(accounts)
accounts = Account.objects.filter(asset__in=asset_ids)
for account in accounts:
if account.asset_id not in asset_permed_accounts_mapper:
continue
permed_usernames = asset_permed_accounts_mapper[account.asset_id]
if "@ALL" in permed_usernames or account.username in permed_usernames:
mapper[account.asset_id].add(account)
return mapper
class Job(JMSOrgBaseModel, PeriodTaskModelMixin): class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
name = models.CharField(max_length=128, null=True, verbose_name=_('Name')) name = models.CharField(max_length=128, null=True, verbose_name=_('Name'))
@ -54,7 +118,7 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
@property @property
def last_execution(self): def last_execution(self):
return self.executions.last() return self.executions.first()
@property @property
def date_last_run(self): def date_last_run(self):
@ -90,7 +154,7 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
@property @property
def inventory(self): def inventory(self):
return JMSInventory(self.assets.all(), self.runas_policy, self.runas) return JMSPermedInventory(self.assets.all(), self.runas_policy, self.runas, user=self.creator)
@property @property
def material(self): def material(self):
@ -339,7 +403,21 @@ class JobExecution(JMSOrgBaseModel):
'dangerous keyword \'{}\'\033[0m'.format(line['line'], line['file'], line['keyword'])) 'dangerous keyword \'{}\'\033[0m'.format(line['line'], line['file'], line['keyword']))
raise Exception("Playbook contains dangerous keywords") raise Exception("Playbook contains dangerous keywords")
def check_assets_perms(self):
all_permed_assets = UserPermAssetUtil(self.creator).get_all_assets()
has_permed_assets = set(self.current_job.assets.all()) & set(all_permed_assets)
error_assets_count = 0
for asset in self.current_job.assets.all():
if asset not in has_permed_assets:
print("\033[31mAsset {}({}) has no access permission\033[0m".format(asset.name, asset.address))
error_assets_count += 1
if error_assets_count > 0:
raise Exception("You do not have access rights to {} assets".format(error_assets_count))
def before_start(self): def before_start(self):
self.check_assets_perms()
if self.current_job.type == 'playbook': if self.current_job.type == 'playbook':
self.check_danger_keywords() self.check_danger_keywords()
if self.current_job.type == 'adhoc': if self.current_job.type == 'adhoc':

View File

@ -3,7 +3,7 @@ import uuid
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
from assets.models import Node from assets.models import Node, Asset
from perms.utils.user_perm import UserPermAssetUtil from perms.utils.user_perm import UserPermAssetUtil
from common.serializers.fields import ReadableHiddenField from common.serializers.fields import ReadableHiddenField
from ops.mixin import PeriodTaskSerializerMixin from ops.mixin import PeriodTaskSerializerMixin
@ -17,6 +17,8 @@ class JobSerializer(BulkOrgResourceModelSerializer, PeriodTaskSerializerMixin):
nodes = serializers.ListField(required=False, child=serializers.CharField()) nodes = serializers.ListField(required=False, child=serializers.CharField())
date_last_run = serializers.DateTimeField(label=_('Date last run'), read_only=True) date_last_run = serializers.DateTimeField(label=_('Date last run'), read_only=True)
name = serializers.CharField(label=_('Name'), max_length=128, allow_blank=True, required=False) name = serializers.CharField(label=_('Name'), max_length=128, allow_blank=True, required=False)
assets = serializers.PrimaryKeyRelatedField(label=_('Assets'), queryset=Asset.objects, many=True,
required=False)
def to_internal_value(self, data): def to_internal_value(self, data):
instant = data.get('instant', False) instant = data.get('instant', False)

View File

@ -59,7 +59,7 @@ def expire_user_orgs(*args):
@receiver(post_save, sender=Organization) @receiver(post_save, sender=Organization)
def on_org_create(sender, instance, created=False, **kwargs): def on_org_create(sender, instance, created=False, **kwargs):
if created: if not created:
return return
expire_user_orgs() expire_user_orgs()

View File

@ -3,23 +3,22 @@ from urllib.parse import parse_qsl
from django.conf import settings from django.conf import settings
from django.db.models import F, Value, CharField from django.db.models import F, Value, CharField
from rest_framework.request import Request from rest_framework.exceptions import PermissionDenied, NotFound
from rest_framework.response import Response
from rest_framework.generics import ListAPIView from rest_framework.generics import ListAPIView
from rest_framework.generics import get_object_or_404 from rest_framework.generics import get_object_or_404
from rest_framework.exceptions import PermissionDenied, NotFound from rest_framework.request import Request
from rest_framework.response import Response
from assets.utils import KubernetesTree
from assets.models import Asset
from accounts.const import AliasAccount from accounts.const import AliasAccount
from assets.api import SerializeToTreeNodeMixin from assets.api import SerializeToTreeNodeMixin
from accounts.models import Account from assets.models import Asset
from assets.utils import KubernetesTree
from authentication.models import ConnectionToken from authentication.models import ConnectionToken
from common.utils import get_object_or_none, lazyproperty from common.utils import get_object_or_none, lazyproperty
from common.utils.common import timeit from common.utils.common import timeit
from perms.hands import Node from perms.hands import Node
from perms.models import PermNode from perms.models import PermNode
from perms.utils import PermAccountUtil, UserPermNodeUtil, AssetPermissionUtil from perms.utils import PermAccountUtil, UserPermNodeUtil
from perms.utils import UserPermAssetUtil from perms.utils import UserPermAssetUtil
from .mixin import RebuildTreeMixin from .mixin import RebuildTreeMixin
from ..mixin import SelfOrPKUserMixin from ..mixin import SelfOrPKUserMixin
@ -153,16 +152,16 @@ class UserGrantedK8sAsTreeApi(SelfOrPKUserMixin, ListAPIView):
util = PermAccountUtil() util = PermAccountUtil()
accounts = util.get_permed_accounts_for_user(self.user, token.asset) accounts = util.get_permed_accounts_for_user(self.user, token.asset)
account_name = token.account account_name = token.account
accounts = filter(lambda x: x.name == account_name, accounts) if account_name in [
accounts = list(accounts)
if not accounts:
raise NotFound('Account is not found')
account = accounts[0]
if account.name in [
AliasAccount.INPUT, AliasAccount.USER AliasAccount.INPUT, AliasAccount.USER
]: ]:
return token.input_secret return token.input_secret
else: else:
accounts = filter(lambda x: x.name == account_name, accounts)
accounts = list(accounts)
if not accounts:
raise NotFound('Account is not found')
account = accounts[0]
return account.secret return account.secret
@staticmethod @staticmethod

View File

@ -95,6 +95,7 @@ class AssetPermissionFilter(PermissionBaseFilter):
node_name = filters.CharFilter(method='do_nothing') node_name = filters.CharFilter(method='do_nothing')
asset_id = filters.UUIDFilter(method='do_nothing') asset_id = filters.UUIDFilter(method='do_nothing')
asset_name = filters.CharFilter(method='do_nothing') asset_name = filters.CharFilter(method='do_nothing')
address = filters.CharFilter(method='do_nothing')
accounts = filters.CharFilter(method='do_nothing') accounts = filters.CharFilter(method='do_nothing')
ip = filters.CharFilter(method='do_nothing') ip = filters.CharFilter(method='do_nothing')
@ -153,14 +154,14 @@ class AssetPermissionFilter(PermissionBaseFilter):
is_query_all = self.get_query_param('all', True) is_query_all = self.get_query_param('all', True)
asset_id = self.get_query_param('asset_id') asset_id = self.get_query_param('asset_id')
asset_name = self.get_query_param('asset_name') asset_name = self.get_query_param('asset_name')
ip = self.get_query_param('address') address = self.get_query_param('address')
if asset_id: if asset_id:
assets = Asset.objects.filter(pk=asset_id) assets = Asset.objects.filter(pk=asset_id)
elif asset_name: elif asset_name:
assets = Asset.objects.filter(name=asset_name) assets = Asset.objects.filter(name=asset_name)
elif ip: elif address:
assets = Asset.objects.filter(ip=ip) assets = Asset.objects.filter(address=address)
else: else:
return queryset return queryset
if not assets: if not assets:

View File

@ -59,6 +59,8 @@ class RoleViewSet(JMSModelViewSet):
@staticmethod @staticmethod
def set_users_amount(queryset): def set_users_amount(queryset):
"""设置角色的用户绑定数量,以减少查询""" """设置角色的用户绑定数量,以减少查询"""
ids = [role.id for role in queryset]
queryset = Role.objects.filter(id__in=ids)
org_id = current_org.id org_id = current_org.id
q = Q(role__scope=Role.Scope.system) | Q(role__scope=Role.Scope.org, org_id=org_id) q = Q(role__scope=Role.Scope.system) | Q(role__scope=Role.Scope.org, org_id=org_id)
role_bindings = RoleBinding.objects.filter(q).values_list('role_id').annotate(user_count=Count('user_id')) role_bindings = RoleBinding.objects.filter(q).values_list('role_id').annotate(user_count=Count('user_id'))
@ -69,12 +71,11 @@ class RoleViewSet(JMSModelViewSet):
role.users_amount = role_user_amount_mapper.get(role.id, 0) role.users_amount = role_user_amount_mapper.get(role.id, 0)
return queryset return queryset
def paginate_queryset(self, queryset): def get_serializer(self, *args, **kwargs):
page_queryset = super().paginate_queryset(queryset) # 返回是 list 对象 if len(args) == 1:
page_queryset_ids = [str(i.id) for i in page_queryset] queryset = self.set_users_amount(args[0])
queryset = queryset.filter(id__in=page_queryset_ids) args = (queryset,)
queryset = self.set_users_amount(queryset) return super().get_serializer(*args, **kwargs)
return queryset
def perform_update(self, serializer): def perform_update(self, serializer):
instance = serializer.instance instance = serializer.instance

View File

@ -12,8 +12,9 @@ __all__ = [
class AppletPublicationSerializer(serializers.ModelSerializer): class AppletPublicationSerializer(serializers.ModelSerializer):
applet = ObjectRelatedField(attrs=('id', 'name', 'display_name', 'icon', 'version'), queryset=Applet.objects.all()) applet = ObjectRelatedField(attrs=('id', 'name', 'display_name', 'icon', 'version'), label=_("Applet"),
host = ObjectRelatedField(queryset=AppletHost.objects.all()) queryset=Applet.objects.all())
host = ObjectRelatedField(queryset=AppletHost.objects.all(), label=_("Host"))
status = LabeledChoiceField(choices=PublishStatus.choices, label=_("Status"), default=Status.pending) status = LabeledChoiceField(choices=PublishStatus.choices, label=_("Status"), default=Status.pending)
class Meta: class Meta:

View File

@ -51,10 +51,11 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, SuggestionMixin, BulkModelV
queryset = super().get_queryset().prefetch_related('groups') queryset = super().get_queryset().prefetch_related('groups')
return queryset return queryset
def paginate_queryset(self, queryset): def get_serializer(self, *args, **kwargs):
page = super().paginate_queryset(queryset) if len(args) == 0:
self.set_users_roles_for_cache(page or queryset) queryset = self.set_users_roles_for_cache(args[0])
return page args = (queryset,)
return super().get_serializer(*args, **kwargs)
@action(methods=['get'], detail=False, url_path='suggestions') @action(methods=['get'], detail=False, url_path='suggestions')
def match(self, request, *args, **kwargs): def match(self, request, *args, **kwargs):

View File

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from django.utils.translation import ugettext_lazy as _
from django.db.models import Prefetch
from rest_framework import serializers
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from django.db.models import Count from django.db.models import Count
from ..models import User, UserGroup from django.utils.translation import ugettext_lazy as _
from common.serializers.mixin import ObjectRelatedField
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .. import utils from .. import utils
from ..models import User, UserGroup
__all__ = [ __all__ = [
'UserGroupSerializer', 'UserGroupSerializer',
@ -15,9 +14,8 @@ __all__ = [
class UserGroupSerializer(BulkOrgResourceModelSerializer): class UserGroupSerializer(BulkOrgResourceModelSerializer):
users = serializers.PrimaryKeyRelatedField( users = ObjectRelatedField(
required=False, many=True, queryset=User.objects, label=_('User'), required=False, many=True, queryset=User.objects, label=_('User'),
# write_only=True, # group can return many to many on detail
) )
class Meta: class Meta:

View File

@ -39,7 +39,7 @@ class RolesSerializerMixin(serializers.Serializer):
label=_("System roles"), many=True, default=default_system_roles label=_("System roles"), many=True, default=default_system_roles
) )
org_roles = ObjectRelatedField( org_roles = ObjectRelatedField(
queryset=Role.org_roles, attrs=('id', 'display_name'), queryset=Role.org_roles, attrs=('id', 'display_name', 'name'),
label=_("Org roles"), many=True, required=False, label=_("Org roles"), many=True, required=False,
default=default_org_roles default=default_org_roles
) )
@ -91,6 +91,8 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer
) )
login_blocked = serializers.BooleanField(read_only=True, label=_("Login blocked")) login_blocked = serializers.BooleanField(read_only=True, label=_("Login blocked"))
is_expired = serializers.BooleanField(read_only=True, label=_("Is expired")) is_expired = serializers.BooleanField(read_only=True, label=_("Is expired"))
is_valid = serializers.BooleanField(read_only=True, label=_("Is valid"))
is_otp_secret_key_bound = serializers.BooleanField(read_only=True, label=_("Is OTP bound"))
can_public_key_auth = serializers.BooleanField( can_public_key_auth = serializers.BooleanField(
source="can_use_ssh_key_login", label=_("Can public key authentication"), source="can_use_ssh_key_login", label=_("Can public key authentication"),
read_only=True read_only=True