From b7021b5ecb74238f4cc127bbed61a92562e28d1b Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 19 Sep 2019 14:48:25 +0800 Subject: [PATCH] =?UTF-8?q?[Update]=20=E6=94=AF=E6=8C=81=E6=94=B6=E9=9B=86?= =?UTF-8?q?=E8=B5=84=E4=BA=A7=E4=B8=8A=E7=9A=84=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/asset.py | 1 + apps/assets/api/gathered_user.py | 2 + apps/assets/filters.py | 60 +++-- apps/assets/migrations/0041_gathereduser.py | 4 +- apps/assets/models/gathered_user.py | 4 +- apps/assets/serializers/gathered_user.py | 7 +- apps/assets/tasks/gather_asset_users.py | 3 +- apps/common/filters.py | 6 +- apps/locale/zh/LC_MESSAGES/django.mo | Bin 79735 -> 79863 bytes apps/locale/zh/LC_MESSAGES/django.po | 266 ++++++++++++-------- apps/ops/models/adhoc.py | 36 +-- apps/orgs/mixins/api.py | 13 +- apps/perms/api/user_permission/mixin.py | 2 +- 13 files changed, 236 insertions(+), 168 deletions(-) diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index 86e3d8fd2..371ee1fdc 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -36,6 +36,7 @@ class AssetViewSet(OrgBulkModelViewSet): serializer_class = serializers.AssetSerializer permission_classes = (IsOrgAdminOrAppUser,) extra_filter_backends = [AssetByNodeFilterBackend, LabelFilterBackend] + custom_filter_fields = ['admin_user_id'] def set_assets_node(self, assets): if not isinstance(assets, list): diff --git a/apps/assets/api/gathered_user.py b/apps/assets/api/gathered_user.py index 2f844d9e0..038d47208 100644 --- a/apps/assets/api/gathered_user.py +++ b/apps/assets/api/gathered_user.py @@ -6,6 +6,7 @@ from assets.models import GatheredUser from common.permissions import IsOrgAdmin from ..serializers import GatheredUserSerializer +from ..filters import AssetRelatedByNodeFilterBackend __all__ = ['GatheredUserViewSet'] @@ -15,6 +16,7 @@ class GatheredUserViewSet(OrgModelViewSet): queryset = GatheredUser.objects.all() serializer_class = GatheredUserSerializer permission_classes = [IsOrgAdmin] + extra_filter_backends = [AssetRelatedByNodeFilterBackend] filter_fields = ['asset', 'username', 'present'] search_fields = ['username', 'asset__ip', 'asset__hostname'] diff --git a/apps/assets/filters.py b/apps/assets/filters.py index 3636f76e2..0c6008172 100644 --- a/apps/assets/filters.py +++ b/apps/assets/filters.py @@ -12,63 +12,54 @@ from .models import Node, Label class AssetByNodeFilterBackend(filters.BaseFilterBackend): fields = ['node', 'all'] - # def filter_node(self, queryset): - # node_id = self.request.query_params.get("node_id") - # if not node_id: - # return queryset - # - # node = get_object_or_404(Node, id=node_id) - # show_current_asset = self.request.query_params.get("show_current_asset") in ('1', 'true') - # - # # 当前节点是顶层节点, 并且仅显示直接资产 - # if node.is_org_root() and show_current_asset: - # queryset = queryset.filter( - # Q(nodes=node_id) | Q(nodes__isnull=True) - # ).distinct() - # # 当前节点是顶层节点,显示所有资产 - # elif node.is_org_root() and not show_current_asset: - # return queryset - # # 当前节点不是鼎城节点,只显示直接资产 - # elif not node.is_org_root() and show_current_asset: - # queryset = queryset.filter(nodes=node) - # else: - # children = node.get_all_children(with_self=True) - # queryset = queryset.filter(nodes__in=children).distinct() - # return queryset - def get_schema_fields(self, view): return [ coreapi.Field( name=field, location='query', required=False, - type='string', example='', description='' + type='string', example='', description='', schema=None, ) for field in self.fields ] - def filter_queryset(self, request, queryset, view): - node_id = dict_get_any(request.query_params, ['node', 'node_id']) - if not node_id: - return queryset + @staticmethod + def is_query_all(request): query_all_arg = request.query_params.get('all') show_current_asset_arg = request.query_params.get('show_current_asset') query_all = query_all_arg == '1' if show_current_asset_arg is not None: query_all = show_current_asset_arg != '1' + return query_all + + @staticmethod + def get_query_node(request): + node_id = dict_get_any(request.query_params, ['node', 'node_id']) + if not node_id: + return None, False if is_uuid(node_id): node = get_object_or_none(Node, id=node_id) else: node = get_object_or_none(Node, key=node_id) + return node, True - if not node: + @staticmethod + def perform_query(pattern, queryset): + return queryset.filter(nodes__key__regex=pattern) + + def filter_queryset(self, request, queryset, view): + node, has_query_arg = self.get_query_node(request) + if not has_query_arg: + return queryset + + if node is None: return queryset.none() - + query_all = self.is_query_all(request) if query_all: pattern = node.get_all_children_pattern(with_self=True) else: pattern = node.get_children_key_pattern(with_self=True) - return queryset.filter(nodes__key__regex=pattern) + return self.perform_query(pattern, queryset) class LabelFilterBackend(filters.BaseFilterBackend): @@ -117,3 +108,8 @@ class LabelFilterBackend(filters.BaseFilterBackend): return queryset +class AssetRelatedByNodeFilterBackend(AssetByNodeFilterBackend): + @staticmethod + def perform_query(pattern, queryset): + return queryset.filter(asset__nodes__key__regex=pattern).distinct() + diff --git a/apps/assets/migrations/0041_gathereduser.py b/apps/assets/migrations/0041_gathereduser.py index 9accee746..f1b464e74 100644 --- a/apps/assets/migrations/0041_gathereduser.py +++ b/apps/assets/migrations/0041_gathereduser.py @@ -18,10 +18,10 @@ class Migration(migrations.Migration): ('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')), ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), ('username', models.CharField(blank=True, db_index=True, max_length=32, verbose_name='Username')), - ('present', models.BooleanField(default=True)), + ('present', models.BooleanField(default=True, verbose_name='Present')), ('date_created', models.DateTimeField(auto_now_add=True, verbose_name='Date created')), ('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')), - ('asset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='assets.Asset')), + ('asset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='assets.Asset', verbose_name='Asset')), ], options={'ordering': ['asset'], 'verbose_name': 'GatherUser'}, ), diff --git a/apps/assets/models/gathered_user.py b/apps/assets/models/gathered_user.py index 305bced37..282f9293a 100644 --- a/apps/assets/models/gathered_user.py +++ b/apps/assets/models/gathered_user.py @@ -11,10 +11,10 @@ __all__ = ['GatheredUser'] class GatheredUser(OrgModelMixin): id = models.UUIDField(default=uuid.uuid4, primary_key=True) - asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE) + asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_("Asset")) username = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=_('Username')) - present = models.BooleanField(default=True) + present = models.BooleanField(default=True, verbose_name=_("Present")) date_created = models.DateTimeField(auto_now_add=True, verbose_name=_("Date created")) date_updated = models.DateTimeField(auto_now=True, diff --git a/apps/assets/serializers/gathered_user.py b/apps/assets/serializers/gathered_user.py index 517b6a596..956c19c6b 100644 --- a/apps/assets/serializers/gathered_user.py +++ b/apps/assets/serializers/gathered_user.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- # -from ..models import GatheredUser +from django.utils.translation import ugettext_lazy as _ from orgs.mixins.serializers import OrgResourceModelSerializerMixin +from ..models import GatheredUser class GatheredUserSerializer(OrgResourceModelSerializerMixin): @@ -14,3 +15,7 @@ class GatheredUserSerializer(OrgResourceModelSerializerMixin): 'present', 'date_created', 'date_updated' ] read_only_fields = fields + labels = { + 'hostname': _("Hostname"), + 'ip': "IP" + } diff --git a/apps/assets/tasks/gather_asset_users.py b/apps/assets/tasks/gather_asset_users.py index 2662e5c76..efeecc25e 100644 --- a/apps/assets/tasks/gather_asset_users.py +++ b/apps/assets/tasks/gather_asset_users.py @@ -116,8 +116,9 @@ def gather_asset_users(assets, task_name=None): for k, value in hosts_category.items(): if not value['hosts']: continue + _task_name = '{}: {}'.format(task_name, k) task, created = update_or_create_ansible_task( - task_name=task_name, hosts=value['hosts'], tasks=value['tasks'], + task_name=_task_name, hosts=value['hosts'], tasks=value['tasks'], pattern='all', options=const.TASK_OPTIONS, run_as_admin=True, created_by=value['hosts'][0].org_id, ) diff --git a/apps/common/filters.py b/apps/common/filters.py index 0dc275ce0..7792ff088 100644 --- a/apps/common/filters.py +++ b/apps/common/filters.py @@ -70,7 +70,6 @@ class IDSpmFilter(filters.BaseFilterBackend): class CustomFilter(filters.BaseFilterBackend): - custom_filter_fields = [] # ["node", "asset"] def get_schema_fields(self, view): fields = [] @@ -79,7 +78,10 @@ class CustomFilter(filters.BaseFilterBackend): type='string', example='', description='' ) - for field in self.custom_filter_fields: + if not hasattr(view, 'custom_filter_fields'): + return [] + + for field in view.custom_filter_fields: if isinstance(field, str): defaults['name'] = field elif isinstance(field, dict): diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 428c67c3e287794a8808e8fd6b10333195c7cf44..d927e9014bb3e4bb0bacf96b2dce82843b5b6927 100644 GIT binary patch delta 23667 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\n" "Language-Team: Jumpserver team\n" @@ -77,8 +77,8 @@ msgstr "运行参数" #: applications/templates/applications/user_remote_app_list.html:18 #: assets/forms/domain.py:15 assets/forms/label.py:13 #: assets/models/asset.py:295 assets/models/authbook.py:24 -#: assets/serializers/admin_user.py:32 assets/serializers/asset_user.py:82 -#: assets/serializers/system_user.py:31 +#: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:32 +#: assets/serializers/asset_user.py:82 assets/serializers/system_user.py:31 #: assets/templates/assets/admin_user_list.html:46 #: assets/templates/assets/domain_detail.html:60 #: assets/templates/assets/domain_list.html:26 @@ -96,15 +96,13 @@ msgstr "运行参数" #: terminal/templates/terminal/session_list.html:28 #: terminal/templates/terminal/session_list.html:72 #: xpack/plugins/change_auth_plan/forms.py:121 -#: xpack/plugins/change_auth_plan/models.py:412 +#: xpack/plugins/change_auth_plan/models.py:409 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:46 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:54 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:13 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:14 -#: xpack/plugins/cloud/models.py:310 +#: xpack/plugins/cloud/models.py:307 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:63 -#: xpack/plugins/gathered_user/forms.py:13 -#: xpack/plugins/gathered_user/forms.py:15 #: xpack/plugins/orgs/templates/orgs/org_list.html:16 #: xpack/plugins/vault/forms.py:13 xpack/plugins/vault/forms.py:15 msgid "Asset" @@ -162,6 +160,8 @@ msgstr "资产" #: xpack/plugins/cloud/templates/cloud/account_list.html:12 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:56 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:12 +#: xpack/plugins/gathered_user/models.py:28 +#: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:16 #: xpack/plugins/orgs/templates/orgs/org_detail.html:52 #: xpack/plugins/orgs/templates/orgs/org_list.html:12 msgid "Name" @@ -202,6 +202,7 @@ msgstr "参数" #: xpack/plugins/change_auth_plan/models.py:105 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:113 #: xpack/plugins/cloud/models.py:80 xpack/plugins/cloud/models.py:179 +#: xpack/plugins/gathered_user/models.py:46 msgid "Created by" msgstr "创建者" @@ -268,6 +269,7 @@ msgstr "创建日期" #: xpack/plugins/cloud/templates/cloud/account_list.html:15 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:105 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:18 +#: xpack/plugins/gathered_user/models.py:42 #: xpack/plugins/orgs/templates/orgs/org_detail.html:64 #: xpack/plugins/orgs/templates/orgs/org_list.html:22 msgid "Comment" @@ -316,7 +318,7 @@ msgstr "远程应用" #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:71 #: xpack/plugins/cloud/templates/cloud/account_create_update.html:33 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:53 -#: xpack/plugins/gathered_user/templates/gathered_user/vault_create.html:45 +#: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:44 #: xpack/plugins/interface/templates/interface/interface.html:72 #: xpack/plugins/vault/templates/vault/vault_create.html:45 msgid "Reset" @@ -355,7 +357,6 @@ msgstr "重置" #: users/templates/users/user_profile_update.html:68 #: users/templates/users/user_pubkey_update.html:81 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:72 -#: xpack/plugins/gathered_user/templates/gathered_user/vault_create.html:46 #: xpack/plugins/interface/templates/interface/interface.html:74 #: xpack/plugins/vault/templates/vault/vault_create.html:46 msgid "Submit" @@ -429,6 +430,7 @@ msgstr "详情" #: xpack/plugins/cloud/templates/cloud/account_list.html:40 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:29 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:57 +#: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:51 #: xpack/plugins/orgs/templates/orgs/org_detail.html:25 #: xpack/plugins/orgs/templates/orgs/org_list.html:88 msgid "Update" @@ -470,6 +472,7 @@ msgstr "更新" #: xpack/plugins/cloud/templates/cloud/account_list.html:42 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:33 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:58 +#: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:52 #: xpack/plugins/orgs/templates/orgs/org_detail.html:29 #: xpack/plugins/orgs/templates/orgs/org_list.html:90 msgid "Delete" @@ -528,6 +531,7 @@ msgstr "创建远程应用" #: xpack/plugins/cloud/templates/cloud/account_list.html:16 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:72 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:19 +#: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:20 #: xpack/plugins/orgs/templates/orgs/org_list.html:23 msgid "Action" msgstr "动作" @@ -560,11 +564,6 @@ msgstr "远程应用详情" msgid "My RemoteApp" msgstr "我的远程应用" -#: assets/api/asset.py:40 -#, python-format -msgid "%(hostname)s was %(action)s successfully" -msgstr "%(hostname)s %(action)s成功" - #: assets/api/node.py:58 msgid "You can't update the root node name" msgstr "不能修改根节点名称" @@ -590,6 +589,8 @@ msgstr "端口" #: assets/templates/assets/system_user_assets.html:83 #: perms/models/asset_permission.py:79 #: xpack/plugins/change_auth_plan/models.py:71 +#: xpack/plugins/gathered_user/models.py:31 +#: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:17 msgid "Nodes" msgstr "节点" @@ -619,7 +620,7 @@ msgid "Domain" msgstr "网域" #: assets/forms/asset.py:68 assets/forms/asset.py:101 assets/forms/asset.py:114 -#: assets/forms/asset.py:149 assets/models/node.py:393 +#: assets/forms/asset.py:149 assets/models/node.py:401 #: assets/templates/assets/asset_create.html:42 #: perms/forms/asset_permission.py:82 perms/forms/asset_permission.py:89 #: perms/templates/perms/asset_permission_list.html:53 @@ -694,7 +695,7 @@ msgstr "SSH网关,支持代理SSH,RDP和VNC" #: users/templates/users/user_profile.html:47 #: xpack/plugins/change_auth_plan/forms.py:106 #: xpack/plugins/change_auth_plan/models.py:62 -#: xpack/plugins/change_auth_plan/models.py:408 +#: xpack/plugins/change_auth_plan/models.py:405 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:65 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:53 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:12 @@ -722,7 +723,7 @@ msgstr "密码或密钥密码" #: users/templates/users/user_pubkey_update.html:41 #: users/templates/users/user_update.html:20 #: xpack/plugins/change_auth_plan/models.py:92 -#: xpack/plugins/change_auth_plan/models.py:263 +#: xpack/plugins/change_auth_plan/models.py:260 msgid "Password" msgstr "密码" @@ -785,6 +786,7 @@ msgid "IP" msgstr "IP" #: assets/models/asset.py:136 assets/serializers/asset_user.py:27 +#: assets/serializers/gathered_user.py:19 #: assets/templates/assets/_asset_list_modal.html:46 #: assets/templates/assets/_asset_user_auth_update_modal.html:9 #: assets/templates/assets/_asset_user_auth_view_modal.html:15 @@ -914,12 +916,12 @@ msgid "AuthBook" msgstr "" #: assets/models/base.py:31 xpack/plugins/change_auth_plan/models.py:96 -#: xpack/plugins/change_auth_plan/models.py:270 +#: xpack/plugins/change_auth_plan/models.py:267 msgid "SSH private key" msgstr "ssh密钥" #: assets/models/base.py:32 xpack/plugins/change_auth_plan/models.py:99 -#: xpack/plugins/change_auth_plan/models.py:266 +#: xpack/plugins/change_auth_plan/models.py:263 msgid "SSH public key" msgstr "ssh公钥" @@ -1054,6 +1056,11 @@ msgstr "命令过滤规则" msgid "Gateway" msgstr "网关" +#: assets/models/gathered_user.py:17 +#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:75 +msgid "Present" +msgstr "存在" + #: assets/models/gathered_user.py:32 msgid "GatherUser" msgstr "收集用户" @@ -1096,7 +1103,7 @@ msgstr "默认资产组" msgid "User" msgstr "用户" -#: assets/models/label.py:19 assets/models/node.py:384 +#: assets/models/label.py:19 assets/models/node.py:392 #: assets/templates/assets/label_list.html:15 settings/models.py:30 msgid "Value" msgstr "值" @@ -1105,19 +1112,19 @@ msgstr "值" msgid "Category" msgstr "分类" -#: assets/models/node.py:222 +#: assets/models/node.py:230 msgid "New node" msgstr "新节点" -#: assets/models/node.py:308 +#: assets/models/node.py:316 msgid "ungrouped" msgstr "未分组" -#: assets/models/node.py:310 +#: assets/models/node.py:318 msgid "empty" msgstr "空" -#: assets/models/node.py:383 +#: assets/models/node.py:391 msgid "Key" msgstr "键" @@ -1291,7 +1298,7 @@ msgstr "测试资产可连接性: {}" #: assets/tasks/asset_user_connectivity.py:27 #: assets/tasks/push_system_user.py:130 -#: xpack/plugins/change_auth_plan/models.py:521 +#: xpack/plugins/change_auth_plan/models.py:518 msgid "The asset {} system platform {} does not support run Ansible tasks" msgstr "资产 {} 系统平台 {} 不支持运行 Ansible 任务" @@ -1311,7 +1318,7 @@ msgstr "更新资产硬件信息" msgid "Update asset hardware info: {}" msgstr "更新资产硬件信息: {}" -#: assets/tasks/gather_asset_users.py:95 +#: assets/tasks/gather_asset_users.py:96 msgid "Gather assets users" msgstr "收集资产上的用户" @@ -1536,6 +1543,7 @@ msgstr "重命名成功" #: perms/templates/perms/remote_app_permission_create_update.html:39 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:43 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:27 +#: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:27 msgid "Basic" msgstr "基本" @@ -1558,6 +1566,7 @@ msgstr "自动生成密钥" #: terminal/templates/terminal/terminal_update.html:40 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:67 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:48 +#: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:39 msgid "Other" msgstr "其它" @@ -1609,12 +1618,13 @@ msgstr "替换资产的管理员" #: perms/templates/perms/asset_permission_asset.html:103 #: xpack/plugins/change_auth_plan/forms.py:116 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:109 +#: xpack/plugins/gathered_user/forms.py:36 msgid "Select nodes" msgstr "选择节点" #: assets/templates/assets/admin_user_detail.html:100 #: assets/templates/assets/asset_detail.html:204 -#: assets/templates/assets/asset_list.html:418 +#: assets/templates/assets/asset_list.html:422 #: assets/templates/assets/cmd_filter_detail.html:106 #: assets/templates/assets/system_user_assets.html:97 #: assets/templates/assets/system_user_detail.html:182 @@ -1631,6 +1641,7 @@ msgstr "选择节点" #: users/templates/users/user_list.html:256 #: xpack/plugins/cloud/templates/cloud/account_create_update.html:34 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:54 +#: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:45 #: xpack/plugins/interface/templates/interface/interface.html:103 #: xpack/plugins/orgs/templates/orgs/org_create_update.html:33 msgid "Confirm" @@ -1678,8 +1689,8 @@ msgstr "创建管理用户" #: assets/templates/assets/admin_user_list.html:162 #: assets/templates/assets/admin_user_list.html:193 -#: assets/templates/assets/asset_list.html:299 -#: assets/templates/assets/asset_list.html:336 +#: assets/templates/assets/asset_list.html:303 +#: assets/templates/assets/asset_list.html:340 #: assets/templates/assets/system_user_list.html:192 #: assets/templates/assets/system_user_list.html:223 #: users/templates/users/user_group_list.html:164 @@ -1797,31 +1808,31 @@ msgstr "禁用所选" msgid "Active selected" msgstr "激活所选" -#: assets/templates/assets/asset_list.html:189 +#: assets/templates/assets/asset_list.html:193 msgid "Add assets to node" msgstr "添加资产到节点" -#: assets/templates/assets/asset_list.html:190 +#: assets/templates/assets/asset_list.html:194 msgid "Move assets to node" msgstr "移动资产到节点" -#: assets/templates/assets/asset_list.html:192 +#: assets/templates/assets/asset_list.html:196 msgid "Refresh node hardware info" msgstr "更新节点资产硬件信息" -#: assets/templates/assets/asset_list.html:193 +#: assets/templates/assets/asset_list.html:197 msgid "Test node connective" msgstr "测试节点资产可连接性" -#: assets/templates/assets/asset_list.html:195 +#: assets/templates/assets/asset_list.html:199 msgid "Display only current node assets" msgstr "仅显示当前节点资产" -#: assets/templates/assets/asset_list.html:196 +#: assets/templates/assets/asset_list.html:200 msgid "Displays all child node assets" msgstr "显示所有子节点资产" -#: assets/templates/assets/asset_list.html:412 +#: assets/templates/assets/asset_list.html:416 #: assets/templates/assets/system_user_list.html:133 #: users/templates/users/user_detail.html:388 #: users/templates/users/user_detail.html:414 @@ -1832,11 +1843,11 @@ msgstr "显示所有子节点资产" msgid "Are you sure?" msgstr "你确认吗?" -#: assets/templates/assets/asset_list.html:413 +#: assets/templates/assets/asset_list.html:417 msgid "This will delete the selected assets !!!" msgstr "删除选择资产" -#: assets/templates/assets/asset_list.html:416 +#: assets/templates/assets/asset_list.html:420 #: assets/templates/assets/system_user_list.html:137 #: settings/templates/settings/terminal_setting.html:166 #: users/templates/users/user_detail.html:392 @@ -1850,16 +1861,16 @@ msgstr "删除选择资产" msgid "Cancel" msgstr "取消" -#: assets/templates/assets/asset_list.html:429 +#: assets/templates/assets/asset_list.html:433 msgid "Asset Deleted." msgstr "已被删除" -#: assets/templates/assets/asset_list.html:430 #: assets/templates/assets/asset_list.html:434 +#: assets/templates/assets/asset_list.html:438 msgid "Asset Delete" msgstr "删除" -#: assets/templates/assets/asset_list.html:433 +#: assets/templates/assets/asset_list.html:437 msgid "Asset Deleting failed." msgstr "删除失败" @@ -2179,7 +2190,6 @@ msgstr "成功" #: audits/models.py:32 #: authentication/templates/authentication/_access_key_modal.html:38 -#: xpack/plugins/gathered_user/templates/gathered_user/gathered_user_list.html:48 #: xpack/plugins/vault/templates/vault/vault.html:46 msgid "Create" msgstr "创建" @@ -2210,8 +2220,8 @@ msgstr "启用" msgid "-" msgstr "" -#: audits/models.py:77 xpack/plugins/cloud/models.py:267 -#: xpack/plugins/cloud/models.py:290 +#: audits/models.py:77 xpack/plugins/cloud/models.py:264 +#: xpack/plugins/cloud/models.py:287 msgid "Failed" msgstr "失败" @@ -2239,15 +2249,15 @@ msgid "MFA" msgstr "MFA" #: audits/models.py:86 audits/templates/audits/login_log_list.html:63 -#: xpack/plugins/change_auth_plan/models.py:416 +#: xpack/plugins/change_auth_plan/models.py:413 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:15 -#: xpack/plugins/cloud/models.py:281 +#: xpack/plugins/cloud/models.py:278 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:69 msgid "Reason" msgstr "原因" #: audits/models.py:87 audits/templates/audits/login_log_list.html:64 -#: xpack/plugins/cloud/models.py:278 xpack/plugins/cloud/models.py:313 +#: xpack/plugins/cloud/models.py:275 xpack/plugins/cloud/models.py:310 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:70 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:65 msgid "Status" @@ -2265,10 +2275,11 @@ msgstr "登录日期" #: perms/templates/perms/asset_permission_detail.html:86 #: perms/templates/perms/remote_app_permission_detail.html:78 #: terminal/models.py:165 terminal/templates/terminal/session_list.html:34 -#: xpack/plugins/change_auth_plan/models.py:249 -#: xpack/plugins/change_auth_plan/models.py:419 +#: xpack/plugins/change_auth_plan/models.py:246 +#: xpack/plugins/change_auth_plan/models.py:416 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:59 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:17 +#: xpack/plugins/gathered_user/models.py:143 msgid "Date start" msgstr "开始日期" @@ -2688,19 +2699,6 @@ msgstr "" msgid "Encrypt field using Secret Key" msgstr "" -#: common/mixins/api.py:64 -#, python-format -msgid "%(name)s was %(action)s successfully" -msgstr "%(name)s %(action)s成功" - -#: common/mixins/api.py:65 -msgid "create" -msgstr "创建" - -#: common/mixins/api.py:65 -msgid "update" -msgstr "更新" - #: common/mixins/models.py:31 msgid "is discard" msgstr "" @@ -2800,54 +2798,55 @@ msgstr "Become" msgid "Create by" msgstr "创建者" -#: ops/models/adhoc.py:224 +#: ops/models/adhoc.py:226 msgid "{} Start task: {}" msgstr "{} 任务开始: {}" -#: ops/models/adhoc.py:227 +#: ops/models/adhoc.py:238 msgid "{} Task finish" msgstr "{} 任务结束" -#: ops/models/adhoc.py:325 +#: ops/models/adhoc.py:329 msgid "Start time" msgstr "开始时间" -#: ops/models/adhoc.py:326 +#: ops/models/adhoc.py:330 msgid "End time" msgstr "完成时间" -#: ops/models/adhoc.py:327 ops/templates/ops/adhoc_history.html:57 +#: ops/models/adhoc.py:331 ops/templates/ops/adhoc_history.html:57 #: ops/templates/ops/task_history.html:63 ops/templates/ops/task_list.html:33 -#: xpack/plugins/change_auth_plan/models.py:252 -#: xpack/plugins/change_auth_plan/models.py:422 +#: xpack/plugins/change_auth_plan/models.py:249 +#: xpack/plugins/change_auth_plan/models.py:419 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:58 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:16 +#: xpack/plugins/gathered_user/models.py:146 msgid "Time" msgstr "时间" -#: ops/models/adhoc.py:328 ops/templates/ops/adhoc_detail.html:106 +#: ops/models/adhoc.py:332 ops/templates/ops/adhoc_detail.html:106 #: ops/templates/ops/adhoc_history.html:55 #: ops/templates/ops/adhoc_history_detail.html:69 #: ops/templates/ops/task_detail.html:84 ops/templates/ops/task_history.html:61 msgid "Is finished" msgstr "是否完成" -#: ops/models/adhoc.py:329 ops/templates/ops/adhoc_history.html:56 +#: ops/models/adhoc.py:333 ops/templates/ops/adhoc_history.html:56 #: ops/templates/ops/task_history.html:62 msgid "Is success" msgstr "是否成功" -#: ops/models/adhoc.py:330 +#: ops/models/adhoc.py:334 msgid "Adhoc raw result" msgstr "结果" -#: ops/models/adhoc.py:331 +#: ops/models/adhoc.py:335 msgid "Adhoc result summary" msgstr "汇总" #: ops/models/command.py:22 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:56 -#: xpack/plugins/cloud/models.py:276 +#: xpack/plugins/cloud/models.py:273 msgid "Result" msgstr "结果" @@ -2882,6 +2881,7 @@ msgstr "运行用户" #: ops/templates/ops/adhoc_detail.html:94 ops/templates/ops/task_list.html:28 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:18 +#: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:19 msgid "Run times" msgstr "执行次数" @@ -3049,6 +3049,7 @@ msgstr "版本" #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:54 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:141 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:55 +#: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:49 msgid "Run" msgstr "执行" @@ -3067,6 +3068,7 @@ msgid "Ops" msgstr "作业中心" #: ops/views/adhoc.py:46 templates/_nav.html:115 +#: xpack/plugins/gathered_user/views.py:35 msgid "Task list" msgstr "任务列表" @@ -3377,21 +3379,21 @@ msgstr "连接LDAP成功" msgid "Match {} s users" msgstr "匹配 {} 个用户" -#: settings/api.py:159 +#: settings/api.py:161 msgid "succeed: {} failed: {} total: {}" msgstr "成功:{} 失败:{} 总数:{}" -#: settings/api.py:181 settings/api.py:217 +#: settings/api.py:183 settings/api.py:219 msgid "" "Error: Account invalid (Please make sure the information such as Access key " "or Secret key is correct)" msgstr "错误:账户无效 (请确保 Access key 或 Secret key 等信息正确)" -#: settings/api.py:187 settings/api.py:223 +#: settings/api.py:189 settings/api.py:225 msgid "Create succeed" msgstr "创建成功" -#: settings/api.py:205 settings/api.py:243 +#: settings/api.py:207 settings/api.py:245 #: settings/templates/settings/terminal_setting.html:154 msgid "Delete succeed" msgstr "删除成功" @@ -3850,7 +3852,7 @@ msgid "Endpoint suffix" msgstr "端点后缀" #: settings/templates/settings/replay_storage_create.html:136 -#: xpack/plugins/cloud/models.py:307 +#: xpack/plugins/cloud/models.py:304 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:109 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:62 msgid "Region" @@ -5444,7 +5446,7 @@ msgid "Password length" msgstr "密码长度" #: xpack/plugins/change_auth_plan/forms.py:51 -#: xpack/plugins/change_auth_plan/models.py:212 +#: xpack/plugins/change_auth_plan/models.py:209 msgid "* For security, do not change {} user's password" msgstr "* 为了安全,禁止更改 {} 用户的密码" @@ -5465,6 +5467,9 @@ msgstr "* 请输入有效的 crontab 表达式" #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:41 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:72 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:16 +#: xpack/plugins/gathered_user/forms.py:13 +#: xpack/plugins/gathered_user/forms.py:41 +#: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:32 msgid "Periodic perform" msgstr "定时执行" @@ -5477,10 +5482,12 @@ msgstr "" "用户不存在,则创建用户。" #: xpack/plugins/change_auth_plan/forms.py:131 xpack/plugins/cloud/forms.py:90 +#: xpack/plugins/gathered_user/forms.py:44 msgid "Tips: (Units: hour)" msgstr "提示:(单位: 时)" #: xpack/plugins/change_auth_plan/forms.py:132 xpack/plugins/cloud/forms.py:91 +#: xpack/plugins/gathered_user/forms.py:45 msgid "" "eg: Every Sunday 03:05 run <5 3 * * 0>
Tips: Using 5 digits linux " "crontab expressions (