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',
}
def get_object(self):
return get_object_or_404(Account, pk=self.kwargs.get('pk'))
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):
data = serializer.validated_data
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':
task = push_accounts_to_assets_task.delay(account_ids)

View File

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

View File

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

View File

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

View File

@ -38,7 +38,7 @@ class BaseAutomationSerializer(PeriodTaskSerializerMixin, BulkOrgResourceModelSe
}
def validate_name(self, name):
if self.instance:
if self.instance and self.instance.name == name:
return name
if BaseAutomation.objects.filter(name=name, type=self.model_type).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 .models import Account
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:
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":
task = push_accounts_to_assets_task.delay(account_ids)
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.serializers import GroupedChoiceSerializer
from assets.models import Platform
from assets.const import AllTypes
from assets.serializers import PlatformSerializer
__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):
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)
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):
task_name = gettext_noop("Test if the assets under the node are connectable ")
asset_ids = node.get_all_asset_ids()
asset_ids = [str(i) for i in asset_ids]
org_id = str(current_org.id)
return test_assets_connectivity_task.delay(asset_ids, org_id, task_name)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,26 +2,90 @@ import json
import logging
import os
import uuid
from collections import defaultdict
from celery import current_task
from django.conf import settings
from django.db import models
from django.db.models import Q
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
__all__ = ["Job", "JobExecution"]
__all__ = ["Job", "JobExecution", "JMSPermedInventory"]
from simple_history.models import HistoricalRecords
from accounts.models import Account
from acls.models import CommandFilterACL
from assets.models import Asset
from ops.ansible import JMSInventory, AdHocRunner, PlaybookRunner
from ops.mixin import PeriodTaskModelMixin
from ops.variables import *
from ops.const import Types, Modules, RunasPolicies, JobStatus
from orgs.mixins.models import JMSOrgBaseModel
from perms.models import AssetPermission
from perms.utils import UserPermAssetUtil
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):
name = models.CharField(max_length=128, null=True, verbose_name=_('Name'))
@ -54,7 +118,7 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
@property
def last_execution(self):
return self.executions.last()
return self.executions.first()
@property
def date_last_run(self):
@ -90,7 +154,7 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
@property
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
def material(self):
@ -339,7 +403,21 @@ class JobExecution(JMSOrgBaseModel):
'dangerous keyword \'{}\'\033[0m'.format(line['line'], line['file'], line['keyword']))
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):
self.check_assets_perms()
if self.current_job.type == 'playbook':
self.check_danger_keywords()
if self.current_job.type == 'adhoc':

View File

@ -3,7 +3,7 @@ import uuid
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from assets.models import Node
from assets.models import Node, Asset
from perms.utils.user_perm import UserPermAssetUtil
from common.serializers.fields import ReadableHiddenField
from ops.mixin import PeriodTaskSerializerMixin
@ -17,6 +17,8 @@ class JobSerializer(BulkOrgResourceModelSerializer, PeriodTaskSerializerMixin):
nodes = serializers.ListField(required=False, child=serializers.CharField())
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)
assets = serializers.PrimaryKeyRelatedField(label=_('Assets'), queryset=Asset.objects, many=True,
required=False)
def to_internal_value(self, data):
instant = data.get('instant', False)

View File

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

View File

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

View File

@ -95,6 +95,7 @@ class AssetPermissionFilter(PermissionBaseFilter):
node_name = filters.CharFilter(method='do_nothing')
asset_id = filters.UUIDFilter(method='do_nothing')
asset_name = filters.CharFilter(method='do_nothing')
address = filters.CharFilter(method='do_nothing')
accounts = 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)
asset_id = self.get_query_param('asset_id')
asset_name = self.get_query_param('asset_name')
ip = self.get_query_param('address')
address = self.get_query_param('address')
if asset_id:
assets = Asset.objects.filter(pk=asset_id)
elif asset_name:
assets = Asset.objects.filter(name=asset_name)
elif ip:
assets = Asset.objects.filter(ip=ip)
elif address:
assets = Asset.objects.filter(address=address)
else:
return queryset
if not assets:

View File

@ -59,6 +59,8 @@ class RoleViewSet(JMSModelViewSet):
@staticmethod
def set_users_amount(queryset):
"""设置角色的用户绑定数量,以减少查询"""
ids = [role.id for role in queryset]
queryset = Role.objects.filter(id__in=ids)
org_id = current_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'))
@ -69,12 +71,11 @@ class RoleViewSet(JMSModelViewSet):
role.users_amount = role_user_amount_mapper.get(role.id, 0)
return queryset
def paginate_queryset(self, queryset):
page_queryset = super().paginate_queryset(queryset) # 返回是 list 对象
page_queryset_ids = [str(i.id) for i in page_queryset]
queryset = queryset.filter(id__in=page_queryset_ids)
queryset = self.set_users_amount(queryset)
return queryset
def get_serializer(self, *args, **kwargs):
if len(args) == 1:
queryset = self.set_users_amount(args[0])
args = (queryset,)
return super().get_serializer(*args, **kwargs)
def perform_update(self, serializer):
instance = serializer.instance

View File

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

View File

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

View File

@ -1,13 +1,12 @@
# -*- 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 ..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 ..models import User, UserGroup
__all__ = [
'UserGroupSerializer',
@ -15,9 +14,8 @@ __all__ = [
class UserGroupSerializer(BulkOrgResourceModelSerializer):
users = serializers.PrimaryKeyRelatedField(
users = ObjectRelatedField(
required=False, many=True, queryset=User.objects, label=_('User'),
# write_only=True, # group can return many to many on detail
)
class Meta:

View File

@ -39,7 +39,7 @@ class RolesSerializerMixin(serializers.Serializer):
label=_("System roles"), many=True, default=default_system_roles
)
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,
default=default_org_roles
)
@ -91,6 +91,8 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer
)
login_blocked = serializers.BooleanField(read_only=True, label=_("Login blocked"))
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(
source="can_use_ssh_key_login", label=_("Can public key authentication"),
read_only=True