mirror of https://github.com/jumpserver/jumpserver
commit
776234e8cc
|
@ -87,6 +87,9 @@ class SystemUser(BaseUser):
|
||||||
(PROTOCOL_POSTGRESQL, 'postgresql'),
|
(PROTOCOL_POSTGRESQL, 'postgresql'),
|
||||||
(PROTOCOL_K8S, 'k8s'),
|
(PROTOCOL_K8S, 'k8s'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SUPPORT_PUSH_PROTOCOLS = [PROTOCOL_SSH, PROTOCOL_RDP]
|
||||||
|
|
||||||
ASSET_CATEGORY_PROTOCOLS = [
|
ASSET_CATEGORY_PROTOCOLS = [
|
||||||
PROTOCOL_SSH, PROTOCOL_RDP, PROTOCOL_TELNET, PROTOCOL_VNC
|
PROTOCOL_SSH, PROTOCOL_RDP, PROTOCOL_TELNET, PROTOCOL_VNC
|
||||||
]
|
]
|
||||||
|
@ -151,11 +154,15 @@ class SystemUser(BaseUser):
|
||||||
return self.get_login_mode_display()
|
return self.get_login_mode_display()
|
||||||
|
|
||||||
def is_need_push(self):
|
def is_need_push(self):
|
||||||
if self.auto_push and self.protocol in [self.PROTOCOL_SSH, self.PROTOCOL_RDP]:
|
if self.auto_push and self.is_protocol_support_push:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_protocol_support_push(self):
|
||||||
|
return self.protocol in self.SUPPORT_PUSH_PROTOCOLS
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_need_cmd_filter(self):
|
def is_need_cmd_filter(self):
|
||||||
return self.protocol not in [self.PROTOCOL_RDP, self.PROTOCOL_VNC]
|
return self.protocol not in [self.PROTOCOL_RDP, self.PROTOCOL_VNC]
|
||||||
|
|
|
@ -193,7 +193,8 @@ def on_asset_nodes_add(instance, action, reverse, pk_set, **kwargs):
|
||||||
systemuser_id=system_user_id,
|
systemuser_id=system_user_id,
|
||||||
asset_id=asset_id
|
asset_id=asset_id
|
||||||
))
|
))
|
||||||
push_system_user_to_assets.delay(system_user_id, asset_ids_to_push)
|
if asset_ids_to_push:
|
||||||
|
push_system_user_to_assets.delay(system_user_id, asset_ids_to_push)
|
||||||
m2m_model.objects.bulk_create(to_create)
|
m2m_model.objects.bulk_create(to_create)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.db.models.signals import (
|
||||||
m2m_changed
|
m2m_changed
|
||||||
)
|
)
|
||||||
|
|
||||||
from orgs.utils import ensure_in_real_or_default_org
|
from orgs.utils import ensure_in_real_or_default_org, tmp_to_org
|
||||||
from common.const.signals import PRE_ADD, POST_REMOVE, PRE_CLEAR
|
from common.const.signals import PRE_ADD, POST_REMOVE, PRE_CLEAR
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from assets.models import Asset, Node, compute_parent_key
|
from assets.models import Asset, Node, compute_parent_key
|
||||||
|
@ -34,15 +34,16 @@ def on_node_asset_change(sender, action, instance, reverse, pk_set, **kwargs):
|
||||||
|
|
||||||
operator = mapper[action]
|
operator = mapper[action]
|
||||||
|
|
||||||
if reverse:
|
with tmp_to_org(instance.org):
|
||||||
node: Node = instance
|
if reverse:
|
||||||
asset_pk_set = set(pk_set)
|
node: Node = instance
|
||||||
NodeAssetsAmountUtils.update_node_assets_amount(node, asset_pk_set, operator)
|
asset_pk_set = set(pk_set)
|
||||||
else:
|
NodeAssetsAmountUtils.update_node_assets_amount(node, asset_pk_set, operator)
|
||||||
asset_pk = instance.id
|
else:
|
||||||
# 与资产直接关联的节点
|
asset_pk = instance.id
|
||||||
node_keys = set(Node.objects.filter(id__in=pk_set).values_list('key', flat=True))
|
# 与资产直接关联的节点
|
||||||
NodeAssetsAmountUtils.update_nodes_asset_amount(node_keys, asset_pk, operator)
|
node_keys = set(Node.objects.filter(id__in=pk_set).values_list('key', flat=True))
|
||||||
|
NodeAssetsAmountUtils.update_nodes_asset_amount(node_keys, asset_pk, operator)
|
||||||
|
|
||||||
|
|
||||||
class NodeAssetsAmountUtils:
|
class NodeAssetsAmountUtils:
|
||||||
|
|
|
@ -25,10 +25,13 @@ def check_asset_can_run_ansible(asset):
|
||||||
|
|
||||||
|
|
||||||
def check_system_user_can_run_ansible(system_user):
|
def check_system_user_can_run_ansible(system_user):
|
||||||
if not system_user.is_need_push():
|
if not system_user.auto_push:
|
||||||
msg = _("Push system user task skip, auto push not enable or "
|
logger.warn(f'Push system user task skip, auto push not enable: system_user={system_user.name}')
|
||||||
"protocol is not ssh or rdp: {}").format(system_user.name)
|
return False
|
||||||
logger.info(msg)
|
if not system_user.is_protocol_support_push:
|
||||||
|
logger.warn(f'Push system user task skip, protocol not support: '
|
||||||
|
f'system_user={system_user.name} protocol={system_user.protocol} '
|
||||||
|
f'support_protocol={system_user.SUPPORT_PUSH_PROTOCOLS}')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Push root as system user is dangerous
|
# Push root as system user is dangerous
|
||||||
|
@ -37,10 +40,6 @@ def check_system_user_can_run_ansible(system_user):
|
||||||
logger.info(msg)
|
logger.info(msg)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# if system_user.protocol != "ssh":
|
|
||||||
# msg = _("System user protocol not ssh: {}".format(system_user))
|
|
||||||
# logger.info(msg)
|
|
||||||
# return False
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,9 @@ class SessionAuditSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class CommandExecutionSerializer(serializers.ModelSerializer):
|
class CommandExecutionSerializer(serializers.ModelSerializer):
|
||||||
is_success = serializers.BooleanField(read_only=True, label=_('Is success'))
|
is_success = serializers.BooleanField(read_only=True, label=_('Is success'))
|
||||||
|
hosts_display = serializers.ListSerializer(
|
||||||
|
child=serializers.CharField(), source='hosts', read_only=True, label=_('Hosts for display')
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CommandExecution
|
model = CommandExecution
|
||||||
|
@ -72,7 +75,7 @@ class CommandExecutionSerializer(serializers.ModelSerializer):
|
||||||
'run_as', 'command', 'user', 'is_finished',
|
'run_as', 'command', 'user', 'is_finished',
|
||||||
'date_start', 'result', 'is_success', 'org_id'
|
'date_start', 'result', 'is_success', 'org_id'
|
||||||
]
|
]
|
||||||
fields = fields_small + ['hosts', 'run_as_display', 'user_display']
|
fields = fields_small + ['hosts', 'hosts_display', 'run_as_display', 'user_display']
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'result': {'label': _('Result')}, # model 上的方法,只能在这修改
|
'result': {'label': _('Result')}, # model 上的方法,只能在这修改
|
||||||
'is_success': {'label': _('Is success')},
|
'is_success': {'label': _('Is success')},
|
||||||
|
|
|
@ -68,6 +68,7 @@ class LoginConfirmSetting(CommonModelMixin):
|
||||||
def create_confirm_ticket(self, request=None):
|
def create_confirm_ticket(self, request=None):
|
||||||
from tickets import const
|
from tickets import const
|
||||||
from tickets.models import Ticket
|
from tickets.models import Ticket
|
||||||
|
from orgs.models import Organization
|
||||||
ticket_title = _('Login confirm') + ' {}'.format(self.user)
|
ticket_title = _('Login confirm') + ' {}'.format(self.user)
|
||||||
ticket_meta = self.construct_confirm_ticket_meta(request)
|
ticket_meta = self.construct_confirm_ticket_meta(request)
|
||||||
ticket_assignees = self.reviewers.all()
|
ticket_assignees = self.reviewers.all()
|
||||||
|
@ -75,6 +76,7 @@ class LoginConfirmSetting(CommonModelMixin):
|
||||||
'title': ticket_title,
|
'title': ticket_title,
|
||||||
'type': const.TicketTypeChoices.login_confirm.value,
|
'type': const.TicketTypeChoices.login_confirm.value,
|
||||||
'meta': ticket_meta,
|
'meta': ticket_meta,
|
||||||
|
'org_id': Organization.ROOT_ID,
|
||||||
}
|
}
|
||||||
ticket = Ticket.objects.create(**data)
|
ticket = Ticket.objects.create(**data)
|
||||||
ticket.assignees.set(ticket_assignees)
|
ticket.assignees.set(ticket_assignees)
|
||||||
|
|
|
@ -170,7 +170,7 @@ class UserLoginWaitConfirmView(TemplateView):
|
||||||
if not ticket_id:
|
if not ticket_id:
|
||||||
ticket = None
|
ticket = None
|
||||||
else:
|
else:
|
||||||
ticket = get_object_or_none(Ticket, pk=ticket_id)
|
ticket = Ticket.all().filter(pk=ticket_id).first()
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
if ticket:
|
if ticket:
|
||||||
timestamp_created = datetime.datetime.timestamp(ticket.date_created)
|
timestamp_created = datetime.datetime.timestamp(ticket.date_created)
|
||||||
|
|
|
@ -283,7 +283,7 @@ class Config(dict):
|
||||||
'SERVER_REPLAY_STORAGE': {},
|
'SERVER_REPLAY_STORAGE': {},
|
||||||
'CONNECTION_TOKEN_ENABLED': False,
|
'CONNECTION_TOKEN_ENABLED': False,
|
||||||
'ONLY_ALLOW_EXIST_USER_AUTH': False,
|
'ONLY_ALLOW_EXIST_USER_AUTH': False,
|
||||||
'ONLY_ALLOW_AUTH_FROM_SOURCE': True,
|
'ONLY_ALLOW_AUTH_FROM_SOURCE': False,
|
||||||
'DISK_CHECK_ENABLED': True,
|
'DISK_CHECK_ENABLED': True,
|
||||||
'SESSION_SAVE_EVERY_REQUEST': True,
|
'SESSION_SAVE_EVERY_REQUEST': True,
|
||||||
'SESSION_EXPIRE_AT_BROWSER_CLOSE_FORCE': False,
|
'SESSION_EXPIRE_AT_BROWSER_CLOSE_FORCE': False,
|
||||||
|
|
|
@ -12,7 +12,7 @@ XPACK_CONTEXT_PROCESSOR = []
|
||||||
|
|
||||||
if XPACK_ENABLED:
|
if XPACK_ENABLED:
|
||||||
from xpack.utils import get_xpack_templates_dir, get_xpack_context_processor
|
from xpack.utils import get_xpack_templates_dir, get_xpack_context_processor
|
||||||
INSTALLED_APPS.append('xpack.apps.XpackConfig')
|
INSTALLED_APPS.insert(0, 'xpack.apps.XpackConfig')
|
||||||
XPACK_TEMPLATES_DIR = get_xpack_templates_dir(const.BASE_DIR)
|
XPACK_TEMPLATES_DIR = get_xpack_templates_dir(const.BASE_DIR)
|
||||||
XPACK_CONTEXT_PROCESSOR = get_xpack_context_processor()
|
XPACK_CONTEXT_PROCESSOR = get_xpack_context_processor()
|
||||||
TEMPLATES[0]['DIRS'].extend(XPACK_TEMPLATES_DIR)
|
TEMPLATES[0]['DIRS'].extend(XPACK_TEMPLATES_DIR)
|
||||||
|
|
|
@ -42,13 +42,13 @@ INSTALLED_APPS = [
|
||||||
'perms.apps.PermsConfig',
|
'perms.apps.PermsConfig',
|
||||||
'ops.apps.OpsConfig',
|
'ops.apps.OpsConfig',
|
||||||
'settings.apps.SettingsConfig',
|
'settings.apps.SettingsConfig',
|
||||||
'common.apps.CommonConfig',
|
|
||||||
'terminal.apps.TerminalConfig',
|
'terminal.apps.TerminalConfig',
|
||||||
'audits.apps.AuditsConfig',
|
'audits.apps.AuditsConfig',
|
||||||
'authentication.apps.AuthenticationConfig', # authentication
|
'authentication.apps.AuthenticationConfig', # authentication
|
||||||
'applications.apps.ApplicationsConfig',
|
'applications.apps.ApplicationsConfig',
|
||||||
'tickets.apps.TicketsConfig',
|
'tickets.apps.TicketsConfig',
|
||||||
'acls.apps.AclsConfig',
|
'acls.apps.AclsConfig',
|
||||||
|
'common.apps.CommonConfig',
|
||||||
'jms_oidc_rp',
|
'jms_oidc_rp',
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
'rest_framework_swagger',
|
'rest_framework_swagger',
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#
|
#
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from werkzeug.local import LocalProxy
|
from werkzeug.local import LocalProxy
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from common.local import thread_local
|
from common.local import thread_local
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,4 +19,11 @@ def get_current_request():
|
||||||
return _find('current_request')
|
return _find('current_request')
|
||||||
|
|
||||||
|
|
||||||
|
def has_valid_xpack_license():
|
||||||
|
if not settings.XPACK_ENABLED:
|
||||||
|
return False
|
||||||
|
from xpack.plugins.license.models import License
|
||||||
|
return License.has_valid_license()
|
||||||
|
|
||||||
|
|
||||||
current_request = LocalProxy(partial(_find, 'current_request'))
|
current_request = LocalProxy(partial(_find, 'current_request'))
|
||||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-03-11 17:54+0800\n"
|
"POT-Creation-Date: 2021-03-17 18:17+0800\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||||
|
@ -35,7 +35,7 @@ msgstr ""
|
||||||
#: assets/models/cmd_filter.py:21 assets/models/domain.py:21
|
#: assets/models/cmd_filter.py:21 assets/models/domain.py:21
|
||||||
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
|
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
|
||||||
#: orgs/models.py:23 perms/models/base.py:49 settings/models.py:29
|
#: orgs/models.py:23 perms/models/base.py:49 settings/models.py:29
|
||||||
#: terminal/models/storage.py:23 terminal/models/storage.py:75
|
#: terminal/models/storage.py:23 terminal/models/storage.py:81
|
||||||
#: terminal/models/task.py:16 terminal/models/terminal.py:139
|
#: terminal/models/task.py:16 terminal/models/terminal.py:139
|
||||||
#: users/forms/profile.py:32 users/models/group.py:15 users/models/user.py:530
|
#: users/forms/profile.py:32 users/models/group.py:15 users/models/user.py:530
|
||||||
#: users/templates/users/_select_user_modal.html:13
|
#: users/templates/users/_select_user_modal.html:13
|
||||||
|
@ -56,12 +56,12 @@ msgid "Name"
|
||||||
msgstr "名称"
|
msgstr "名称"
|
||||||
|
|
||||||
#: acls/models/base.py:27 assets/models/cmd_filter.py:53
|
#: acls/models/base.py:27 assets/models/cmd_filter.py:53
|
||||||
#: assets/models/user.py:119
|
#: assets/models/user.py:122
|
||||||
msgid "Priority"
|
msgid "Priority"
|
||||||
msgstr "优先级"
|
msgstr "优先级"
|
||||||
|
|
||||||
#: acls/models/base.py:28 assets/models/cmd_filter.py:53
|
#: acls/models/base.py:28 assets/models/cmd_filter.py:53
|
||||||
#: assets/models/user.py:119
|
#: assets/models/user.py:122
|
||||||
msgid "1-100, the lower the value will be match first"
|
msgid "1-100, the lower the value will be match first"
|
||||||
msgstr "优先级可选范围为 1-100 (数值越小越优先)"
|
msgstr "优先级可选范围为 1-100 (数值越小越优先)"
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ msgstr "激活中"
|
||||||
#: assets/models/domain.py:22 assets/models/domain.py:56
|
#: assets/models/domain.py:22 assets/models/domain.py:56
|
||||||
#: assets/models/group.py:23 assets/models/label.py:23 ops/models/adhoc.py:37
|
#: assets/models/group.py:23 assets/models/label.py:23 ops/models/adhoc.py:37
|
||||||
#: orgs/models.py:26 perms/models/base.py:57 settings/models.py:34
|
#: orgs/models.py:26 perms/models/base.py:57 settings/models.py:34
|
||||||
#: terminal/models/storage.py:29 terminal/models/storage.py:81
|
#: terminal/models/storage.py:29 terminal/models/storage.py:87
|
||||||
#: terminal/models/terminal.py:153 tickets/models/ticket.py:73
|
#: terminal/models/terminal.py:153 tickets/models/ticket.py:73
|
||||||
#: users/models/group.py:16 users/models/user.py:563
|
#: users/models/group.py:16 users/models/user.py:563
|
||||||
#: users/templates/users/user_detail.html:115
|
#: users/templates/users/user_detail.html:115
|
||||||
|
@ -125,13 +125,13 @@ msgstr "动作"
|
||||||
#: acls/models/login_acl.py:28 acls/models/login_asset_acl.py:20
|
#: acls/models/login_acl.py:28 acls/models/login_asset_acl.py:20
|
||||||
#: acls/serializers/login_acl.py:28 assets/models/label.py:15
|
#: acls/serializers/login_acl.py:28 assets/models/label.py:15
|
||||||
#: audits/models.py:36 audits/models.py:56 audits/models.py:69
|
#: audits/models.py:36 audits/models.py:56 audits/models.py:69
|
||||||
#: audits/serializers.py:81 authentication/models.py:44
|
#: audits/serializers.py:84 authentication/models.py:44
|
||||||
#: authentication/models.py:95 orgs/models.py:18 orgs/models.py:403
|
#: authentication/models.py:97 orgs/models.py:18 orgs/models.py:417
|
||||||
#: perms/models/base.py:50 templates/index.html:78
|
#: perms/models/base.py:50 templates/index.html:78
|
||||||
#: terminal/backends/command/models.py:18
|
#: terminal/backends/command/models.py:18
|
||||||
#: terminal/backends/command/serializers.py:12 terminal/models/session.py:37
|
#: terminal/backends/command/serializers.py:12 terminal/models/session.py:37
|
||||||
#: tickets/models/comment.py:17 users/models/user.py:159
|
#: tickets/models/comment.py:17 users/models/user.py:159
|
||||||
#: users/models/user.py:677 users/serializers/group.py:20
|
#: users/models/user.py:699 users/serializers/group.py:20
|
||||||
#: users/templates/users/user_asset_permission.html:38
|
#: users/templates/users/user_asset_permission.html:38
|
||||||
#: users/templates/users/user_asset_permission.html:64
|
#: users/templates/users/user_asset_permission.html:64
|
||||||
#: users/templates/users/user_database_app_permission.html:37
|
#: users/templates/users/user_database_app_permission.html:37
|
||||||
|
@ -144,7 +144,7 @@ msgstr "动作"
|
||||||
msgid "User"
|
msgid "User"
|
||||||
msgstr "用户"
|
msgstr "用户"
|
||||||
|
|
||||||
#: acls/models/login_asset_acl.py:17 authentication/models.py:71
|
#: acls/models/login_asset_acl.py:17 authentication/models.py:72
|
||||||
#: tickets/const.py:9 users/templates/users/user_detail.html:250
|
#: tickets/const.py:9 users/templates/users/user_detail.html:250
|
||||||
msgid "Login confirm"
|
msgid "Login confirm"
|
||||||
msgstr "登录复核"
|
msgstr "登录复核"
|
||||||
|
@ -156,9 +156,9 @@ msgstr "系统用户"
|
||||||
#: acls/models/login_asset_acl.py:22
|
#: acls/models/login_asset_acl.py:22
|
||||||
#: applications/serializers/attrs/application_category/remote_app.py:33
|
#: applications/serializers/attrs/application_category/remote_app.py:33
|
||||||
#: assets/models/asset.py:355 assets/models/authbook.py:26
|
#: assets/models/asset.py:355 assets/models/authbook.py:26
|
||||||
#: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:29
|
#: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:30
|
||||||
#: assets/serializers/asset_user.py:47 assets/serializers/asset_user.py:84
|
#: assets/serializers/asset_user.py:47 assets/serializers/asset_user.py:84
|
||||||
#: assets/serializers/system_user.py:191 audits/models.py:38
|
#: assets/serializers/system_user.py:192 audits/models.py:38
|
||||||
#: perms/models/asset_permission.py:99 templates/index.html:82
|
#: perms/models/asset_permission.py:99 templates/index.html:82
|
||||||
#: terminal/backends/command/models.py:19
|
#: terminal/backends/command/models.py:19
|
||||||
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:39
|
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:39
|
||||||
|
@ -192,7 +192,7 @@ msgstr "IP 地址无效: `{}`"
|
||||||
msgid "IP"
|
msgid "IP"
|
||||||
msgstr "IP"
|
msgstr "IP"
|
||||||
|
|
||||||
#: acls/serializers/login_acl.py:41
|
#: acls/serializers/login_acl.py:45
|
||||||
msgid "The user `{}` is not in the current organization: `{}`"
|
msgid "The user `{}` is not in the current organization: `{}`"
|
||||||
msgstr "用户 `{}` 不在当前组织: `{}`"
|
msgstr "用户 `{}` 不在当前组织: `{}`"
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ msgid "Hostname"
|
||||||
msgstr "主机名"
|
msgstr "主机名"
|
||||||
|
|
||||||
#: acls/serializers/login_asset_acl.py:41 assets/models/asset.py:187
|
#: acls/serializers/login_asset_acl.py:41 assets/models/asset.py:187
|
||||||
#: assets/models/domain.py:54 assets/models/user.py:120
|
#: assets/models/domain.py:54 assets/models/user.py:123
|
||||||
#: terminal/serializers/session.py:29 terminal/serializers/storage.py:69
|
#: terminal/serializers/session.py:29 terminal/serializers/storage.py:69
|
||||||
msgid "Protocol"
|
msgid "Protocol"
|
||||||
msgstr "协议"
|
msgstr "协议"
|
||||||
|
@ -241,12 +241,12 @@ msgstr "协议选项: {}"
|
||||||
msgid "Unsupported protocols: {}"
|
msgid "Unsupported protocols: {}"
|
||||||
msgstr "不支持的协议: {}"
|
msgstr "不支持的协议: {}"
|
||||||
|
|
||||||
#: acls/serializers/login_asset_acl.py:78
|
#: acls/serializers/login_asset_acl.py:80
|
||||||
#: tickets/serializers/ticket/ticket.py:109
|
#: tickets/serializers/ticket/ticket.py:109
|
||||||
msgid "The organization `{}` does not exist"
|
msgid "The organization `{}` does not exist"
|
||||||
msgstr "组织 `{}` 不存在"
|
msgstr "组织 `{}` 不存在"
|
||||||
|
|
||||||
#: acls/serializers/login_asset_acl.py:83
|
#: acls/serializers/login_asset_acl.py:85
|
||||||
msgid "None of the reviewers belong to Organization `{}`"
|
msgid "None of the reviewers belong to Organization `{}`"
|
||||||
msgstr "所有复核人都不属于组织 `{}`"
|
msgstr "所有复核人都不属于组织 `{}`"
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ msgstr "类别"
|
||||||
#: perms/models/application_permission.py:23
|
#: perms/models/application_permission.py:23
|
||||||
#: perms/serializers/application/permission.py:17
|
#: perms/serializers/application/permission.py:17
|
||||||
#: perms/serializers/application/user_permission.py:34
|
#: perms/serializers/application/user_permission.py:34
|
||||||
#: terminal/models/storage.py:26 terminal/models/storage.py:78
|
#: terminal/models/storage.py:26 terminal/models/storage.py:84
|
||||||
#: tickets/models/ticket.py:38
|
#: tickets/models/ticket.py:38
|
||||||
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:27
|
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:27
|
||||||
#: users/templates/users/user_granted_database_app.html:35
|
#: users/templates/users/user_granted_database_app.html:35
|
||||||
|
@ -335,7 +335,7 @@ msgstr "目标URL"
|
||||||
#: applications/serializers/attrs/application_type/vmware_client.py:30
|
#: applications/serializers/attrs/application_type/vmware_client.py:30
|
||||||
#: assets/models/base.py:252 assets/serializers/asset_user.py:71
|
#: assets/models/base.py:252 assets/serializers/asset_user.py:71
|
||||||
#: audits/signals_handler.py:46 authentication/forms.py:22
|
#: audits/signals_handler.py:46 authentication/forms.py:22
|
||||||
#: authentication/templates/authentication/login.html:148
|
#: authentication/templates/authentication/login.html:155
|
||||||
#: settings/serializers/settings.py:89 users/forms/profile.py:21
|
#: settings/serializers/settings.py:89 users/forms/profile.py:21
|
||||||
#: users/templates/users/user_otp_check_password.html:13
|
#: users/templates/users/user_otp_check_password.html:13
|
||||||
#: users/templates/users/user_password_update.html:43
|
#: users/templates/users/user_password_update.html:43
|
||||||
|
@ -394,7 +394,8 @@ msgstr "基础"
|
||||||
msgid "Charset"
|
msgid "Charset"
|
||||||
msgstr "编码"
|
msgstr "编码"
|
||||||
|
|
||||||
#: assets/models/asset.py:145 tickets/models/ticket.py:40
|
#: assets/models/asset.py:145 assets/serializers/asset.py:171
|
||||||
|
#: tickets/models/ticket.py:40
|
||||||
msgid "Meta"
|
msgid "Meta"
|
||||||
msgstr "元数据"
|
msgstr "元数据"
|
||||||
|
|
||||||
|
@ -412,7 +413,7 @@ msgstr "系统平台"
|
||||||
msgid "Protocols"
|
msgid "Protocols"
|
||||||
msgstr "协议组"
|
msgstr "协议组"
|
||||||
|
|
||||||
#: assets/models/asset.py:192 assets/models/user.py:115
|
#: assets/models/asset.py:192 assets/models/user.py:118
|
||||||
#: perms/models/asset_permission.py:100
|
#: perms/models/asset_permission.py:100
|
||||||
#: xpack/plugins/change_auth_plan/models.py:56
|
#: xpack/plugins/change_auth_plan/models.py:56
|
||||||
#: xpack/plugins/gathered_user/models.py:24
|
#: xpack/plugins/gathered_user/models.py:24
|
||||||
|
@ -503,7 +504,7 @@ msgstr "标签管理"
|
||||||
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:26
|
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:26
|
||||||
#: assets/models/cmd_filter.py:60 assets/models/group.py:21
|
#: assets/models/cmd_filter.py:60 assets/models/group.py:21
|
||||||
#: common/db/models.py:70 common/mixins/models.py:49 orgs/models.py:24
|
#: common/db/models.py:70 common/mixins/models.py:49 orgs/models.py:24
|
||||||
#: orgs/models.py:407 perms/models/base.py:55 users/models/user.py:571
|
#: orgs/models.py:421 perms/models/base.py:55 users/models/user.py:571
|
||||||
#: users/serializers/group.py:35 users/templates/users/user_detail.html:97
|
#: users/serializers/group.py:35 users/templates/users/user_detail.html:97
|
||||||
#: xpack/plugins/change_auth_plan/models.py:81
|
#: xpack/plugins/change_auth_plan/models.py:81
|
||||||
#: xpack/plugins/cloud/models.py:104 xpack/plugins/gathered_user/models.py:30
|
#: xpack/plugins/cloud/models.py:104 xpack/plugins/gathered_user/models.py:30
|
||||||
|
@ -517,7 +518,7 @@ msgstr "创建者"
|
||||||
#: assets/models/gathered_user.py:19 assets/models/group.py:22
|
#: assets/models/gathered_user.py:19 assets/models/group.py:22
|
||||||
#: assets/models/label.py:25 common/db/models.py:72 common/mixins/models.py:50
|
#: assets/models/label.py:25 common/db/models.py:72 common/mixins/models.py:50
|
||||||
#: ops/models/adhoc.py:38 ops/models/command.py:29 orgs/models.py:25
|
#: ops/models/adhoc.py:38 ops/models/command.py:29 orgs/models.py:25
|
||||||
#: orgs/models.py:405 perms/models/base.py:56 users/models/group.py:18
|
#: orgs/models.py:419 perms/models/base.py:56 users/models/group.py:18
|
||||||
#: users/templates/users/user_group_detail.html:58
|
#: users/templates/users/user_group_detail.html:58
|
||||||
#: xpack/plugins/cloud/models.py:107
|
#: xpack/plugins/cloud/models.py:107
|
||||||
msgid "Date created"
|
msgid "Date created"
|
||||||
|
@ -553,7 +554,7 @@ msgstr "SSH公钥"
|
||||||
|
|
||||||
#: assets/models/base.py:257 assets/models/gathered_user.py:20
|
#: assets/models/base.py:257 assets/models/gathered_user.py:20
|
||||||
#: common/db/models.py:73 common/mixins/models.py:51 ops/models/adhoc.py:39
|
#: common/db/models.py:73 common/mixins/models.py:51 ops/models/adhoc.py:39
|
||||||
#: orgs/models.py:406
|
#: orgs/models.py:420
|
||||||
msgid "Date updated"
|
msgid "Date updated"
|
||||||
msgstr "更新日期"
|
msgstr "更新日期"
|
||||||
|
|
||||||
|
@ -591,7 +592,7 @@ msgid "Default"
|
||||||
msgstr "默认"
|
msgstr "默认"
|
||||||
|
|
||||||
#: assets/models/cluster.py:36 assets/models/label.py:14
|
#: assets/models/cluster.py:36 assets/models/label.py:14
|
||||||
#: users/models/user.py:689
|
#: users/models/user.py:711
|
||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "系统"
|
msgstr "系统"
|
||||||
|
|
||||||
|
@ -599,7 +600,7 @@ msgstr "系统"
|
||||||
msgid "Default Cluster"
|
msgid "Default Cluster"
|
||||||
msgstr "默认Cluster"
|
msgstr "默认Cluster"
|
||||||
|
|
||||||
#: assets/models/cmd_filter.py:33 assets/models/user.py:125
|
#: assets/models/cmd_filter.py:33 assets/models/user.py:128
|
||||||
msgid "Command filter"
|
msgid "Command filter"
|
||||||
msgstr "命令过滤器"
|
msgstr "命令过滤器"
|
||||||
|
|
||||||
|
@ -664,7 +665,7 @@ msgstr "资产组"
|
||||||
msgid "Default asset group"
|
msgid "Default asset group"
|
||||||
msgstr "默认资产组"
|
msgstr "默认资产组"
|
||||||
|
|
||||||
#: assets/models/label.py:19 assets/models/node.py:575 settings/models.py:30
|
#: assets/models/label.py:19 assets/models/node.py:538 settings/models.py:30
|
||||||
msgid "Value"
|
msgid "Value"
|
||||||
msgstr "值"
|
msgstr "值"
|
||||||
|
|
||||||
|
@ -672,23 +673,23 @@ msgstr "值"
|
||||||
msgid "New node"
|
msgid "New node"
|
||||||
msgstr "新节点"
|
msgstr "新节点"
|
||||||
|
|
||||||
#: assets/models/node.py:467 users/templates/users/_granted_assets.html:130
|
#: assets/models/node.py:466 users/templates/users/_granted_assets.html:130
|
||||||
msgid "empty"
|
msgid "empty"
|
||||||
msgstr "空"
|
msgstr "空"
|
||||||
|
|
||||||
#: assets/models/node.py:574 perms/models/asset_permission.py:156
|
#: assets/models/node.py:537 perms/models/asset_permission.py:156
|
||||||
msgid "Key"
|
msgid "Key"
|
||||||
msgstr "键"
|
msgstr "键"
|
||||||
|
|
||||||
#: assets/models/node.py:576
|
#: assets/models/node.py:539
|
||||||
msgid "Full value"
|
msgid "Full value"
|
||||||
msgstr "全称"
|
msgstr "全称"
|
||||||
|
|
||||||
#: assets/models/node.py:579 perms/models/asset_permission.py:157
|
#: assets/models/node.py:542 perms/models/asset_permission.py:157
|
||||||
msgid "Parent key"
|
msgid "Parent key"
|
||||||
msgstr "ssh私钥"
|
msgstr "ssh私钥"
|
||||||
|
|
||||||
#: assets/models/node.py:588 assets/serializers/system_user.py:190
|
#: assets/models/node.py:551 assets/serializers/system_user.py:191
|
||||||
#: users/templates/users/user_asset_permission.html:41
|
#: users/templates/users/user_asset_permission.html:41
|
||||||
#: users/templates/users/user_asset_permission.html:73
|
#: users/templates/users/user_asset_permission.html:73
|
||||||
#: users/templates/users/user_asset_permission.html:158
|
#: users/templates/users/user_asset_permission.html:158
|
||||||
|
@ -696,66 +697,66 @@ msgstr "ssh私钥"
|
||||||
msgid "Node"
|
msgid "Node"
|
||||||
msgstr "节点"
|
msgstr "节点"
|
||||||
|
|
||||||
#: assets/models/user.py:111
|
#: assets/models/user.py:114
|
||||||
msgid "Automatic login"
|
msgid "Automatic login"
|
||||||
msgstr "自动登录"
|
msgstr "自动登录"
|
||||||
|
|
||||||
#: assets/models/user.py:112
|
#: assets/models/user.py:115
|
||||||
msgid "Manually login"
|
msgid "Manually login"
|
||||||
msgstr "手动登录"
|
msgstr "手动登录"
|
||||||
|
|
||||||
#: assets/models/user.py:114
|
#: assets/models/user.py:117
|
||||||
msgid "Username same with user"
|
msgid "Username same with user"
|
||||||
msgstr "用户名与用户相同"
|
msgstr "用户名与用户相同"
|
||||||
|
|
||||||
#: assets/models/user.py:116 assets/serializers/domain.py:30
|
#: assets/models/user.py:119 assets/serializers/domain.py:30
|
||||||
#: templates/_nav.html:39 xpack/plugins/change_auth_plan/models.py:52
|
#: templates/_nav.html:39 xpack/plugins/change_auth_plan/models.py:52
|
||||||
msgid "Assets"
|
msgid "Assets"
|
||||||
msgstr "资产"
|
msgstr "资产"
|
||||||
|
|
||||||
#: assets/models/user.py:117 templates/_nav.html:17
|
#: assets/models/user.py:120 templates/_nav.html:17
|
||||||
#: users/views/profile/password.py:42 users/views/profile/pubkey.py:36
|
#: users/views/profile/password.py:42 users/views/profile/pubkey.py:36
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr "用户管理"
|
msgstr "用户管理"
|
||||||
|
|
||||||
#: assets/models/user.py:118 users/templates/users/user_group_list.html:90
|
#: assets/models/user.py:121 users/templates/users/user_group_list.html:90
|
||||||
#: users/templates/users/user_profile.html:124
|
#: users/templates/users/user_profile.html:124
|
||||||
msgid "User groups"
|
msgid "User groups"
|
||||||
msgstr "用户组"
|
msgstr "用户组"
|
||||||
|
|
||||||
#: assets/models/user.py:121
|
#: assets/models/user.py:124
|
||||||
msgid "Auto push"
|
msgid "Auto push"
|
||||||
msgstr "自动推送"
|
msgstr "自动推送"
|
||||||
|
|
||||||
#: assets/models/user.py:122
|
#: assets/models/user.py:125
|
||||||
msgid "Sudo"
|
msgid "Sudo"
|
||||||
msgstr "Sudo"
|
msgstr "Sudo"
|
||||||
|
|
||||||
#: assets/models/user.py:123
|
#: assets/models/user.py:126
|
||||||
msgid "Shell"
|
msgid "Shell"
|
||||||
msgstr "Shell"
|
msgstr "Shell"
|
||||||
|
|
||||||
#: assets/models/user.py:124
|
#: assets/models/user.py:127
|
||||||
msgid "Login mode"
|
msgid "Login mode"
|
||||||
msgstr "登录模式"
|
msgstr "登录模式"
|
||||||
|
|
||||||
#: assets/models/user.py:126
|
#: assets/models/user.py:129
|
||||||
msgid "SFTP Root"
|
msgid "SFTP Root"
|
||||||
msgstr "SFTP根路径"
|
msgstr "SFTP根路径"
|
||||||
|
|
||||||
#: assets/models/user.py:127 authentication/models.py:93
|
#: assets/models/user.py:130 authentication/models.py:95
|
||||||
msgid "Token"
|
msgid "Token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/models/user.py:128
|
#: assets/models/user.py:131
|
||||||
msgid "Home"
|
msgid "Home"
|
||||||
msgstr "家目录"
|
msgstr "家目录"
|
||||||
|
|
||||||
#: assets/models/user.py:129
|
#: assets/models/user.py:132
|
||||||
msgid "System groups"
|
msgid "System groups"
|
||||||
msgstr "用户组"
|
msgstr "用户组"
|
||||||
|
|
||||||
#: assets/models/user.py:221 audits/models.py:39
|
#: assets/models/user.py:228 audits/models.py:39
|
||||||
#: perms/models/application_permission.py:31
|
#: perms/models/application_permission.py:31
|
||||||
#: perms/models/asset_permission.py:101 templates/_nav.html:45
|
#: perms/models/asset_permission.py:101 templates/_nav.html:45
|
||||||
#: terminal/backends/command/models.py:20
|
#: terminal/backends/command/models.py:20
|
||||||
|
@ -858,6 +859,17 @@ msgstr "应用数量"
|
||||||
msgid "Gateways count"
|
msgid "Gateways count"
|
||||||
msgstr "网关数量"
|
msgstr "网关数量"
|
||||||
|
|
||||||
|
#: assets/serializers/label.py:13 assets/serializers/system_user.py:45
|
||||||
|
#: assets/serializers/system_user.py:166
|
||||||
|
#: perms/serializers/asset/permission.py:66
|
||||||
|
msgid "Assets amount"
|
||||||
|
msgstr "资产数量"
|
||||||
|
|
||||||
|
#: assets/serializers/label.py:14
|
||||||
|
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:24
|
||||||
|
msgid "Category display"
|
||||||
|
msgstr "类别 (显示名称)"
|
||||||
|
|
||||||
#: assets/serializers/node.py:18
|
#: assets/serializers/node.py:18
|
||||||
msgid "value"
|
msgid "value"
|
||||||
msgstr "值"
|
msgstr "值"
|
||||||
|
@ -870,22 +882,17 @@ msgstr "不能包含: /"
|
||||||
msgid "The same level node name cannot be the same"
|
msgid "The same level node name cannot be the same"
|
||||||
msgstr "同级别节点名字不能重复"
|
msgstr "同级别节点名字不能重复"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:44 assets/serializers/system_user.py:164
|
#: assets/serializers/system_user.py:44 assets/serializers/system_user.py:165
|
||||||
#: perms/serializers/asset/permission.py:67
|
#: perms/serializers/asset/permission.py:67
|
||||||
msgid "Nodes amount"
|
msgid "Nodes amount"
|
||||||
msgstr "节点数量"
|
msgstr "节点数量"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:45 assets/serializers/system_user.py:165
|
#: assets/serializers/system_user.py:46 assets/serializers/system_user.py:167
|
||||||
#: perms/serializers/asset/permission.py:66
|
#: assets/serializers/system_user.py:193
|
||||||
msgid "Assets amount"
|
|
||||||
msgstr "资产数量"
|
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:46 assets/serializers/system_user.py:166
|
|
||||||
#: assets/serializers/system_user.py:192
|
|
||||||
msgid "Login mode display"
|
msgid "Login mode display"
|
||||||
msgstr "登录模式(显示名称)"
|
msgstr "登录模式(显示名称)"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:48 assets/serializers/system_user.py:168
|
#: assets/serializers/system_user.py:48 assets/serializers/system_user.py:169
|
||||||
msgid "Ad domain"
|
msgid "Ad domain"
|
||||||
msgstr "Ad 网域"
|
msgstr "Ad 网域"
|
||||||
|
|
||||||
|
@ -1008,17 +1015,11 @@ msgstr "资产已经被禁用, 跳过: {}"
|
||||||
msgid "Asset may not be support ansible, skipped: {}"
|
msgid "Asset may not be support ansible, skipped: {}"
|
||||||
msgstr "资产或许不支持ansible, 跳过: {}"
|
msgstr "资产或许不支持ansible, 跳过: {}"
|
||||||
|
|
||||||
#: assets/tasks/utils.py:29
|
#: assets/tasks/utils.py:39
|
||||||
msgid ""
|
|
||||||
"Push system user task skip, auto push not enable or protocol is not ssh or "
|
|
||||||
"rdp: {}"
|
|
||||||
msgstr "推送系统用户任务跳过,自动推送没有打开,或协议不是ssh或rdp: {}"
|
|
||||||
|
|
||||||
#: assets/tasks/utils.py:36
|
|
||||||
msgid "For security, do not push user {}"
|
msgid "For security, do not push user {}"
|
||||||
msgstr "为了安全,禁止推送用户 {}"
|
msgstr "为了安全,禁止推送用户 {}"
|
||||||
|
|
||||||
#: assets/tasks/utils.py:56
|
#: assets/tasks/utils.py:55
|
||||||
msgid "No assets matched, stop task"
|
msgid "No assets matched, stop task"
|
||||||
msgstr "没有匹配到资产,结束任务"
|
msgstr "没有匹配到资产,结束任务"
|
||||||
|
|
||||||
|
@ -1165,7 +1166,7 @@ msgstr "用户代理"
|
||||||
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
|
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
|
||||||
#: authentication/templates/authentication/login_otp.html:6
|
#: authentication/templates/authentication/login_otp.html:6
|
||||||
#: users/forms/profile.py:64 users/models/user.py:552
|
#: users/forms/profile.py:64 users/models/user.py:552
|
||||||
#: users/serializers/profile.py:102 users/templates/users/user_detail.html:77
|
#: users/serializers/profile.py:99 users/templates/users/user_detail.html:77
|
||||||
#: users/templates/users/user_profile.html:87
|
#: users/templates/users/user_profile.html:87
|
||||||
msgid "MFA"
|
msgid "MFA"
|
||||||
msgstr "多因子认证"
|
msgstr "多因子认证"
|
||||||
|
@ -1204,29 +1205,33 @@ msgstr "状态(显示名称)"
|
||||||
msgid "MFA for display"
|
msgid "MFA for display"
|
||||||
msgstr "多因子认证状态(显示名称)"
|
msgstr "多因子认证状态(显示名称)"
|
||||||
|
|
||||||
#: audits/serializers.py:66 audits/serializers.py:78 ops/models/adhoc.py:247
|
#: audits/serializers.py:66 audits/serializers.py:81 ops/models/adhoc.py:247
|
||||||
#: terminal/serializers/session.py:34
|
#: terminal/serializers/session.py:34
|
||||||
msgid "Is success"
|
msgid "Is success"
|
||||||
msgstr "是否成功"
|
msgstr "是否成功"
|
||||||
|
|
||||||
#: audits/serializers.py:77 ops/models/command.py:26
|
#: audits/serializers.py:68
|
||||||
|
msgid "Hosts for display"
|
||||||
|
msgstr "主机 (显示名称)"
|
||||||
|
|
||||||
|
#: audits/serializers.py:80 ops/models/command.py:26
|
||||||
#: xpack/plugins/cloud/models.py:155
|
#: xpack/plugins/cloud/models.py:155
|
||||||
msgid "Result"
|
msgid "Result"
|
||||||
msgstr "结果"
|
msgstr "结果"
|
||||||
|
|
||||||
#: audits/serializers.py:79 terminal/serializers/storage.py:178
|
#: audits/serializers.py:82 terminal/serializers/storage.py:178
|
||||||
msgid "Hosts"
|
msgid "Hosts"
|
||||||
msgstr "主机"
|
msgstr "主机"
|
||||||
|
|
||||||
#: audits/serializers.py:80
|
#: audits/serializers.py:83
|
||||||
msgid "Run as"
|
msgid "Run as"
|
||||||
msgstr "运行用户"
|
msgstr "运行用户"
|
||||||
|
|
||||||
#: audits/serializers.py:82
|
#: audits/serializers.py:85
|
||||||
msgid "Run as for display"
|
msgid "Run as for display"
|
||||||
msgstr "运行用户(显示名称)"
|
msgstr "运行用户(显示名称)"
|
||||||
|
|
||||||
#: audits/serializers.py:83
|
#: audits/serializers.py:86
|
||||||
msgid "User for display"
|
msgid "User for display"
|
||||||
msgstr "用户(显示名称)"
|
msgstr "用户(显示名称)"
|
||||||
|
|
||||||
|
@ -1349,8 +1354,8 @@ msgid ""
|
||||||
"after {} minutes)"
|
"after {} minutes)"
|
||||||
msgstr "账号已被锁定(请联系管理员解锁 或 {}分钟后重试)"
|
msgstr "账号已被锁定(请联系管理员解锁 或 {}分钟后重试)"
|
||||||
|
|
||||||
#: authentication/errors.py:55 users/views/profile/otp.py:110
|
#: authentication/errors.py:55 users/views/profile/otp.py:107
|
||||||
#: users/views/profile/otp.py:149 users/views/profile/otp.py:169
|
#: users/views/profile/otp.py:146 users/views/profile/otp.py:166
|
||||||
msgid "MFA code invalid, or ntp sync server time"
|
msgid "MFA code invalid, or ntp sync server time"
|
||||||
msgstr "MFA验证码不正确,或者服务器端时间不对"
|
msgstr "MFA验证码不正确,或者服务器端时间不对"
|
||||||
|
|
||||||
|
@ -1399,7 +1404,7 @@ msgstr "多因子认证验证码"
|
||||||
msgid "Private Token"
|
msgid "Private Token"
|
||||||
msgstr "SSH密钥"
|
msgstr "SSH密钥"
|
||||||
|
|
||||||
#: authentication/models.py:94
|
#: authentication/models.py:96
|
||||||
msgid "Expired"
|
msgid "Expired"
|
||||||
msgstr "过期时间"
|
msgstr "过期时间"
|
||||||
|
|
||||||
|
@ -1429,7 +1434,7 @@ msgid "Show"
|
||||||
msgstr "显示"
|
msgstr "显示"
|
||||||
|
|
||||||
#: authentication/templates/authentication/_access_key_modal.html:66
|
#: authentication/templates/authentication/_access_key_modal.html:66
|
||||||
#: users/models/user.py:445 users/serializers/profile.py:99
|
#: users/models/user.py:445 users/serializers/profile.py:96
|
||||||
#: users/templates/users/user_profile.html:94
|
#: users/templates/users/user_profile.html:94
|
||||||
#: users/templates/users/user_profile.html:163
|
#: users/templates/users/user_profile.html:163
|
||||||
#: users/templates/users/user_profile.html:166
|
#: users/templates/users/user_profile.html:166
|
||||||
|
@ -1438,7 +1443,7 @@ msgid "Disable"
|
||||||
msgstr "禁用"
|
msgstr "禁用"
|
||||||
|
|
||||||
#: authentication/templates/authentication/_access_key_modal.html:67
|
#: authentication/templates/authentication/_access_key_modal.html:67
|
||||||
#: users/models/user.py:446 users/serializers/profile.py:100
|
#: users/models/user.py:446 users/serializers/profile.py:97
|
||||||
#: users/templates/users/user_profile.html:92
|
#: users/templates/users/user_profile.html:92
|
||||||
#: users/templates/users/user_profile.html:170
|
#: users/templates/users/user_profile.html:170
|
||||||
msgid "Enable"
|
msgid "Enable"
|
||||||
|
@ -1487,30 +1492,30 @@ msgstr "确认"
|
||||||
msgid "Code error"
|
msgid "Code error"
|
||||||
msgstr "代码错误"
|
msgstr "代码错误"
|
||||||
|
|
||||||
#: authentication/templates/authentication/login.html:141
|
#: authentication/templates/authentication/login.html:148
|
||||||
msgid "Welcome back, please enter username and password to login"
|
msgid "Welcome back, please enter username and password to login"
|
||||||
msgstr "欢迎回来,请输入用户名和密码登录"
|
msgstr "欢迎回来,请输入用户名和密码登录"
|
||||||
|
|
||||||
#: authentication/templates/authentication/login.html:167
|
#: authentication/templates/authentication/login.html:174
|
||||||
#: users/templates/users/forgot_password.html:15
|
#: users/templates/users/forgot_password.html:15
|
||||||
#: users/templates/users/forgot_password.html:16
|
#: users/templates/users/forgot_password.html:16
|
||||||
msgid "Forgot password"
|
msgid "Forgot password"
|
||||||
msgstr "忘记密码"
|
msgstr "忘记密码"
|
||||||
|
|
||||||
#: authentication/templates/authentication/login.html:174
|
#: authentication/templates/authentication/login.html:181
|
||||||
#: templates/_header_bar.html:83
|
#: templates/_header_bar.html:83
|
||||||
msgid "Login"
|
msgid "Login"
|
||||||
msgstr "登录"
|
msgstr "登录"
|
||||||
|
|
||||||
#: authentication/templates/authentication/login.html:181
|
#: authentication/templates/authentication/login.html:188
|
||||||
msgid "More login options"
|
msgid "More login options"
|
||||||
msgstr "更多登录方式"
|
msgstr "更多登录方式"
|
||||||
|
|
||||||
#: authentication/templates/authentication/login.html:184
|
#: authentication/templates/authentication/login.html:191
|
||||||
msgid "OpenID"
|
msgid "OpenID"
|
||||||
msgstr "OpenID"
|
msgstr "OpenID"
|
||||||
|
|
||||||
#: authentication/templates/authentication/login.html:189
|
#: authentication/templates/authentication/login.html:196
|
||||||
msgid "CAS"
|
msgid "CAS"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1833,15 +1838,15 @@ msgstr "{} 任务结束"
|
||||||
msgid "Date finished"
|
msgid "Date finished"
|
||||||
msgstr "结束日期"
|
msgstr "结束日期"
|
||||||
|
|
||||||
#: ops/models/command.py:74
|
#: ops/models/command.py:78
|
||||||
msgid "Task start"
|
msgid "Task start"
|
||||||
msgstr "任务开始"
|
msgstr "任务开始"
|
||||||
|
|
||||||
#: ops/models/command.py:96
|
#: ops/models/command.py:100
|
||||||
msgid "Command `{}` is forbidden ........"
|
msgid "Command `{}` is forbidden ........"
|
||||||
msgstr "命令 `{}` 不允许被执行 ......."
|
msgstr "命令 `{}` 不允许被执行 ......."
|
||||||
|
|
||||||
#: ops/models/command.py:109
|
#: ops/models/command.py:113
|
||||||
msgid "Task end"
|
msgid "Task end"
|
||||||
msgstr "任务结束"
|
msgstr "任务结束"
|
||||||
|
|
||||||
|
@ -1865,16 +1870,21 @@ msgstr "更新任务内容: {}"
|
||||||
msgid "Disk used more than 80%: {} => {}"
|
msgid "Disk used more than 80%: {} => {}"
|
||||||
msgstr "磁盘使用率超过 80%: {} => {}"
|
msgstr "磁盘使用率超过 80%: {} => {}"
|
||||||
|
|
||||||
#: orgs/api.py:64
|
#: orgs/api.py:76
|
||||||
msgid "Organization contains undeleted resources"
|
#, python-brace-format
|
||||||
msgstr "组织包含未删除的资源"
|
msgid "Have `{model._meta.verbose_name}` exists, Please delete"
|
||||||
|
msgstr "`{model._meta.verbose_name}` 存在数据, 请先删除"
|
||||||
|
|
||||||
#: orgs/api.py:68
|
#: orgs/api.py:80
|
||||||
msgid "The current organization cannot be deleted"
|
msgid "The current organization cannot be deleted"
|
||||||
msgstr "当前组织不能被删除"
|
msgstr "当前组织不能被删除"
|
||||||
|
|
||||||
|
#: orgs/mixins/api.py:46
|
||||||
|
msgid "Root organization only allow view and delete"
|
||||||
|
msgstr "全局组织仅支持 查看和删除"
|
||||||
|
|
||||||
#: orgs/mixins/models.py:45 orgs/mixins/serializers.py:25 orgs/models.py:36
|
#: orgs/mixins/models.py:45 orgs/mixins/serializers.py:25 orgs/models.py:36
|
||||||
#: orgs/models.py:402 orgs/serializers.py:101
|
#: orgs/models.py:416 orgs/serializers.py:101
|
||||||
#: tickets/serializers/ticket/ticket.py:81
|
#: tickets/serializers/ticket/ticket.py:81
|
||||||
msgid "Organization"
|
msgid "Organization"
|
||||||
msgstr "组织"
|
msgstr "组织"
|
||||||
|
@ -1891,7 +1901,7 @@ msgstr "组织审计员"
|
||||||
msgid "GLOBAL"
|
msgid "GLOBAL"
|
||||||
msgstr "全局组织"
|
msgstr "全局组织"
|
||||||
|
|
||||||
#: orgs/models.py:404 users/models/user.py:540
|
#: orgs/models.py:418 users/models/user.py:540
|
||||||
#: users/templates/users/_select_user_modal.html:15
|
#: users/templates/users/_select_user_modal.html:15
|
||||||
#: users/templates/users/user_detail.html:73
|
#: users/templates/users/user_detail.html:73
|
||||||
#: users/templates/users/user_list.html:16
|
#: users/templates/users/user_list.html:16
|
||||||
|
@ -1899,14 +1909,6 @@ msgstr "全局组织"
|
||||||
msgid "Role"
|
msgid "Role"
|
||||||
msgstr "角色"
|
msgstr "角色"
|
||||||
|
|
||||||
#: perms/const.py:7 perms/models/asset_permission.py:189
|
|
||||||
msgid "Ungrouped"
|
|
||||||
msgstr "未分组"
|
|
||||||
|
|
||||||
#: perms/const.py:10
|
|
||||||
msgid "Empty"
|
|
||||||
msgstr "空"
|
|
||||||
|
|
||||||
#: perms/exceptions.py:9
|
#: perms/exceptions.py:9
|
||||||
msgid "The administrator is modifying permissions. Please wait"
|
msgid "The administrator is modifying permissions. Please wait"
|
||||||
msgstr "管理员正在修改授权,请稍等"
|
msgstr "管理员正在修改授权,请稍等"
|
||||||
|
@ -1965,6 +1967,10 @@ msgstr "动作"
|
||||||
msgid "Asset permission"
|
msgid "Asset permission"
|
||||||
msgstr "资产授权"
|
msgstr "资产授权"
|
||||||
|
|
||||||
|
#: perms/models/asset_permission.py:189
|
||||||
|
msgid "Ungrouped"
|
||||||
|
msgstr "未分组"
|
||||||
|
|
||||||
#: perms/models/asset_permission.py:191
|
#: perms/models/asset_permission.py:191
|
||||||
msgid "Favorite"
|
msgid "Favorite"
|
||||||
msgstr "收藏夹"
|
msgstr "收藏夹"
|
||||||
|
@ -1998,11 +2004,13 @@ msgid ""
|
||||||
"permission type. ({})"
|
"permission type. ({})"
|
||||||
msgstr "应用列表中包含与授权类型不同的应用。({})"
|
msgstr "应用列表中包含与授权类型不同的应用。({})"
|
||||||
|
|
||||||
#: perms/serializers/asset/permission.py:61 users/serializers/user.py:67
|
#: perms/serializers/asset/permission.py:43
|
||||||
|
#: perms/serializers/asset/permission.py:61 users/serializers/user.py:34
|
||||||
|
#: users/serializers/user.py:69
|
||||||
msgid "Is expired"
|
msgid "Is expired"
|
||||||
msgstr "是否过期"
|
msgstr "是否过期"
|
||||||
|
|
||||||
#: perms/serializers/asset/permission.py:62 users/serializers/user.py:66
|
#: perms/serializers/asset/permission.py:62 users/serializers/user.py:68
|
||||||
msgid "Is valid"
|
msgid "Is valid"
|
||||||
msgstr "账户是否有效"
|
msgstr "账户是否有效"
|
||||||
|
|
||||||
|
@ -2018,11 +2026,11 @@ msgstr "用户组数量"
|
||||||
msgid "System users amount"
|
msgid "System users amount"
|
||||||
msgstr "系统用户数量"
|
msgstr "系统用户数量"
|
||||||
|
|
||||||
#: settings/api/common.py:24
|
#: settings/api/common.py:25
|
||||||
msgid "Test mail sent to {}, please check"
|
msgid "Test mail sent to {}, please check"
|
||||||
msgstr "邮件已经发送{}, 请检查"
|
msgstr "邮件已经发送{}, 请检查"
|
||||||
|
|
||||||
#: settings/api/common.py:110 xpack/plugins/interface/api.py:18
|
#: settings/api/common.py:100 xpack/plugins/interface/api.py:18
|
||||||
#: xpack/plugins/interface/models.py:36
|
#: xpack/plugins/interface/models.py:36
|
||||||
msgid "Welcome to the JumpServer open source Bastion Host"
|
msgid "Welcome to the JumpServer open source Bastion Host"
|
||||||
msgstr "欢迎使用JumpServer开源堡垒机"
|
msgstr "欢迎使用JumpServer开源堡垒机"
|
||||||
|
@ -2910,19 +2918,23 @@ msgstr "不允许删除默认存储配置"
|
||||||
msgid "Cannot delete storage that is being used"
|
msgid "Cannot delete storage that is being used"
|
||||||
msgstr "不允许删除正在使用的存储配置"
|
msgstr "不允许删除正在使用的存储配置"
|
||||||
|
|
||||||
#: terminal/api/storage.py:66 terminal/api/storage.py:67
|
#: terminal/api/storage.py:72 terminal/api/storage.py:73
|
||||||
msgid "Command storages"
|
msgid "Command storages"
|
||||||
msgstr "命令存储"
|
msgstr "命令存储"
|
||||||
|
|
||||||
#: terminal/api/storage.py:104
|
#: terminal/api/storage.py:79
|
||||||
|
msgid "Invalid"
|
||||||
|
msgstr "无效"
|
||||||
|
|
||||||
|
#: terminal/api/storage.py:122
|
||||||
msgid "Test failure: {}"
|
msgid "Test failure: {}"
|
||||||
msgstr "测试失败: {}"
|
msgstr "测试失败: {}"
|
||||||
|
|
||||||
#: terminal/api/storage.py:107
|
#: terminal/api/storage.py:125
|
||||||
msgid "Test successful"
|
msgid "Test successful"
|
||||||
msgstr "测试成功"
|
msgstr "测试成功"
|
||||||
|
|
||||||
#: terminal/api/storage.py:109
|
#: terminal/api/storage.py:127
|
||||||
msgid "Test failure: Account invalid"
|
msgid "Test failure: Account invalid"
|
||||||
msgstr "测试失败: 账户无效"
|
msgstr "测试失败: 账户无效"
|
||||||
|
|
||||||
|
@ -2983,6 +2995,10 @@ msgstr "正常"
|
||||||
msgid "Bulk create not support"
|
msgid "Bulk create not support"
|
||||||
msgstr "不支持批量创建"
|
msgstr "不支持批量创建"
|
||||||
|
|
||||||
|
#: terminal/exceptions.py:13
|
||||||
|
msgid "Storage is invalid"
|
||||||
|
msgstr "存储无效"
|
||||||
|
|
||||||
#: terminal/models/session.py:43
|
#: terminal/models/session.py:43
|
||||||
msgid "Login from"
|
msgid "Login from"
|
||||||
msgstr "登录来源"
|
msgstr "登录来源"
|
||||||
|
@ -3423,10 +3439,6 @@ msgstr "受理人"
|
||||||
msgid "Assignees display"
|
msgid "Assignees display"
|
||||||
msgstr "受理人 (显示名称)"
|
msgstr "受理人 (显示名称)"
|
||||||
|
|
||||||
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:24
|
|
||||||
msgid "Category display"
|
|
||||||
msgstr "类别 (显示名称)"
|
|
||||||
|
|
||||||
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:31
|
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:31
|
||||||
#: tickets/serializers/ticket/ticket.py:19
|
#: tickets/serializers/ticket/ticket.py:19
|
||||||
msgid "Type display"
|
msgid "Type display"
|
||||||
|
@ -3558,7 +3570,7 @@ msgstr "工单已处理 - {} ({})"
|
||||||
msgid "Your ticket has been processed, processor - {}"
|
msgid "Your ticket has been processed, processor - {}"
|
||||||
msgstr "你的工单已被处理, 处理人 - {}"
|
msgstr "你的工单已被处理, 处理人 - {}"
|
||||||
|
|
||||||
#: users/api/user.py:200
|
#: users/api/user.py:212
|
||||||
msgid "Could not reset self otp, use profile reset instead"
|
msgid "Could not reset self otp, use profile reset instead"
|
||||||
msgstr "不能在该页面重置多因子认证, 请去个人信息页面重置"
|
msgstr "不能在该页面重置多因子认证, 请去个人信息页面重置"
|
||||||
|
|
||||||
|
@ -3638,8 +3650,8 @@ msgstr "复制你的公钥到这里"
|
||||||
msgid "Public key should not be the same as your old one."
|
msgid "Public key should not be the same as your old one."
|
||||||
msgstr "不能和原来的密钥相同"
|
msgstr "不能和原来的密钥相同"
|
||||||
|
|
||||||
#: users/forms/profile.py:149 users/serializers/profile.py:74
|
#: users/forms/profile.py:149 users/serializers/profile.py:71
|
||||||
#: users/serializers/profile.py:147 users/serializers/profile.py:160
|
#: users/serializers/profile.py:144 users/serializers/profile.py:157
|
||||||
msgid "Not a valid ssh public key"
|
msgid "Not a valid ssh public key"
|
||||||
msgstr "SSH密钥不合法"
|
msgstr "SSH密钥不合法"
|
||||||
|
|
||||||
|
@ -3677,27 +3689,27 @@ msgstr "用户来源"
|
||||||
msgid "Date password last updated"
|
msgid "Date password last updated"
|
||||||
msgstr "最后更新密码日期"
|
msgstr "最后更新密码日期"
|
||||||
|
|
||||||
#: users/models/user.py:685
|
#: users/models/user.py:707
|
||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "管理员"
|
msgstr "管理员"
|
||||||
|
|
||||||
#: users/models/user.py:688
|
#: users/models/user.py:710
|
||||||
msgid "Administrator is the super user of system"
|
msgid "Administrator is the super user of system"
|
||||||
msgstr "Administrator是初始的超级管理员"
|
msgstr "Administrator是初始的超级管理员"
|
||||||
|
|
||||||
#: users/serializers/profile.py:32
|
#: users/serializers/profile.py:29
|
||||||
msgid "The old password is incorrect"
|
msgid "The old password is incorrect"
|
||||||
msgstr "旧密码错误"
|
msgstr "旧密码错误"
|
||||||
|
|
||||||
#: users/serializers/profile.py:40 users/serializers/user.py:112
|
#: users/serializers/profile.py:37 users/serializers/user.py:112
|
||||||
msgid "Password does not match security rules"
|
msgid "Password does not match security rules"
|
||||||
msgstr "密码不满足安全规则"
|
msgstr "密码不满足安全规则"
|
||||||
|
|
||||||
#: users/serializers/profile.py:46
|
#: users/serializers/profile.py:43
|
||||||
msgid "The newly set password is inconsistent"
|
msgid "The newly set password is inconsistent"
|
||||||
msgstr "两次密码不一致"
|
msgstr "两次密码不一致"
|
||||||
|
|
||||||
#: users/serializers/profile.py:118 users/serializers/user.py:65
|
#: users/serializers/profile.py:115 users/serializers/user.py:67
|
||||||
msgid "Is first login"
|
msgid "Is first login"
|
||||||
msgstr "首次登录"
|
msgstr "首次登录"
|
||||||
|
|
||||||
|
@ -3715,58 +3727,58 @@ msgid "Password strategy"
|
||||||
msgstr "密码策略"
|
msgstr "密码策略"
|
||||||
|
|
||||||
#: users/serializers/user.py:30
|
#: users/serializers/user.py:30
|
||||||
msgid "MFA level for display"
|
|
||||||
msgstr "多因子认证等级(显示名称)"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:31
|
|
||||||
msgid "Login blocked"
|
|
||||||
msgstr "登录被阻塞"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:32
|
|
||||||
msgid "Can update"
|
|
||||||
msgstr "是否可更新"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:33
|
|
||||||
msgid "Can delete"
|
|
||||||
msgstr "是否可删除"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:35 users/serializers/user.py:72
|
|
||||||
msgid "Organization role name"
|
|
||||||
msgstr "组织角色名称"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:68
|
|
||||||
msgid "Avatar url"
|
|
||||||
msgstr "头像路径"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:70
|
|
||||||
msgid "Groups name"
|
|
||||||
msgstr "用户组名"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:71
|
|
||||||
msgid "Source name"
|
|
||||||
msgstr "用户来源名"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:73
|
|
||||||
msgid "Super role name"
|
|
||||||
msgstr "超级角色名称"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:74
|
|
||||||
msgid "Total role name"
|
|
||||||
msgstr "汇总角色名称"
|
|
||||||
|
|
||||||
#: users/serializers/user.py:75
|
|
||||||
msgid "MFA enabled"
|
msgid "MFA enabled"
|
||||||
msgstr "是否开启多因子认证"
|
msgstr "是否开启多因子认证"
|
||||||
|
|
||||||
#: users/serializers/user.py:76
|
#: users/serializers/user.py:31
|
||||||
msgid "MFA force enabled"
|
msgid "MFA force enabled"
|
||||||
msgstr "强制启用多因子认证"
|
msgstr "强制启用多因子认证"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:32
|
||||||
|
msgid "MFA level for display"
|
||||||
|
msgstr "多因子认证等级(显示名称)"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:33
|
||||||
|
msgid "Login blocked"
|
||||||
|
msgstr "登录被阻塞"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:35
|
||||||
|
msgid "Can update"
|
||||||
|
msgstr "是否可更新"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:36
|
||||||
|
msgid "Can delete"
|
||||||
|
msgstr "是否可删除"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:38 users/serializers/user.py:74
|
||||||
|
msgid "Organization role name"
|
||||||
|
msgstr "组织角色名称"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:70
|
||||||
|
msgid "Avatar url"
|
||||||
|
msgstr "头像路径"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:72
|
||||||
|
msgid "Groups name"
|
||||||
|
msgstr "用户组名"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:73
|
||||||
|
msgid "Source name"
|
||||||
|
msgstr "用户来源名"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:75
|
||||||
|
msgid "Super role name"
|
||||||
|
msgstr "超级角色名称"
|
||||||
|
|
||||||
|
#: users/serializers/user.py:76
|
||||||
|
msgid "Total role name"
|
||||||
|
msgstr "汇总角色名称"
|
||||||
|
|
||||||
#: users/serializers/user.py:100
|
#: users/serializers/user.py:100
|
||||||
msgid "Role limit to {}"
|
msgid "Role limit to {}"
|
||||||
msgstr "角色只能为 {}"
|
msgstr "角色只能为 {}"
|
||||||
|
|
||||||
#: users/serializers/user.py:202
|
#: users/serializers/user.py:197
|
||||||
msgid "name not unique"
|
msgid "name not unique"
|
||||||
msgstr "名称重复"
|
msgstr "名称重复"
|
||||||
|
|
||||||
|
@ -4591,19 +4603,19 @@ msgstr ""
|
||||||
" <br>\n"
|
" <br>\n"
|
||||||
" "
|
" "
|
||||||
|
|
||||||
#: users/views/profile/otp.py:193
|
#: users/views/profile/otp.py:190
|
||||||
msgid "MFA enable success"
|
msgid "MFA enable success"
|
||||||
msgstr "多因子认证启用成功"
|
msgstr "多因子认证启用成功"
|
||||||
|
|
||||||
#: users/views/profile/otp.py:194
|
#: users/views/profile/otp.py:191
|
||||||
msgid "MFA enable success, return login page"
|
msgid "MFA enable success, return login page"
|
||||||
msgstr "多因子认证启用成功,返回到登录页面"
|
msgstr "多因子认证启用成功,返回到登录页面"
|
||||||
|
|
||||||
#: users/views/profile/otp.py:196
|
#: users/views/profile/otp.py:193
|
||||||
msgid "MFA disable success"
|
msgid "MFA disable success"
|
||||||
msgstr "多因子认证禁用成功"
|
msgstr "多因子认证禁用成功"
|
||||||
|
|
||||||
#: users/views/profile/otp.py:197
|
#: users/views/profile/otp.py:194
|
||||||
msgid "MFA disable success, return login page"
|
msgid "MFA disable success, return login page"
|
||||||
msgstr "多因子认证禁用成功,返回登录页面"
|
msgstr "多因子认证禁用成功,返回登录页面"
|
||||||
|
|
||||||
|
@ -5098,7 +5110,7 @@ msgstr "许可证导入成功"
|
||||||
msgid "License is invalid"
|
msgid "License is invalid"
|
||||||
msgstr "无效的许可证"
|
msgstr "无效的许可证"
|
||||||
|
|
||||||
#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:124
|
#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:127
|
||||||
msgid "License"
|
msgid "License"
|
||||||
msgstr "许可证"
|
msgstr "许可证"
|
||||||
|
|
||||||
|
@ -5117,3 +5129,14 @@ msgstr "旗舰版"
|
||||||
#: xpack/plugins/license/models.py:77
|
#: xpack/plugins/license/models.py:77
|
||||||
msgid "Community edition"
|
msgid "Community edition"
|
||||||
msgstr "社区版"
|
msgstr "社区版"
|
||||||
|
|
||||||
|
#~ msgid ""
|
||||||
|
#~ "Push system user task skip, auto push not enable or protocol is not ssh "
|
||||||
|
#~ "or rdp: {}"
|
||||||
|
#~ msgstr "推送系统用户任务跳过,自动推送没有打开,或协议不是ssh或rdp: {}"
|
||||||
|
|
||||||
|
#~ msgid "Empty"
|
||||||
|
#~ msgstr "空"
|
||||||
|
|
||||||
|
#~ msgid "Organization contains undeleted resources"
|
||||||
|
#~ msgstr "组织包含未删除的资源"
|
||||||
|
|
|
@ -53,7 +53,7 @@ class AdHocDisplay(Display, metaclass=UnSingleton):
|
||||||
# 这里先不 flush,log 文件不需要那么及时。
|
# 这里先不 flush,log 文件不需要那么及时。
|
||||||
self.log_file.write(msg)
|
self.log_file.write(msg)
|
||||||
|
|
||||||
def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False):
|
def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False, newline=True):
|
||||||
if color:
|
if color:
|
||||||
msg = stringc(msg, color)
|
msg = stringc(msg, color)
|
||||||
|
|
||||||
|
@ -62,5 +62,7 @@ class AdHocDisplay(Display, metaclass=UnSingleton):
|
||||||
else:
|
else:
|
||||||
msg2 = msg
|
msg2 = msg
|
||||||
|
|
||||||
self._write_to_screen(msg2, stderr)
|
if log_only:
|
||||||
self._write_to_log_file(msg2)
|
self._write_to_log_file(msg2)
|
||||||
|
else:
|
||||||
|
self._write_to_screen(msg2, stderr)
|
||||||
|
|
|
@ -11,7 +11,7 @@ default_id = '00000000-0000-0000-0000-000000000002'
|
||||||
|
|
||||||
def add_default_org(apps, schema_editor):
|
def add_default_org(apps, schema_editor):
|
||||||
org_cls = apps.get_model('orgs', 'Organization')
|
org_cls = apps.get_model('orgs', 'Organization')
|
||||||
defaults = {'name': 'DEFAULT', 'id': default_id}
|
defaults = {'name': 'Default', 'id': default_id}
|
||||||
org_cls.objects.get_or_create(defaults=defaults, id=default_id)
|
org_cls.objects.get_or_create(defaults=defaults, id=default_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
#
|
#
|
||||||
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
||||||
from rest_framework_bulk import BulkModelViewSet
|
from rest_framework_bulk import BulkModelViewSet
|
||||||
|
from rest_framework.exceptions import MethodNotAllowed
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common.mixins import CommonApiMixin, RelationMixin
|
from common.mixins import CommonApiMixin, RelationMixin
|
||||||
from orgs.utils import current_org
|
from orgs.utils import current_org
|
||||||
|
|
||||||
|
@ -39,15 +42,29 @@ class OrgQuerySetMixin:
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class OrgModelViewSet(CommonApiMixin, OrgQuerySetMixin, ModelViewSet):
|
class OrgViewSetMixin(OrgQuerySetMixin):
|
||||||
|
root_org_readonly_msg = _("Root organization only allow view and delete")
|
||||||
|
|
||||||
|
def update(self, request, *args, **kwargs):
|
||||||
|
if current_org.is_root():
|
||||||
|
raise MethodNotAllowed('put', self.root_org_readonly_msg)
|
||||||
|
return super().update(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
if current_org.is_root():
|
||||||
|
raise MethodNotAllowed('post', self.root_org_readonly_msg)
|
||||||
|
return super().update(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class OrgModelViewSet(CommonApiMixin, OrgViewSetMixin, ModelViewSet):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OrgGenericViewSet(CommonApiMixin, OrgQuerySetMixin, GenericViewSet):
|
class OrgGenericViewSet(CommonApiMixin, OrgViewSetMixin, GenericViewSet):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OrgBulkModelViewSet(CommonApiMixin, OrgQuerySetMixin, BulkModelViewSet):
|
class OrgBulkModelViewSet(CommonApiMixin, OrgViewSetMixin, BulkModelViewSet):
|
||||||
def allow_bulk_destroy(self, qs, filtered):
|
def allow_bulk_destroy(self, qs, filtered):
|
||||||
qs_count = qs.count()
|
qs_count = qs.count()
|
||||||
filtered_count = filtered.count()
|
filtered_count = filtered.count()
|
||||||
|
|
|
@ -5,7 +5,7 @@ from django.dispatch import receiver
|
||||||
|
|
||||||
from users.models import User
|
from users.models import User
|
||||||
from assets.models import Asset
|
from assets.models import Asset
|
||||||
from orgs.utils import current_org
|
from orgs.utils import current_org, tmp_to_org
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from common.exceptions import M2MReverseNotAllowed
|
from common.exceptions import M2MReverseNotAllowed
|
||||||
from common.const.signals import POST_ADD, POST_REMOVE, POST_CLEAR
|
from common.const.signals import POST_ADD, POST_REMOVE, POST_CLEAR
|
||||||
|
@ -18,24 +18,28 @@ logger = get_logger(__file__)
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=User.groups.through)
|
@receiver(m2m_changed, sender=User.groups.through)
|
||||||
def on_user_groups_change(sender, instance, action, reverse, pk_set, **kwargs):
|
def on_user_groups_change(sender, instance, action, reverse, pk_set, **kwargs):
|
||||||
if action.startswith('post'):
|
if not action.startswith('post'):
|
||||||
if reverse:
|
return
|
||||||
group_ids = [instance.id]
|
if reverse:
|
||||||
user_ids = pk_set
|
group_ids = [instance.id]
|
||||||
else:
|
user_ids = pk_set
|
||||||
group_ids = pk_set
|
else:
|
||||||
user_ids = [instance.id]
|
group_ids = pk_set
|
||||||
|
user_ids = [instance.id]
|
||||||
|
|
||||||
exists = AssetPermission.user_groups.through.objects.filter(usergroup_id__in=group_ids).exists()
|
exists = AssetPermission.user_groups.through.objects.filter(usergroup_id__in=group_ids).exists()
|
||||||
if exists:
|
if not exists:
|
||||||
org_ids = [current_org.id]
|
return
|
||||||
UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users(org_ids, user_ids)
|
with tmp_to_org(instance.org):
|
||||||
|
org_ids = [current_org.id]
|
||||||
|
UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users(org_ids, user_ids)
|
||||||
|
|
||||||
|
|
||||||
@receiver([pre_delete], sender=AssetPermission)
|
@receiver([pre_delete], sender=AssetPermission)
|
||||||
def on_asset_perm_pre_delete(sender, instance, **kwargs):
|
def on_asset_perm_pre_delete(sender, instance, **kwargs):
|
||||||
# 授权删除之前,查出所有相关用户
|
# 授权删除之前,查出所有相关用户
|
||||||
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
with tmp_to_org(instance.org):
|
||||||
|
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
||||||
|
|
||||||
|
|
||||||
@receiver([pre_save], sender=AssetPermission)
|
@receiver([pre_save], sender=AssetPermission)
|
||||||
|
@ -44,14 +48,17 @@ def on_asset_perm_pre_save(sender, instance, **kwargs):
|
||||||
old = AssetPermission.objects.get(id=instance.id)
|
old = AssetPermission.objects.get(id=instance.id)
|
||||||
|
|
||||||
if old.is_valid != instance.is_valid:
|
if old.is_valid != instance.is_valid:
|
||||||
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
with tmp_to_org(instance.org):
|
||||||
|
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
||||||
except AssetPermission.DoesNotExist:
|
except AssetPermission.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@receiver([post_save], sender=AssetPermission)
|
@receiver([post_save], sender=AssetPermission)
|
||||||
def on_asset_perm_post_save(sender, instance, created, **kwargs):
|
def on_asset_perm_post_save(sender, instance, created, **kwargs):
|
||||||
if created:
|
if not created:
|
||||||
|
return
|
||||||
|
with tmp_to_org(instance.org):
|
||||||
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,7 +71,10 @@ def on_permission_nodes_changed(sender, instance, action, reverse, **kwargs):
|
||||||
if reverse:
|
if reverse:
|
||||||
raise M2MReverseNotAllowed
|
raise M2MReverseNotAllowed
|
||||||
|
|
||||||
if need_rebuild_mapping_node(action):
|
if not need_rebuild_mapping_node(action):
|
||||||
|
return
|
||||||
|
|
||||||
|
with tmp_to_org(instance.org):
|
||||||
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,28 +83,38 @@ def on_permission_assets_changed(sender, instance, action, reverse, pk_set, mode
|
||||||
if reverse:
|
if reverse:
|
||||||
raise M2MReverseNotAllowed
|
raise M2MReverseNotAllowed
|
||||||
|
|
||||||
if need_rebuild_mapping_node(action):
|
if not need_rebuild_mapping_node(action):
|
||||||
|
return
|
||||||
|
with tmp_to_org(instance.org):
|
||||||
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id])
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=AssetPermission.users.through)
|
@receiver(m2m_changed, sender=AssetPermission.users.through)
|
||||||
def on_asset_permission_users_changed(sender, action, reverse, pk_set, **kwargs):
|
def on_asset_permission_users_changed(sender, action, reverse, instance, pk_set, **kwargs):
|
||||||
if reverse:
|
if reverse:
|
||||||
raise M2MReverseNotAllowed
|
raise M2MReverseNotAllowed
|
||||||
|
|
||||||
if need_rebuild_mapping_node(action):
|
if not need_rebuild_mapping_node(action):
|
||||||
|
return
|
||||||
|
|
||||||
|
with tmp_to_org(instance.org):
|
||||||
UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users(
|
UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users(
|
||||||
[current_org.id], pk_set
|
[current_org.id], pk_set
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=AssetPermission.user_groups.through)
|
@receiver(m2m_changed, sender=AssetPermission.user_groups.through)
|
||||||
def on_asset_permission_user_groups_changed(sender, action, pk_set, reverse, **kwargs):
|
def on_asset_permission_user_groups_changed(sender, instance, action, pk_set, reverse, **kwargs):
|
||||||
if reverse:
|
if reverse:
|
||||||
raise M2MReverseNotAllowed
|
raise M2MReverseNotAllowed
|
||||||
|
|
||||||
if need_rebuild_mapping_node(action):
|
if not need_rebuild_mapping_node(action):
|
||||||
user_ids = User.groups.through.objects.filter(usergroup_id__in=pk_set).distinct().values_list('user_id', flat=True)
|
return
|
||||||
|
|
||||||
|
user_ids = User.groups.through.objects.filter(usergroup_id__in=pk_set) \
|
||||||
|
.values_list('user_id', flat=True) \
|
||||||
|
.distinct()
|
||||||
|
with tmp_to_org(instance.org):
|
||||||
UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users(
|
UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users(
|
||||||
[current_org.id], user_ids
|
[current_org.id], user_ids
|
||||||
)
|
)
|
||||||
|
@ -112,4 +132,5 @@ def on_node_asset_change(action, instance, reverse, pk_set, **kwargs):
|
||||||
asset_pk_set = [instance.id]
|
asset_pk_set = [instance.id]
|
||||||
node_pk_set = pk_set
|
node_pk_set = pk_set
|
||||||
|
|
||||||
UserGrantedTreeRefreshController.add_need_refresh_on_nodes_assets_relate_change(node_pk_set, asset_pk_set)
|
with tmp_to_org(instance.org):
|
||||||
|
UserGrantedTreeRefreshController.add_need_refresh_on_nodes_assets_relate_change(node_pk_set, asset_pk_set)
|
||||||
|
|
|
@ -10,6 +10,7 @@ from django.core.mail import send_mail, get_connection
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.templatetags.static import static
|
from django.templatetags.static import static
|
||||||
|
|
||||||
|
from jumpserver.utils import has_valid_xpack_license
|
||||||
from common.permissions import IsSuperUser
|
from common.permissions import IsSuperUser
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from .. import serializers
|
from .. import serializers
|
||||||
|
@ -94,14 +95,6 @@ class PublicSettingApi(generics.RetrieveAPIView):
|
||||||
logo_urls.update({attr: getattr(obj, attr).url})
|
logo_urls.update({attr: getattr(obj, attr).url})
|
||||||
return logo_urls
|
return logo_urls
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_xpack_license_is_valid():
|
|
||||||
if not settings.XPACK_ENABLED:
|
|
||||||
return False
|
|
||||||
|
|
||||||
from xpack.plugins.license.models import License
|
|
||||||
return License.has_valid_license()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_login_title():
|
def get_login_title():
|
||||||
default_title = _('Welcome to the JumpServer open source Bastion Host')
|
default_title = _('Welcome to the JumpServer open source Bastion Host')
|
||||||
|
@ -121,7 +114,7 @@ class PublicSettingApi(generics.RetrieveAPIView):
|
||||||
"SECURITY_MFA_VERIFY_TTL": settings.SECURITY_MFA_VERIFY_TTL,
|
"SECURITY_MFA_VERIFY_TTL": settings.SECURITY_MFA_VERIFY_TTL,
|
||||||
"SECURITY_COMMAND_EXECUTION": settings.SECURITY_COMMAND_EXECUTION,
|
"SECURITY_COMMAND_EXECUTION": settings.SECURITY_COMMAND_EXECUTION,
|
||||||
"SECURITY_PASSWORD_EXPIRATION_TIME": settings.SECURITY_PASSWORD_EXPIRATION_TIME,
|
"SECURITY_PASSWORD_EXPIRATION_TIME": settings.SECURITY_PASSWORD_EXPIRATION_TIME,
|
||||||
"XPACK_LICENSE_IS_VALID": self.get_xpack_license_is_valid(),
|
"XPACK_LICENSE_IS_VALID": has_valid_xpack_license(),
|
||||||
"LOGIN_TITLE": self.get_login_title(),
|
"LOGIN_TITLE": self.get_login_title(),
|
||||||
"LOGO_URLS": self.get_logo_urls(),
|
"LOGO_URLS": self.get_logo_urls(),
|
||||||
"TICKETS_ENABLED": settings.TICKETS_ENABLED,
|
"TICKETS_ENABLED": settings.TICKETS_ENABLED,
|
||||||
|
|
|
@ -11,7 +11,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from django.template import loader
|
from django.template import loader
|
||||||
|
|
||||||
from terminal.models import CommandStorage
|
from terminal.models import CommandStorage, Command
|
||||||
from terminal.filters import CommandFilter
|
from terminal.filters import CommandFilter
|
||||||
from orgs.utils import current_org
|
from orgs.utils import current_org
|
||||||
from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor, IsAppUser
|
from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor, IsAppUser
|
||||||
|
@ -19,6 +19,7 @@ from common.const.http import GET
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from terminal.utils import send_command_alert_mail
|
from terminal.utils import send_command_alert_mail
|
||||||
from terminal.serializers import InsecureCommandAlertSerializer
|
from terminal.serializers import InsecureCommandAlertSerializer
|
||||||
|
from terminal.exceptions import StorageInvalid
|
||||||
from ..backends import (
|
from ..backends import (
|
||||||
get_command_storage, get_multi_command_storage,
|
get_command_storage, get_multi_command_storage,
|
||||||
SessionCommandSerializer,
|
SessionCommandSerializer,
|
||||||
|
@ -116,9 +117,12 @@ class CommandViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
storages = CommandStorage.objects.all()
|
storages = CommandStorage.objects.all()
|
||||||
for storage in storages:
|
for storage in storages:
|
||||||
|
if not storage.is_valid():
|
||||||
|
continue
|
||||||
|
|
||||||
qs = storage.get_command_queryset()
|
qs = storage.get_command_queryset()
|
||||||
commands = self.filter_queryset(qs)
|
commands = self.filter_queryset(qs)
|
||||||
merged_commands.extend(commands)
|
merged_commands.extend(commands[:]) # ES 默认只取 10 条数据
|
||||||
|
|
||||||
merged_commands.sort(key=lambda command: command.timestamp, reverse=True)
|
merged_commands.sort(key=lambda command: command.timestamp, reverse=True)
|
||||||
page = self.paginate_queryset(merged_commands)
|
page = self.paginate_queryset(merged_commands)
|
||||||
|
@ -126,7 +130,7 @@ class CommandViewSet(viewsets.ModelViewSet):
|
||||||
serializer = self.get_serializer(page, many=True)
|
serializer = self.get_serializer(page, many=True)
|
||||||
return self.get_paginated_response(serializer.data)
|
return self.get_paginated_response(serializer.data)
|
||||||
|
|
||||||
serializer = self.get_serializer(queryset, many=True)
|
serializer = self.get_serializer(merged_commands, many=True)
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
|
@ -141,7 +145,10 @@ class CommandViewSet(viewsets.ModelViewSet):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
command_storage_id = self.request.query_params.get('command_storage_id')
|
command_storage_id = self.request.query_params.get('command_storage_id')
|
||||||
storage = CommandStorage.objects.get(id=command_storage_id)
|
storage = CommandStorage.objects.get(id=command_storage_id)
|
||||||
qs = storage.get_command_queryset()
|
if not storage.is_valid():
|
||||||
|
raise StorageInvalid
|
||||||
|
else:
|
||||||
|
qs = storage.get_command_queryset()
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
|
|
|
@ -46,7 +46,13 @@ class CommandStorageViewSet(BaseStorageViewSetMixin, viewsets.ModelViewSet):
|
||||||
def tree(self, request: Request):
|
def tree(self, request: Request):
|
||||||
storage_qs = self.get_queryset().exclude(name='null')
|
storage_qs = self.get_queryset().exclude(name='null')
|
||||||
storages_with_count = []
|
storages_with_count = []
|
||||||
|
invalid_storages = []
|
||||||
|
|
||||||
for storage in storage_qs:
|
for storage in storage_qs:
|
||||||
|
if not storage.is_valid():
|
||||||
|
invalid_storages.append(storage)
|
||||||
|
continue
|
||||||
|
|
||||||
command_qs = storage.get_command_queryset()
|
command_qs = storage.get_command_queryset()
|
||||||
filterset = CommandFilter(
|
filterset = CommandFilter(
|
||||||
data=request.query_params, queryset=command_qs,
|
data=request.query_params, queryset=command_qs,
|
||||||
|
@ -70,6 +76,7 @@ class CommandStorageViewSet(BaseStorageViewSetMixin, viewsets.ModelViewSet):
|
||||||
'open': True,
|
'open': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invalid = _('Invalid')
|
||||||
nodes = [
|
nodes = [
|
||||||
{
|
{
|
||||||
'id': storage.id,
|
'id': storage.id,
|
||||||
|
@ -78,7 +85,18 @@ class CommandStorageViewSet(BaseStorageViewSetMixin, viewsets.ModelViewSet):
|
||||||
'pId': 'root',
|
'pId': 'root',
|
||||||
'isParent': False,
|
'isParent': False,
|
||||||
'open': False,
|
'open': False,
|
||||||
|
'valid': True,
|
||||||
} for storage, command_count in storages_with_count
|
} for storage, command_count in storages_with_count
|
||||||
|
] + [
|
||||||
|
{
|
||||||
|
'id': storage.id,
|
||||||
|
'name': f'{storage.name}({storage.type}) *{invalid}',
|
||||||
|
'title': f'{storage.name}({storage.type})',
|
||||||
|
'pId': 'root',
|
||||||
|
'isParent': False,
|
||||||
|
'open': False,
|
||||||
|
'valid': False,
|
||||||
|
} for storage in invalid_storages
|
||||||
]
|
]
|
||||||
nodes.append(root)
|
nodes.append(root)
|
||||||
return Response(data=nodes)
|
return Response(data=nodes)
|
||||||
|
|
|
@ -25,7 +25,7 @@ class CommandStore():
|
||||||
kwargs = config.get("OTHER", {})
|
kwargs = config.get("OTHER", {})
|
||||||
self.index = config.get("INDEX") or 'jumpserver'
|
self.index = config.get("INDEX") or 'jumpserver'
|
||||||
self.doc_type = config.get("DOC_TYPE") or 'command_store'
|
self.doc_type = config.get("DOC_TYPE") or 'command_store'
|
||||||
self.es = Elasticsearch(hosts=hosts, **kwargs)
|
self.es = Elasticsearch(hosts=hosts, max_retries=0, **kwargs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def make_data(command):
|
def make_data(command):
|
||||||
|
@ -81,9 +81,9 @@ class CommandStore():
|
||||||
"""返回所有数据"""
|
"""返回所有数据"""
|
||||||
raise NotImplementedError("Not support")
|
raise NotImplementedError("Not support")
|
||||||
|
|
||||||
def ping(self):
|
def ping(self, timeout=None):
|
||||||
try:
|
try:
|
||||||
return self.es.ping()
|
return self.es.ping(request_timeout=timeout)
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -121,7 +121,11 @@ class CommandStore():
|
||||||
org_id = match.get('org_id')
|
org_id = match.get('org_id')
|
||||||
|
|
||||||
real_default_org_id = '00000000-0000-0000-0000-000000000002'
|
real_default_org_id = '00000000-0000-0000-0000-000000000002'
|
||||||
if org_id in (real_default_org_id, ''):
|
root_org_id = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
|
if org_id == root_org_id:
|
||||||
|
match.pop('org_id')
|
||||||
|
elif org_id in (real_default_org_id, ''):
|
||||||
match.pop('org_id')
|
match.pop('org_id')
|
||||||
should.append({
|
should.append({
|
||||||
'bool':{
|
'bool':{
|
||||||
|
@ -256,7 +260,7 @@ class QuerySet(DJQuerySet):
|
||||||
clone = self.__clone()
|
clone = self.__clone()
|
||||||
from_ = item.start or 0
|
from_ = item.start or 0
|
||||||
if item.stop is None:
|
if item.stop is None:
|
||||||
size = 10
|
size = self.max_result_window - from_
|
||||||
else:
|
else:
|
||||||
size = item.stop - from_
|
size = item.stop - from_
|
||||||
|
|
||||||
|
|
|
@ -6,3 +6,9 @@ from common.exceptions import JMSException
|
||||||
class BulkCreateNotSupport(JMSException):
|
class BulkCreateNotSupport(JMSException):
|
||||||
default_code = 'bulk_create_not_support'
|
default_code = 'bulk_create_not_support'
|
||||||
default_detail = _('Bulk create not support')
|
default_detail = _('Bulk create not support')
|
||||||
|
|
||||||
|
|
||||||
|
class StorageInvalid(JMSException):
|
||||||
|
default_code = 'storage_invalid'
|
||||||
|
default_detail = _('Storage is invalid')
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,14 @@ class CommandStorage(CommonModelMixin):
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
if self.type_null_or_server:
|
if self.type_null_or_server:
|
||||||
return True
|
return True
|
||||||
storage = jms_storage.get_log_storage(self.config)
|
|
||||||
return storage.ping()
|
if self.type not in TYPE_ENGINE_MAPPING:
|
||||||
|
logger.error(f'Command storage `{self.type}` not support')
|
||||||
|
return False
|
||||||
|
|
||||||
|
engine_mod = import_module(TYPE_ENGINE_MAPPING[self.type])
|
||||||
|
store = engine_mod.CommandStore(self.config)
|
||||||
|
return store.ping(timeout=3)
|
||||||
|
|
||||||
def is_use(self):
|
def is_use(self):
|
||||||
return Terminal.objects.filter(command_storage=self.name, is_deleted=False).exists()
|
return Terminal.objects.filter(command_storage=self.name, is_deleted=False).exists()
|
||||||
|
|
Loading…
Reference in New Issue