mirror of https://github.com/jumpserver/jumpserver
commit
2ca4002624
|
@ -45,3 +45,4 @@ test.py
|
||||||
.history/
|
.history/
|
||||||
.test/
|
.test/
|
||||||
*.mo
|
*.mo
|
||||||
|
apps.iml
|
||||||
|
|
|
@ -89,7 +89,7 @@ JumpServer is a mission critical product. Please refer to the Basic Security Rec
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright (c) 2014-2024 FIT2CLOUD, All rights reserved.
|
Copyright (c) 2014-2025 FIT2CLOUD, All rights reserved.
|
||||||
|
|
||||||
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,13 @@ class ActionAclSerializer(serializers.Serializer):
|
||||||
return
|
return
|
||||||
if not settings.XPACK_LICENSE_IS_VALID:
|
if not settings.XPACK_LICENSE_IS_VALID:
|
||||||
field_action._choices.pop(ActionChoices.review, None)
|
field_action._choices.pop(ActionChoices.review, None)
|
||||||
|
if not (
|
||||||
|
settings.XPACK_LICENSE_IS_VALID and
|
||||||
|
settings.XPACK_LICENSE_EDITION_ULTIMATE and
|
||||||
|
settings.FACE_RECOGNITION_ENABLED
|
||||||
|
):
|
||||||
|
field_action._choices.pop(ActionChoices.face_verify, None)
|
||||||
|
field_action._choices.pop(ActionChoices.face_online, None)
|
||||||
for choice in self.Meta.action_choices_exclude:
|
for choice in self.Meta.action_choices_exclude:
|
||||||
field_action._choices.pop(choice, None)
|
field_action._choices.pop(choice, None)
|
||||||
|
|
||||||
|
|
|
@ -123,13 +123,15 @@ class RDPFileClientProtocolURLMixin:
|
||||||
# rdp_options['domain:s'] = token.account_ad_domain
|
# rdp_options['domain:s'] = token.account_ad_domain
|
||||||
|
|
||||||
# 设置宽高
|
# 设置宽高
|
||||||
height = self.request.query_params.get('height')
|
|
||||||
width = self.request.query_params.get('width')
|
resolution_value = token.connect_options.get('resolution', 'auto')
|
||||||
if width and height:
|
if resolution_value != 'auto':
|
||||||
rdp_options['desktopwidth:i'] = width
|
width, height = resolution_value.split('x')
|
||||||
rdp_options['desktopheight:i'] = height
|
if width and height:
|
||||||
rdp_options['winposstr:s'] = f'0,1,0,0,{width},{height}'
|
rdp_options['desktopwidth:i'] = width
|
||||||
rdp_options['dynamic resolution:i'] = '0'
|
rdp_options['desktopheight:i'] = height
|
||||||
|
rdp_options['winposstr:s'] = f'0,1,0,0,{width},{height}'
|
||||||
|
rdp_options['dynamic resolution:i'] = '0'
|
||||||
|
|
||||||
color_quality = self.request.query_params.get('rdp_color_quality')
|
color_quality = self.request.query_params.get('rdp_color_quality')
|
||||||
color_quality = color_quality if color_quality else os.getenv('JUMPSERVER_COLOR_DEPTH', RDPColorQuality.HIGH)
|
color_quality = color_quality if color_quality else os.getenv('JUMPSERVER_COLOR_DEPTH', RDPColorQuality.HIGH)
|
||||||
|
|
|
@ -30,10 +30,11 @@ class MFAFace(BaseMFA, AuthFaceMixin):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def global_enabled():
|
def global_enabled():
|
||||||
return settings.XPACK_LICENSE_IS_VALID \
|
return (
|
||||||
and LicenseEditionChoices.ULTIMATE == \
|
settings.XPACK_LICENSE_IS_VALID and
|
||||||
LicenseEditionChoices.from_key(settings.XPACK_LICENSE_EDITION) \
|
settings.XPACK_LICENSE_EDITION_ULTIMATE and
|
||||||
and settings.FACE_RECOGNITION_ENABLED
|
settings.FACE_RECOGNITION_ENABLED
|
||||||
|
)
|
||||||
|
|
||||||
def get_enable_url(self) -> str:
|
def get_enable_url(self) -> str:
|
||||||
return '/ui/#/profile/index'
|
return '/ui/#/profile/index'
|
||||||
|
|
|
@ -51,7 +51,7 @@ auth._get_backends = _get_backends
|
||||||
def authenticate(request=None, **credentials):
|
def authenticate(request=None, **credentials):
|
||||||
"""
|
"""
|
||||||
If the given credentials are valid, return a User object.
|
If the given credentials are valid, return a User object.
|
||||||
之所以 hack 这个 auticate
|
之所以 hack 这个 authenticate
|
||||||
"""
|
"""
|
||||||
username = credentials.get('username')
|
username = credentials.get('username')
|
||||||
|
|
||||||
|
@ -500,10 +500,12 @@ class AuthMixin(CommonMixin, AuthPreCheckMixin, AuthACLMixin, AuthFaceMixin, MFA
|
||||||
key_prefix_captcha = "_LOGIN_INVALID_{}"
|
key_prefix_captcha = "_LOGIN_INVALID_{}"
|
||||||
|
|
||||||
def _check_auth_user_is_valid(self, username, password, public_key):
|
def _check_auth_user_is_valid(self, username, password, public_key):
|
||||||
user = authenticate(
|
credentials = {'username': username}
|
||||||
self.request, username=username,
|
if password:
|
||||||
password=password, public_key=public_key
|
credentials['password'] = password
|
||||||
)
|
if public_key:
|
||||||
|
credentials['public_key'] = public_key
|
||||||
|
user = authenticate(self.request, **credentials)
|
||||||
if not user:
|
if not user:
|
||||||
self.raise_credential_error(errors.reason_password_failed)
|
self.raise_credential_error(errors.reason_password_failed)
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ class BaseLoginCallbackView(AuthMixin, FlashMessageMixin, IMClientMixin, View):
|
||||||
response = self.get_failed_response(login_url, title=msg, msg=msg)
|
response = self.get_failed_response(login_url, title=msg, msg=msg)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
if 'next=client' in redirect_url:
|
if redirect_url and 'next=client' in redirect_url:
|
||||||
self.request.META['QUERY_STRING'] += '&next=client'
|
self.request.META['QUERY_STRING'] += '&next=client'
|
||||||
return self.redirect_to_guard_view()
|
return self.redirect_to_guard_view()
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-12-19 15:10+0800\n"
|
"POT-Creation-Date: 2025-01-08 14:25+0800\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -365,7 +365,7 @@ msgstr ""
|
||||||
#: accounts/serializers/automations/change_secret.py:150
|
#: accounts/serializers/automations/change_secret.py:150
|
||||||
#: accounts/templates/accounts/asset_account_change_info.html:7
|
#: accounts/templates/accounts/asset_account_change_info.html:7
|
||||||
#: accounts/templates/accounts/change_secret_failed_info.html:11
|
#: accounts/templates/accounts/change_secret_failed_info.html:11
|
||||||
#: acls/serializers/base.py:123 assets/models/asset/common.py:102
|
#: acls/serializers/base.py:130 assets/models/asset/common.py:102
|
||||||
#: assets/models/asset/common.py:362 assets/models/cmd_filter.py:36
|
#: assets/models/asset/common.py:362 assets/models/cmd_filter.py:36
|
||||||
#: audits/models.py:58 authentication/models/connection_token.py:36
|
#: audits/models.py:58 authentication/models/connection_token.py:36
|
||||||
#: perms/models/asset_permission.py:69 terminal/backends/command/models.py:17
|
#: perms/models/asset_permission.py:69 terminal/backends/command/models.py:17
|
||||||
|
@ -408,7 +408,7 @@ msgstr ""
|
||||||
#: accounts/serializers/automations/change_secret.py:120
|
#: accounts/serializers/automations/change_secret.py:120
|
||||||
#: accounts/serializers/automations/change_secret.py:151
|
#: accounts/serializers/automations/change_secret.py:151
|
||||||
#: accounts/templates/accounts/change_secret_failed_info.html:12
|
#: accounts/templates/accounts/change_secret_failed_info.html:12
|
||||||
#: acls/serializers/base.py:124
|
#: acls/serializers/base.py:131
|
||||||
#: acls/templates/acls/asset_login_reminder.html:10
|
#: acls/templates/acls/asset_login_reminder.html:10
|
||||||
#: assets/serializers/gateway.py:33 audits/models.py:59
|
#: assets/serializers/gateway.py:33 audits/models.py:59
|
||||||
#: authentication/api/connection_token.py:459 ops/models/base.py:18
|
#: authentication/api/connection_token.py:459 ops/models/base.py:18
|
||||||
|
@ -513,7 +513,7 @@ msgid "Trigger mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: accounts/models/automations/backup_account.py:140 audits/models.py:203
|
#: accounts/models/automations/backup_account.py:140 audits/models.py:203
|
||||||
#: terminal/models/session/sharing.py:125 xpack/plugins/cloud/manager.py:176
|
#: terminal/models/session/sharing.py:125 xpack/plugins/cloud/manager.py:179
|
||||||
#: xpack/plugins/cloud/models.py:231
|
#: xpack/plugins/cloud/models.py:231
|
||||||
msgid "Reason"
|
msgid "Reason"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -929,7 +929,7 @@ msgstr ""
|
||||||
#: ops/models/job.py:155 ops/serializers/job.py:20
|
#: ops/models/job.py:155 ops/serializers/job.py:20
|
||||||
#: perms/serializers/permission.py:46
|
#: perms/serializers/permission.py:46
|
||||||
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
|
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
|
||||||
#: xpack/plugins/cloud/manager.py:89
|
#: xpack/plugins/cloud/manager.py:92
|
||||||
msgid "Assets"
|
msgid "Assets"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -956,7 +956,7 @@ msgstr ""
|
||||||
msgid "ID"
|
msgid "ID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: accounts/serializers/account/account.py:475 acls/serializers/base.py:116
|
#: accounts/serializers/account/account.py:475 acls/serializers/base.py:123
|
||||||
#: acls/templates/acls/asset_login_reminder.html:8
|
#: acls/templates/acls/asset_login_reminder.html:8
|
||||||
#: acls/templates/acls/user_login_reminder.html:8
|
#: acls/templates/acls/user_login_reminder.html:8
|
||||||
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:54
|
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:54
|
||||||
|
@ -964,7 +964,7 @@ msgstr ""
|
||||||
#: audits/serializers.py:195 authentication/models/connection_token.py:32
|
#: audits/serializers.py:195 authentication/models/connection_token.py:32
|
||||||
#: authentication/models/ssh_key.py:22 authentication/models/sso_token.py:16
|
#: authentication/models/ssh_key.py:22 authentication/models/sso_token.py:16
|
||||||
#: notifications/models/notification.py:12
|
#: notifications/models/notification.py:12
|
||||||
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:63
|
#: perms/api/user_permission/mixin.py:58 perms/models/asset_permission.py:63
|
||||||
#: rbac/builtin.py:125 rbac/models/rolebinding.py:49
|
#: rbac/builtin.py:125 rbac/models/rolebinding.py:49
|
||||||
#: rbac/serializers/rolebinding.py:17 terminal/backends/command/models.py:16
|
#: rbac/serializers/rolebinding.py:17 terminal/backends/command/models.py:16
|
||||||
#: terminal/models/session/session.py:31 terminal/models/session/sharing.py:34
|
#: terminal/models/session/session.py:31 terminal/models/session/sharing.py:34
|
||||||
|
@ -1491,15 +1491,15 @@ msgstr ""
|
||||||
msgid "IP/Host"
|
msgid "IP/Host"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: acls/serializers/base.py:91
|
#: acls/serializers/base.py:98
|
||||||
msgid "Recipients"
|
msgid "Recipients"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: acls/serializers/base.py:103 tickets/serializers/ticket/ticket.py:77
|
#: acls/serializers/base.py:110 tickets/serializers/ticket/ticket.py:77
|
||||||
msgid "The organization `{}` does not exist"
|
msgid "The organization `{}` does not exist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: acls/serializers/base.py:109
|
#: acls/serializers/base.py:116
|
||||||
msgid "None of the reviewers belong to Organization `{}`"
|
msgid "None of the reviewers belong to Organization `{}`"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1710,7 +1710,7 @@ msgstr ""
|
||||||
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:76
|
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:76
|
||||||
#: settings/serializers/feature.py:80 settings/serializers/feature.py:93
|
#: settings/serializers/feature.py:80 settings/serializers/feature.py:93
|
||||||
#: settings/serializers/msg.py:30 terminal/models/component/endpoint.py:14
|
#: settings/serializers/msg.py:30 terminal/models/component/endpoint.py:14
|
||||||
#: terminal/serializers/applet.py:17 xpack/plugins/cloud/manager.py:89
|
#: terminal/serializers/applet.py:17 xpack/plugins/cloud/manager.py:92
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:72
|
#: xpack/plugins/cloud/serializers/account_attrs.py:72
|
||||||
msgid "Host"
|
msgid "Host"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -2748,7 +2748,7 @@ msgstr ""
|
||||||
#: audits/const.py:23 rbac/tree.py:268 terminal/api/session/session.py:284
|
#: audits/const.py:23 rbac/tree.py:268 terminal/api/session/session.py:284
|
||||||
#: terminal/templates/terminal/_msg_command_warning.html:18
|
#: terminal/templates/terminal/_msg_command_warning.html:18
|
||||||
#: terminal/templates/terminal/_msg_session_sharing.html:10
|
#: terminal/templates/terminal/_msg_session_sharing.html:10
|
||||||
#: xpack/plugins/cloud/manager.py:90
|
#: xpack/plugins/cloud/manager.py:93
|
||||||
msgid "View"
|
msgid "View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2956,7 +2956,7 @@ msgid "Creator"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: audits/serializers.py:39 ops/models/base.py:52 ops/models/job.py:240
|
#: audits/serializers.py:39 ops/models/base.py:52 ops/models/job.py:240
|
||||||
#: xpack/plugins/cloud/manager.py:99
|
#: xpack/plugins/cloud/manager.py:102
|
||||||
msgid "Summary"
|
msgid "Summary"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3131,7 +3131,7 @@ msgid "No available face feature"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/api/face.py:100 authentication/mfa/face.py:21
|
#: authentication/api/face.py:100 authentication/mfa/face.py:21
|
||||||
#: authentication/mfa/face.py:23
|
#: authentication/mfa/face.py:23 users/views/profile/face.py:72
|
||||||
msgid "Facial comparison failed"
|
msgid "Facial comparison failed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3447,11 +3447,11 @@ msgstr ""
|
||||||
msgid "Face Recognition"
|
msgid "Face Recognition"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/mfa/face.py:54
|
#: authentication/mfa/face.py:55
|
||||||
msgid "Bind face to enable"
|
msgid "Bind face to enable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/mfa/face.py:58
|
#: authentication/mfa/face.py:59
|
||||||
msgid "Unbind face to disable"
|
msgid "Unbind face to disable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3626,13 +3626,13 @@ msgstr ""
|
||||||
|
|
||||||
#: authentication/models/ssh_key.py:15 terminal/serializers/storage.py:146
|
#: authentication/models/ssh_key.py:15 terminal/serializers/storage.py:146
|
||||||
#: users/models/user/__init__.py:93
|
#: users/models/user/__init__.py:93
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:213
|
#: xpack/plugins/cloud/serializers/account_attrs.py:214
|
||||||
msgid "Private key"
|
msgid "Private key"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/models/ssh_key.py:18 settings/serializers/terminal.py:34
|
#: authentication/models/ssh_key.py:18 settings/serializers/terminal.py:34
|
||||||
#: users/forms/profile.py:175 users/models/user/__init__.py:96
|
#: users/forms/profile.py:175 users/models/user/__init__.py:96
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:210
|
#: xpack/plugins/cloud/serializers/account_attrs.py:211
|
||||||
msgid "Public key"
|
msgid "Public key"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -4077,29 +4077,29 @@ msgstr ""
|
||||||
msgid "Redirecting to {} authentication"
|
msgid "Redirecting to {} authentication"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/views/login.py:243
|
#: authentication/views/login.py:247
|
||||||
msgid "Login timeout, please try again."
|
msgid "Login timeout, please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/views/login.py:288
|
#: authentication/views/login.py:292
|
||||||
msgid "User email already exists ({})"
|
msgid "User email already exists ({})"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/views/login.py:366
|
#: authentication/views/login.py:370
|
||||||
msgid ""
|
msgid ""
|
||||||
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
|
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
|
||||||
" Don't close this page"
|
" Don't close this page"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/views/login.py:371
|
#: authentication/views/login.py:375
|
||||||
msgid "No ticket found"
|
msgid "No ticket found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/views/login.py:407
|
#: authentication/views/login.py:411
|
||||||
msgid "Logout success"
|
msgid "Logout success"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/views/login.py:408
|
#: authentication/views/login.py:412
|
||||||
msgid "Logout success, return login page"
|
msgid "Logout success, return login page"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -4189,7 +4189,7 @@ msgstr ""
|
||||||
msgid "Ultimate edition"
|
msgid "Ultimate edition"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/const/common.py:5 xpack/plugins/cloud/manager.py:417
|
#: common/const/common.py:5 xpack/plugins/cloud/manager.py:424
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s was created successfully"
|
msgid "%(name)s was created successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -4250,8 +4250,8 @@ msgstr ""
|
||||||
#: common/serializers/fields.py:144 terminal/serializers/session.py:81
|
#: common/serializers/fields.py:144 terminal/serializers/session.py:81
|
||||||
#: tickets/serializers/ticket/common.py:58
|
#: tickets/serializers/ticket/common.py:58
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:56
|
#: xpack/plugins/cloud/serializers/account_attrs.py:56
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:79
|
#: xpack/plugins/cloud/serializers/account_attrs.py:80
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:150
|
#: xpack/plugins/cloud/serializers/account_attrs.py:151
|
||||||
msgid "This field is required."
|
msgid "This field is required."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -5067,9 +5067,10 @@ msgstr ""
|
||||||
|
|
||||||
#: ops/models/variable.py:12 ops/serializers/variable.py:23
|
#: ops/models/variable.py:12 ops/serializers/variable.py:23
|
||||||
msgid ""
|
msgid ""
|
||||||
"The variable name used in the script has a fixed prefix 'jms_' followed by "
|
"The variable name used in the script will have a fixed prefix jms_ added to "
|
||||||
"the input variable name. For example, if the variable name is 'name,' the "
|
"the input variable name. For example, if the input variable name is name, "
|
||||||
"final generated environment variable will be 'jms_name'."
|
"the resulting environment variable will be jms_name, and it can be "
|
||||||
|
"referenced in the script using {{ jms_name }}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/models/variable.py:16 ops/serializers/variable.py:31
|
#: ops/models/variable.py:16 ops/serializers/variable.py:31
|
||||||
|
@ -5156,11 +5157,11 @@ msgid ""
|
||||||
"is the value."
|
"is the value."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:53
|
#: ops/tasks.py:54
|
||||||
msgid "Run ansible task"
|
msgid "Run ansible task"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:56
|
#: ops/tasks.py:57
|
||||||
msgid ""
|
msgid ""
|
||||||
"Execute scheduled adhoc and playbooks, periodically invoking the task for "
|
"Execute scheduled adhoc and playbooks, periodically invoking the task for "
|
||||||
"execution"
|
"execution"
|
||||||
|
@ -5174,19 +5175,19 @@ msgstr ""
|
||||||
msgid "Execute the task when manually adhoc or playbooks"
|
msgid "Execute the task when manually adhoc or playbooks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:107
|
#: ops/tasks.py:106
|
||||||
msgid "Clear celery periodic tasks"
|
msgid "Clear celery periodic tasks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:109
|
#: ops/tasks.py:108
|
||||||
msgid "At system startup, clean up celery tasks that no longer exist"
|
msgid "At system startup, clean up celery tasks that no longer exist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:133
|
#: ops/tasks.py:132
|
||||||
msgid "Create or update periodic tasks"
|
msgid "Create or update periodic tasks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:135
|
#: ops/tasks.py:134
|
||||||
msgid ""
|
msgid ""
|
||||||
"With version iterations, new tasks may be added, or task names and execution "
|
"With version iterations, new tasks may be added, or task names and execution "
|
||||||
"times may \n"
|
"times may \n"
|
||||||
|
@ -5195,11 +5196,11 @@ msgid ""
|
||||||
" of scheduled tasks will be updated"
|
" of scheduled tasks will be updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:148
|
#: ops/tasks.py:147
|
||||||
msgid "Periodic check service performance"
|
msgid "Periodic check service performance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:150
|
#: ops/tasks.py:149
|
||||||
msgid ""
|
msgid ""
|
||||||
"Check every hour whether each component is offline and whether the CPU, "
|
"Check every hour whether each component is offline and whether the CPU, "
|
||||||
"memory, \n"
|
"memory, \n"
|
||||||
|
@ -5207,11 +5208,11 @@ msgid ""
|
||||||
"the administrator"
|
"the administrator"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:160
|
#: ops/tasks.py:159
|
||||||
msgid "Clean up unexpected jobs"
|
msgid "Clean up unexpected jobs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:162
|
#: ops/tasks.py:161
|
||||||
msgid ""
|
msgid ""
|
||||||
"Due to exceptions caused by executing adhoc and playbooks in the Job "
|
"Due to exceptions caused by executing adhoc and playbooks in the Job "
|
||||||
"Center, \n"
|
"Center, \n"
|
||||||
|
@ -5222,11 +5223,11 @@ msgid ""
|
||||||
" failed"
|
" failed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:175
|
#: ops/tasks.py:174
|
||||||
msgid "Clean job_execution db record"
|
msgid "Clean job_execution db record"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ops/tasks.py:177
|
#: ops/tasks.py:176
|
||||||
msgid ""
|
msgid ""
|
||||||
"Due to the execution of adhoc and playbooks in the Job Center, execution "
|
"Due to the execution of adhoc and playbooks in the Job Center, execution "
|
||||||
"records will \n"
|
"records will \n"
|
||||||
|
@ -5668,7 +5669,7 @@ msgstr ""
|
||||||
msgid "Session audits"
|
msgid "Session audits"
|
||||||
msgstr "Session"
|
msgstr "Session"
|
||||||
|
|
||||||
#: rbac/tree.py:49 xpack/plugins/cloud/manager.py:90
|
#: rbac/tree.py:49 xpack/plugins/cloud/manager.py:93
|
||||||
msgid "Cloud import"
|
msgid "Cloud import"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -5711,7 +5712,7 @@ msgid "Appearance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: rbac/tree.py:65 xpack/plugins/license/meta.py:10
|
#: rbac/tree.py:65 xpack/plugins/license/meta.py:10
|
||||||
#: xpack/plugins/license/models.py:151
|
#: xpack/plugins/license/models.py:153
|
||||||
msgid "License"
|
msgid "License"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -6424,7 +6425,7 @@ msgid "SSO auth key TTL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: settings/serializers/auth/sso.py:20
|
#: settings/serializers/auth/sso.py:20
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:200
|
#: xpack/plugins/cloud/serializers/account_attrs.py:201
|
||||||
msgid "Unit: second"
|
msgid "Unit: second"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -6581,7 +6582,7 @@ msgid "Tenant ID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: settings/serializers/feature.py:109 terminal/serializers/storage.py:68
|
#: settings/serializers/feature.py:109 terminal/serializers/storage.py:68
|
||||||
#: xpack/plugins/cloud/manager.py:107 xpack/plugins/cloud/manager.py:112
|
#: xpack/plugins/cloud/manager.py:110 xpack/plugins/cloud/manager.py:115
|
||||||
#: xpack/plugins/cloud/models.py:287
|
#: xpack/plugins/cloud/models.py:287
|
||||||
msgid "Region"
|
msgid "Region"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -7465,7 +7466,7 @@ msgstr ""
|
||||||
msgid "Command storages"
|
msgid "Command storages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: terminal/api/component/storage.py:84 xpack/plugins/cloud/manager.py:107
|
#: terminal/api/component/storage.py:84 xpack/plugins/cloud/manager.py:110
|
||||||
msgid "Invalid"
|
msgid "Invalid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -9580,7 +9581,7 @@ msgstr ""
|
||||||
msgid "Face binding successful"
|
msgid "Face binding successful"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: users/views/profile/face.py:80 users/views/profile/face.py:81
|
#: users/views/profile/face.py:82 users/views/profile/face.py:83
|
||||||
msgid "Face unbinding successful"
|
msgid "Face unbinding successful"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -9776,19 +9777,19 @@ msgstr ""
|
||||||
msgid "Succeed"
|
msgid "Succeed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/const.py:52 xpack/plugins/cloud/manager.py:95
|
#: xpack/plugins/cloud/const.py:52 xpack/plugins/cloud/manager.py:98
|
||||||
msgid "Unsync"
|
msgid "Unsync"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/const.py:53 xpack/plugins/cloud/manager.py:94
|
#: xpack/plugins/cloud/const.py:53 xpack/plugins/cloud/manager.py:97
|
||||||
msgid "New Sync"
|
msgid "New Sync"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/const.py:54 xpack/plugins/cloud/manager.py:94
|
#: xpack/plugins/cloud/const.py:54 xpack/plugins/cloud/manager.py:97
|
||||||
msgid "Synced"
|
msgid "Synced"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/const.py:55 xpack/plugins/cloud/manager.py:96
|
#: xpack/plugins/cloud/const.py:55 xpack/plugins/cloud/manager.py:99
|
||||||
msgid "Released"
|
msgid "Released"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -9808,45 +9809,45 @@ msgstr ""
|
||||||
msgid "Imported"
|
msgid "Imported"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:48
|
#: xpack/plugins/cloud/manager.py:51
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Task \"%s\" starts executing"
|
msgid "Task \"%s\" starts executing"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:87
|
#: xpack/plugins/cloud/manager.py:90
|
||||||
msgid "View the task details path: "
|
msgid "View the task details path: "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:90
|
#: xpack/plugins/cloud/manager.py:93
|
||||||
msgid "Account Details"
|
msgid "Account Details"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:91
|
#: xpack/plugins/cloud/manager.py:94
|
||||||
msgid "Synchronization History List"
|
msgid "Synchronization History List"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:91
|
#: xpack/plugins/cloud/manager.py:94
|
||||||
msgid "Synchronization Instance List"
|
msgid "Synchronization Instance List"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:95
|
#: xpack/plugins/cloud/manager.py:98
|
||||||
msgid "To be released"
|
msgid "To be released"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:99
|
#: xpack/plugins/cloud/manager.py:102
|
||||||
msgid "Task execution completed"
|
msgid "Task execution completed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:104
|
#: xpack/plugins/cloud/manager.py:107
|
||||||
msgid "Synchronization regions"
|
msgid "Synchronization regions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:129
|
#: xpack/plugins/cloud/manager.py:132
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Get instances of region \"%s\" error, error: %s"
|
msgid "Get instances of region \"%s\" error, error: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:175
|
#: xpack/plugins/cloud/manager.py:178
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to synchronize the instance \"%s\""
|
msgid "Failed to synchronize the instance \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -9858,42 +9859,42 @@ msgid ""
|
||||||
"platform type. Skip platform and protocol updates"
|
"platform type. Skip platform and protocol updates"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:399
|
#: xpack/plugins/cloud/manager.py:406
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "The asset \"%s\" already exists"
|
msgid "The asset \"%s\" already exists"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:401
|
#: xpack/plugins/cloud/manager.py:408
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Update asset \"%s\""
|
msgid "Update asset \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:404
|
#: xpack/plugins/cloud/manager.py:411
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Asset \"%s\" has been updated"
|
msgid "Asset \"%s\" has been updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:413
|
#: xpack/plugins/cloud/manager.py:420
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Prepare to create asset \"%s\""
|
msgid "Prepare to create asset \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:434
|
#: xpack/plugins/cloud/manager.py:441
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Set nodes \"%s\""
|
msgid "Set nodes \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:460
|
#: xpack/plugins/cloud/manager.py:467
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Set accounts \"%s\""
|
msgid "Set accounts \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:476
|
#: xpack/plugins/cloud/manager.py:483
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Set protocols \"%s\""
|
msgid "Set protocols \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:490 xpack/plugins/cloud/tasks.py:31
|
#: xpack/plugins/cloud/manager.py:497 xpack/plugins/cloud/tasks.py:31
|
||||||
msgid "Run sync instance task"
|
msgid "Run sync instance task"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -10287,74 +10288,78 @@ msgstr "Access key id"
|
||||||
msgid "Subscription ID"
|
msgid "Subscription ID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:98
|
#: xpack/plugins/cloud/serializers/account_attrs.py:74
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:102
|
msgid "Auto node classification"
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:126
|
msgstr ""
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:156
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:206
|
#: xpack/plugins/cloud/serializers/account_attrs.py:99
|
||||||
|
#: xpack/plugins/cloud/serializers/account_attrs.py:103
|
||||||
|
#: xpack/plugins/cloud/serializers/account_attrs.py:127
|
||||||
|
#: xpack/plugins/cloud/serializers/account_attrs.py:157
|
||||||
|
#: xpack/plugins/cloud/serializers/account_attrs.py:207
|
||||||
msgid "API Endpoint"
|
msgid "API Endpoint"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:108
|
#: xpack/plugins/cloud/serializers/account_attrs.py:109
|
||||||
msgid "Auth url"
|
msgid "Auth url"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:109
|
#: xpack/plugins/cloud/serializers/account_attrs.py:110
|
||||||
msgid "eg: http://openstack.example.com:5000/v3"
|
msgid "eg: http://openstack.example.com:5000/v3"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:112
|
#: xpack/plugins/cloud/serializers/account_attrs.py:113
|
||||||
msgid "User domain"
|
msgid "User domain"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:127
|
#: xpack/plugins/cloud/serializers/account_attrs.py:128
|
||||||
msgid "Cert File"
|
msgid "Cert File"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:128
|
#: xpack/plugins/cloud/serializers/account_attrs.py:129
|
||||||
msgid "Key File"
|
msgid "Key File"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:144
|
#: xpack/plugins/cloud/serializers/account_attrs.py:145
|
||||||
msgid "Service account key"
|
msgid "Service account key"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:145
|
#: xpack/plugins/cloud/serializers/account_attrs.py:146
|
||||||
msgid "The file is in JSON format"
|
msgid "The file is in JSON format"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:163
|
#: xpack/plugins/cloud/serializers/account_attrs.py:164
|
||||||
msgid "IP address invalid `{}`, {}"
|
msgid "IP address invalid `{}`, {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:179
|
#: xpack/plugins/cloud/serializers/account_attrs.py:180
|
||||||
msgid "Such as: 192.168.1.0/24, 10.0.0.0-10.0.0.255"
|
msgid "Such as: 192.168.1.0/24, 10.0.0.0-10.0.0.255"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:182
|
#: xpack/plugins/cloud/serializers/account_attrs.py:183
|
||||||
msgid ""
|
msgid ""
|
||||||
"The port is used to detect the validity of the IP address. When the "
|
"The port is used to detect the validity of the IP address. When the "
|
||||||
"synchronization task is executed, only the valid IP address will be "
|
"synchronization task is executed, only the valid IP address will be "
|
||||||
"synchronized. <br>If the port is 0, all IP addresses are valid."
|
"synchronized. <br>If the port is 0, all IP addresses are valid."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:190
|
#: xpack/plugins/cloud/serializers/account_attrs.py:191
|
||||||
msgid "Hostname prefix"
|
msgid "Hostname prefix"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:193
|
#: xpack/plugins/cloud/serializers/account_attrs.py:194
|
||||||
msgid "IP segment"
|
msgid "IP segment"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:197
|
#: xpack/plugins/cloud/serializers/account_attrs.py:198
|
||||||
msgid "Test port"
|
msgid "Test port"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:200
|
#: xpack/plugins/cloud/serializers/account_attrs.py:201
|
||||||
msgid "Test timeout"
|
msgid "Test timeout"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:216
|
#: xpack/plugins/cloud/serializers/account_attrs.py:217
|
||||||
msgid "Project"
|
msgid "Project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-12-19 15:10+0800\n"
|
"POT-Creation-Date: 2025-01-08 14:25+0800\n"
|
||||||
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
||||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||||
|
@ -364,7 +364,7 @@ msgstr "用户 %s 查看/导出 了密码"
|
||||||
#: accounts/serializers/automations/change_secret.py:150
|
#: accounts/serializers/automations/change_secret.py:150
|
||||||
#: accounts/templates/accounts/asset_account_change_info.html:7
|
#: accounts/templates/accounts/asset_account_change_info.html:7
|
||||||
#: accounts/templates/accounts/change_secret_failed_info.html:11
|
#: accounts/templates/accounts/change_secret_failed_info.html:11
|
||||||
#: acls/serializers/base.py:123 assets/models/asset/common.py:102
|
#: acls/serializers/base.py:130 assets/models/asset/common.py:102
|
||||||
#: assets/models/asset/common.py:362 assets/models/cmd_filter.py:36
|
#: assets/models/asset/common.py:362 assets/models/cmd_filter.py:36
|
||||||
#: audits/models.py:58 authentication/models/connection_token.py:36
|
#: audits/models.py:58 authentication/models/connection_token.py:36
|
||||||
#: perms/models/asset_permission.py:69 terminal/backends/command/models.py:17
|
#: perms/models/asset_permission.py:69 terminal/backends/command/models.py:17
|
||||||
|
@ -407,7 +407,7 @@ msgstr "来源 ID"
|
||||||
#: accounts/serializers/automations/change_secret.py:120
|
#: accounts/serializers/automations/change_secret.py:120
|
||||||
#: accounts/serializers/automations/change_secret.py:151
|
#: accounts/serializers/automations/change_secret.py:151
|
||||||
#: accounts/templates/accounts/change_secret_failed_info.html:12
|
#: accounts/templates/accounts/change_secret_failed_info.html:12
|
||||||
#: acls/serializers/base.py:124
|
#: acls/serializers/base.py:131
|
||||||
#: acls/templates/acls/asset_login_reminder.html:10
|
#: acls/templates/acls/asset_login_reminder.html:10
|
||||||
#: assets/serializers/gateway.py:33 audits/models.py:59
|
#: assets/serializers/gateway.py:33 audits/models.py:59
|
||||||
#: authentication/api/connection_token.py:459 ops/models/base.py:18
|
#: authentication/api/connection_token.py:459 ops/models/base.py:18
|
||||||
|
@ -512,7 +512,7 @@ msgid "Trigger mode"
|
||||||
msgstr "触发模式"
|
msgstr "触发模式"
|
||||||
|
|
||||||
#: accounts/models/automations/backup_account.py:140 audits/models.py:203
|
#: accounts/models/automations/backup_account.py:140 audits/models.py:203
|
||||||
#: terminal/models/session/sharing.py:125 xpack/plugins/cloud/manager.py:176
|
#: terminal/models/session/sharing.py:125 xpack/plugins/cloud/manager.py:179
|
||||||
#: xpack/plugins/cloud/models.py:231
|
#: xpack/plugins/cloud/models.py:231
|
||||||
msgid "Reason"
|
msgid "Reason"
|
||||||
msgstr "原因"
|
msgstr "原因"
|
||||||
|
@ -937,7 +937,7 @@ msgstr "已修改"
|
||||||
#: ops/models/job.py:155 ops/serializers/job.py:20
|
#: ops/models/job.py:155 ops/serializers/job.py:20
|
||||||
#: perms/serializers/permission.py:46
|
#: perms/serializers/permission.py:46
|
||||||
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
|
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
|
||||||
#: xpack/plugins/cloud/manager.py:89
|
#: xpack/plugins/cloud/manager.py:92
|
||||||
msgid "Assets"
|
msgid "Assets"
|
||||||
msgstr "资产"
|
msgstr "资产"
|
||||||
|
|
||||||
|
@ -964,7 +964,7 @@ msgstr "特殊信息"
|
||||||
msgid "ID"
|
msgid "ID"
|
||||||
msgstr "ID"
|
msgstr "ID"
|
||||||
|
|
||||||
#: accounts/serializers/account/account.py:475 acls/serializers/base.py:116
|
#: accounts/serializers/account/account.py:475 acls/serializers/base.py:123
|
||||||
#: acls/templates/acls/asset_login_reminder.html:8
|
#: acls/templates/acls/asset_login_reminder.html:8
|
||||||
#: acls/templates/acls/user_login_reminder.html:8
|
#: acls/templates/acls/user_login_reminder.html:8
|
||||||
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:54
|
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:54
|
||||||
|
@ -972,7 +972,7 @@ msgstr "ID"
|
||||||
#: audits/serializers.py:195 authentication/models/connection_token.py:32
|
#: audits/serializers.py:195 authentication/models/connection_token.py:32
|
||||||
#: authentication/models/ssh_key.py:22 authentication/models/sso_token.py:16
|
#: authentication/models/ssh_key.py:22 authentication/models/sso_token.py:16
|
||||||
#: notifications/models/notification.py:12
|
#: notifications/models/notification.py:12
|
||||||
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:63
|
#: perms/api/user_permission/mixin.py:58 perms/models/asset_permission.py:63
|
||||||
#: rbac/builtin.py:125 rbac/models/rolebinding.py:49
|
#: rbac/builtin.py:125 rbac/models/rolebinding.py:49
|
||||||
#: rbac/serializers/rolebinding.py:17 terminal/backends/command/models.py:16
|
#: rbac/serializers/rolebinding.py:17 terminal/backends/command/models.py:16
|
||||||
#: terminal/models/session/session.py:31 terminal/models/session/sharing.py:34
|
#: terminal/models/session/session.py:31 terminal/models/session/sharing.py:34
|
||||||
|
@ -1519,15 +1519,15 @@ msgstr ""
|
||||||
msgid "IP/Host"
|
msgid "IP/Host"
|
||||||
msgstr "IP/主机"
|
msgstr "IP/主机"
|
||||||
|
|
||||||
#: acls/serializers/base.py:91
|
#: acls/serializers/base.py:98
|
||||||
msgid "Recipients"
|
msgid "Recipients"
|
||||||
msgstr "接收人"
|
msgstr "接收人"
|
||||||
|
|
||||||
#: acls/serializers/base.py:103 tickets/serializers/ticket/ticket.py:77
|
#: acls/serializers/base.py:110 tickets/serializers/ticket/ticket.py:77
|
||||||
msgid "The organization `{}` does not exist"
|
msgid "The organization `{}` does not exist"
|
||||||
msgstr "组织 `{}` 不存在"
|
msgstr "组织 `{}` 不存在"
|
||||||
|
|
||||||
#: acls/serializers/base.py:109
|
#: acls/serializers/base.py:116
|
||||||
msgid "None of the reviewers belong to Organization `{}`"
|
msgid "None of the reviewers belong to Organization `{}`"
|
||||||
msgstr "所有复核人都不属于组织 `{}`"
|
msgstr "所有复核人都不属于组织 `{}`"
|
||||||
|
|
||||||
|
@ -1742,7 +1742,7 @@ msgstr "脚本"
|
||||||
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:76
|
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:76
|
||||||
#: settings/serializers/feature.py:80 settings/serializers/feature.py:93
|
#: settings/serializers/feature.py:80 settings/serializers/feature.py:93
|
||||||
#: settings/serializers/msg.py:30 terminal/models/component/endpoint.py:14
|
#: settings/serializers/msg.py:30 terminal/models/component/endpoint.py:14
|
||||||
#: terminal/serializers/applet.py:17 xpack/plugins/cloud/manager.py:89
|
#: terminal/serializers/applet.py:17 xpack/plugins/cloud/manager.py:92
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:72
|
#: xpack/plugins/cloud/serializers/account_attrs.py:72
|
||||||
msgid "Host"
|
msgid "Host"
|
||||||
msgstr "主机"
|
msgstr "主机"
|
||||||
|
@ -2794,7 +2794,7 @@ msgstr "映射目录"
|
||||||
#: audits/const.py:23 rbac/tree.py:268 terminal/api/session/session.py:284
|
#: audits/const.py:23 rbac/tree.py:268 terminal/api/session/session.py:284
|
||||||
#: terminal/templates/terminal/_msg_command_warning.html:18
|
#: terminal/templates/terminal/_msg_command_warning.html:18
|
||||||
#: terminal/templates/terminal/_msg_session_sharing.html:10
|
#: terminal/templates/terminal/_msg_session_sharing.html:10
|
||||||
#: xpack/plugins/cloud/manager.py:90
|
#: xpack/plugins/cloud/manager.py:93
|
||||||
msgid "View"
|
msgid "View"
|
||||||
msgstr "查看"
|
msgstr "查看"
|
||||||
|
|
||||||
|
@ -3002,7 +3002,7 @@ msgid "Creator"
|
||||||
msgstr "创建者"
|
msgstr "创建者"
|
||||||
|
|
||||||
#: audits/serializers.py:39 ops/models/base.py:52 ops/models/job.py:240
|
#: audits/serializers.py:39 ops/models/base.py:52 ops/models/job.py:240
|
||||||
#: xpack/plugins/cloud/manager.py:99
|
#: xpack/plugins/cloud/manager.py:102
|
||||||
msgid "Summary"
|
msgid "Summary"
|
||||||
msgstr "汇总"
|
msgstr "汇总"
|
||||||
|
|
||||||
|
@ -3181,7 +3181,7 @@ msgid "No available face feature"
|
||||||
msgstr "没有可用的人脸特征"
|
msgstr "没有可用的人脸特征"
|
||||||
|
|
||||||
#: authentication/api/face.py:100 authentication/mfa/face.py:21
|
#: authentication/api/face.py:100 authentication/mfa/face.py:21
|
||||||
#: authentication/mfa/face.py:23
|
#: authentication/mfa/face.py:23 users/views/profile/face.py:72
|
||||||
msgid "Facial comparison failed"
|
msgid "Facial comparison failed"
|
||||||
msgstr "人脸比对失败"
|
msgstr "人脸比对失败"
|
||||||
|
|
||||||
|
@ -3500,11 +3500,11 @@ msgstr "自定义 MFA 全局开启,无法被禁用"
|
||||||
msgid "Face Recognition"
|
msgid "Face Recognition"
|
||||||
msgstr "人脸识别"
|
msgstr "人脸识别"
|
||||||
|
|
||||||
#: authentication/mfa/face.py:54
|
#: authentication/mfa/face.py:55
|
||||||
msgid "Bind face to enable"
|
msgid "Bind face to enable"
|
||||||
msgstr "绑定人脸特征以启用"
|
msgstr "绑定人脸特征以启用"
|
||||||
|
|
||||||
#: authentication/mfa/face.py:58
|
#: authentication/mfa/face.py:59
|
||||||
msgid "Unbind face to disable"
|
msgid "Unbind face to disable"
|
||||||
msgstr "解绑人脸特征以禁用"
|
msgstr "解绑人脸特征以禁用"
|
||||||
|
|
||||||
|
@ -3679,13 +3679,13 @@ msgstr "私有令牌"
|
||||||
|
|
||||||
#: authentication/models/ssh_key.py:15 terminal/serializers/storage.py:146
|
#: authentication/models/ssh_key.py:15 terminal/serializers/storage.py:146
|
||||||
#: users/models/user/__init__.py:93
|
#: users/models/user/__init__.py:93
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:213
|
#: xpack/plugins/cloud/serializers/account_attrs.py:214
|
||||||
msgid "Private key"
|
msgid "Private key"
|
||||||
msgstr "ssh私钥"
|
msgstr "ssh私钥"
|
||||||
|
|
||||||
#: authentication/models/ssh_key.py:18 settings/serializers/terminal.py:34
|
#: authentication/models/ssh_key.py:18 settings/serializers/terminal.py:34
|
||||||
#: users/forms/profile.py:175 users/models/user/__init__.py:96
|
#: users/forms/profile.py:175 users/models/user/__init__.py:96
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:210
|
#: xpack/plugins/cloud/serializers/account_attrs.py:211
|
||||||
msgid "Public key"
|
msgid "Public key"
|
||||||
msgstr "SSH公钥"
|
msgstr "SSH公钥"
|
||||||
|
|
||||||
|
@ -4130,15 +4130,15 @@ msgstr "跳转中"
|
||||||
msgid "Redirecting to {} authentication"
|
msgid "Redirecting to {} authentication"
|
||||||
msgstr "正在跳转到 {} 认证"
|
msgstr "正在跳转到 {} 认证"
|
||||||
|
|
||||||
#: authentication/views/login.py:243
|
#: authentication/views/login.py:247
|
||||||
msgid "Login timeout, please try again."
|
msgid "Login timeout, please try again."
|
||||||
msgstr "登录超时,请重新登录"
|
msgstr "登录超时,请重新登录"
|
||||||
|
|
||||||
#: authentication/views/login.py:288
|
#: authentication/views/login.py:292
|
||||||
msgid "User email already exists ({})"
|
msgid "User email already exists ({})"
|
||||||
msgstr "用户邮箱已存在 ({})"
|
msgstr "用户邮箱已存在 ({})"
|
||||||
|
|
||||||
#: authentication/views/login.py:366
|
#: authentication/views/login.py:370
|
||||||
msgid ""
|
msgid ""
|
||||||
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
|
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
|
||||||
" Don't close this page"
|
" Don't close this page"
|
||||||
|
@ -4146,15 +4146,15 @@ msgstr ""
|
||||||
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
|
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
|
||||||
" 不要关闭本页面"
|
" 不要关闭本页面"
|
||||||
|
|
||||||
#: authentication/views/login.py:371
|
#: authentication/views/login.py:375
|
||||||
msgid "No ticket found"
|
msgid "No ticket found"
|
||||||
msgstr "没有发现工单"
|
msgstr "没有发现工单"
|
||||||
|
|
||||||
#: authentication/views/login.py:407
|
#: authentication/views/login.py:411
|
||||||
msgid "Logout success"
|
msgid "Logout success"
|
||||||
msgstr "退出登录成功"
|
msgstr "退出登录成功"
|
||||||
|
|
||||||
#: authentication/views/login.py:408
|
#: authentication/views/login.py:412
|
||||||
msgid "Logout success, return login page"
|
msgid "Logout success, return login page"
|
||||||
msgstr "退出登录成功,返回到登录页面"
|
msgstr "退出登录成功,返回到登录页面"
|
||||||
|
|
||||||
|
@ -4245,7 +4245,7 @@ msgstr "企业专业版"
|
||||||
msgid "Ultimate edition"
|
msgid "Ultimate edition"
|
||||||
msgstr "企业旗舰版"
|
msgstr "企业旗舰版"
|
||||||
|
|
||||||
#: common/const/common.py:5 xpack/plugins/cloud/manager.py:417
|
#: common/const/common.py:5 xpack/plugins/cloud/manager.py:424
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s was created successfully"
|
msgid "%(name)s was created successfully"
|
||||||
msgstr "%(name)s 创建成功"
|
msgstr "%(name)s 创建成功"
|
||||||
|
@ -4309,8 +4309,8 @@ msgstr "无效的ID,应为列表"
|
||||||
#: common/serializers/fields.py:144 terminal/serializers/session.py:81
|
#: common/serializers/fields.py:144 terminal/serializers/session.py:81
|
||||||
#: tickets/serializers/ticket/common.py:58
|
#: tickets/serializers/ticket/common.py:58
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:56
|
#: xpack/plugins/cloud/serializers/account_attrs.py:56
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:79
|
#: xpack/plugins/cloud/serializers/account_attrs.py:80
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:150
|
#: xpack/plugins/cloud/serializers/account_attrs.py:151
|
||||||
msgid "This field is required."
|
msgid "This field is required."
|
||||||
msgstr "该字段是必填项。"
|
msgstr "该字段是必填项。"
|
||||||
|
|
||||||
|
@ -5134,12 +5134,13 @@ msgstr "变量名"
|
||||||
|
|
||||||
#: ops/models/variable.py:12 ops/serializers/variable.py:23
|
#: ops/models/variable.py:12 ops/serializers/variable.py:23
|
||||||
msgid ""
|
msgid ""
|
||||||
"The variable name used in the script has a fixed prefix 'jms_' followed by "
|
"The variable name used in the script will have a fixed prefix jms_ added to "
|
||||||
"the input variable name. For example, if the variable name is 'name,' the "
|
"the input variable name. For example, if the input variable name is name, "
|
||||||
"final generated environment variable will be 'jms_name'."
|
"the resulting environment variable will be jms_name, and it can be "
|
||||||
|
"referenced in the script using {{ jms_name }}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"在脚本使用的变量名称,固定前缀 jms_ + 输入的变量名,例如变量名name,则最终生"
|
"在脚本使用的变量名称,固定前缀 jms_ + 输入的变量名,例如变量名name,则最终生"
|
||||||
"成环境变量为 jms_name"
|
"成环境变量为 jms_name,在脚本中引用时使用 {{ jms_name }}"
|
||||||
|
|
||||||
#: ops/models/variable.py:16 ops/serializers/variable.py:31
|
#: ops/models/variable.py:16 ops/serializers/variable.py:31
|
||||||
msgid "Default Value"
|
msgid "Default Value"
|
||||||
|
@ -5225,11 +5226,11 @@ msgid ""
|
||||||
"is the value."
|
"is the value."
|
||||||
msgstr "每项单独一行,每行可以用英文冒号分割前边是显示的内容后边是值"
|
msgstr "每项单独一行,每行可以用英文冒号分割前边是显示的内容后边是值"
|
||||||
|
|
||||||
#: ops/tasks.py:53
|
#: ops/tasks.py:54
|
||||||
msgid "Run ansible task"
|
msgid "Run ansible task"
|
||||||
msgstr "运行 Ansible 任务"
|
msgstr "运行 Ansible 任务"
|
||||||
|
|
||||||
#: ops/tasks.py:56
|
#: ops/tasks.py:57
|
||||||
msgid ""
|
msgid ""
|
||||||
"Execute scheduled adhoc and playbooks, periodically invoking the task for "
|
"Execute scheduled adhoc and playbooks, periodically invoking the task for "
|
||||||
"execution"
|
"execution"
|
||||||
|
@ -5243,19 +5244,19 @@ msgstr "开始执行 Ansible 任务"
|
||||||
msgid "Execute the task when manually adhoc or playbooks"
|
msgid "Execute the task when manually adhoc or playbooks"
|
||||||
msgstr "手动执行快捷命令,playbook时执行该任务"
|
msgstr "手动执行快捷命令,playbook时执行该任务"
|
||||||
|
|
||||||
#: ops/tasks.py:107
|
#: ops/tasks.py:106
|
||||||
msgid "Clear celery periodic tasks"
|
msgid "Clear celery periodic tasks"
|
||||||
msgstr "清理周期任务"
|
msgstr "清理周期任务"
|
||||||
|
|
||||||
#: ops/tasks.py:109
|
#: ops/tasks.py:108
|
||||||
msgid "At system startup, clean up celery tasks that no longer exist"
|
msgid "At system startup, clean up celery tasks that no longer exist"
|
||||||
msgstr "系统启动时,清理已经不存在的celery任务"
|
msgstr "系统启动时,清理已经不存在的celery任务"
|
||||||
|
|
||||||
#: ops/tasks.py:133
|
#: ops/tasks.py:132
|
||||||
msgid "Create or update periodic tasks"
|
msgid "Create or update periodic tasks"
|
||||||
msgstr "创建或更新周期任务"
|
msgstr "创建或更新周期任务"
|
||||||
|
|
||||||
#: ops/tasks.py:135
|
#: ops/tasks.py:134
|
||||||
msgid ""
|
msgid ""
|
||||||
"With version iterations, new tasks may be added, or task names and execution "
|
"With version iterations, new tasks may be added, or task names and execution "
|
||||||
"times may \n"
|
"times may \n"
|
||||||
|
@ -5266,11 +5267,11 @@ msgstr ""
|
||||||
"随着版本迭代,可能会新增任务或者修改任务的名称,执行时间,所以在系统启动时,"
|
"随着版本迭代,可能会新增任务或者修改任务的名称,执行时间,所以在系统启动时,"
|
||||||
"将会注册任务或者更新定时任务参数"
|
"将会注册任务或者更新定时任务参数"
|
||||||
|
|
||||||
#: ops/tasks.py:148
|
#: ops/tasks.py:147
|
||||||
msgid "Periodic check service performance"
|
msgid "Periodic check service performance"
|
||||||
msgstr "周期检测服务性能"
|
msgstr "周期检测服务性能"
|
||||||
|
|
||||||
#: ops/tasks.py:150
|
#: ops/tasks.py:149
|
||||||
msgid ""
|
msgid ""
|
||||||
"Check every hour whether each component is offline and whether the CPU, "
|
"Check every hour whether each component is offline and whether the CPU, "
|
||||||
"memory, \n"
|
"memory, \n"
|
||||||
|
@ -5280,11 +5281,11 @@ msgstr ""
|
||||||
"每小时检测各组件是否离线,cpu,内存,硬盘使用率是否超过阈值,向管理员发送消息"
|
"每小时检测各组件是否离线,cpu,内存,硬盘使用率是否超过阈值,向管理员发送消息"
|
||||||
"预警"
|
"预警"
|
||||||
|
|
||||||
#: ops/tasks.py:160
|
#: ops/tasks.py:159
|
||||||
msgid "Clean up unexpected jobs"
|
msgid "Clean up unexpected jobs"
|
||||||
msgstr "清理异常作业"
|
msgstr "清理异常作业"
|
||||||
|
|
||||||
#: ops/tasks.py:162
|
#: ops/tasks.py:161
|
||||||
msgid ""
|
msgid ""
|
||||||
"Due to exceptions caused by executing adhoc and playbooks in the Job "
|
"Due to exceptions caused by executing adhoc and playbooks in the Job "
|
||||||
"Center, \n"
|
"Center, \n"
|
||||||
|
@ -5297,11 +5298,11 @@ msgstr ""
|
||||||
"由于作业中心执行快捷命令,playbook会产生异常,任务状态未更新完成,系统将每小"
|
"由于作业中心执行快捷命令,playbook会产生异常,任务状态未更新完成,系统将每小"
|
||||||
"时执行清理超3小时未完成的异常作业,并将任务标记失败"
|
"时执行清理超3小时未完成的异常作业,并将任务标记失败"
|
||||||
|
|
||||||
#: ops/tasks.py:175
|
#: ops/tasks.py:174
|
||||||
msgid "Clean job_execution db record"
|
msgid "Clean job_execution db record"
|
||||||
msgstr "清理作业中心执行历史"
|
msgstr "清理作业中心执行历史"
|
||||||
|
|
||||||
#: ops/tasks.py:177
|
#: ops/tasks.py:176
|
||||||
msgid ""
|
msgid ""
|
||||||
"Due to the execution of adhoc and playbooks in the Job Center, execution "
|
"Due to the execution of adhoc and playbooks in the Job Center, execution "
|
||||||
"records will \n"
|
"records will \n"
|
||||||
|
@ -5755,7 +5756,7 @@ msgstr "系统设置"
|
||||||
msgid "Session audits"
|
msgid "Session audits"
|
||||||
msgstr "会话审计"
|
msgstr "会话审计"
|
||||||
|
|
||||||
#: rbac/tree.py:49 xpack/plugins/cloud/manager.py:90
|
#: rbac/tree.py:49 xpack/plugins/cloud/manager.py:93
|
||||||
msgid "Cloud import"
|
msgid "Cloud import"
|
||||||
msgstr "云同步"
|
msgstr "云同步"
|
||||||
|
|
||||||
|
@ -5798,7 +5799,7 @@ msgid "Appearance"
|
||||||
msgstr "界面"
|
msgstr "界面"
|
||||||
|
|
||||||
#: rbac/tree.py:65 xpack/plugins/license/meta.py:10
|
#: rbac/tree.py:65 xpack/plugins/license/meta.py:10
|
||||||
#: xpack/plugins/license/models.py:151
|
#: xpack/plugins/license/models.py:153
|
||||||
msgid "License"
|
msgid "License"
|
||||||
msgstr "许可证"
|
msgstr "许可证"
|
||||||
|
|
||||||
|
@ -6543,7 +6544,7 @@ msgid "SSO auth key TTL"
|
||||||
msgstr "令牌有效期"
|
msgstr "令牌有效期"
|
||||||
|
|
||||||
#: settings/serializers/auth/sso.py:20
|
#: settings/serializers/auth/sso.py:20
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:200
|
#: xpack/plugins/cloud/serializers/account_attrs.py:201
|
||||||
msgid "Unit: second"
|
msgid "Unit: second"
|
||||||
msgstr "单位: 秒"
|
msgstr "单位: 秒"
|
||||||
|
|
||||||
|
@ -6705,7 +6706,7 @@ msgid "Tenant ID"
|
||||||
msgstr "租户 ID"
|
msgstr "租户 ID"
|
||||||
|
|
||||||
#: settings/serializers/feature.py:109 terminal/serializers/storage.py:68
|
#: settings/serializers/feature.py:109 terminal/serializers/storage.py:68
|
||||||
#: xpack/plugins/cloud/manager.py:107 xpack/plugins/cloud/manager.py:112
|
#: xpack/plugins/cloud/manager.py:110 xpack/plugins/cloud/manager.py:115
|
||||||
#: xpack/plugins/cloud/models.py:287
|
#: xpack/plugins/cloud/models.py:287
|
||||||
msgid "Region"
|
msgid "Region"
|
||||||
msgstr "地域"
|
msgstr "地域"
|
||||||
|
@ -7639,7 +7640,7 @@ msgstr "无法删除正在使用的存储: {}"
|
||||||
msgid "Command storages"
|
msgid "Command storages"
|
||||||
msgstr "命令存储"
|
msgstr "命令存储"
|
||||||
|
|
||||||
#: terminal/api/component/storage.py:84 xpack/plugins/cloud/manager.py:107
|
#: terminal/api/component/storage.py:84 xpack/plugins/cloud/manager.py:110
|
||||||
msgid "Invalid"
|
msgid "Invalid"
|
||||||
msgstr "无效"
|
msgstr "无效"
|
||||||
|
|
||||||
|
@ -9809,7 +9810,7 @@ msgstr "重定向到 JumpServer 客户端"
|
||||||
msgid "Face binding successful"
|
msgid "Face binding successful"
|
||||||
msgstr "绑定人脸特征成功"
|
msgstr "绑定人脸特征成功"
|
||||||
|
|
||||||
#: users/views/profile/face.py:80 users/views/profile/face.py:81
|
#: users/views/profile/face.py:82 users/views/profile/face.py:83
|
||||||
msgid "Face unbinding successful"
|
msgid "Face unbinding successful"
|
||||||
msgstr "解绑人脸特征成功"
|
msgstr "解绑人脸特征成功"
|
||||||
|
|
||||||
|
@ -10005,19 +10006,19 @@ msgstr "实例名称和部分IP"
|
||||||
msgid "Succeed"
|
msgid "Succeed"
|
||||||
msgstr "成功"
|
msgstr "成功"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/const.py:52 xpack/plugins/cloud/manager.py:95
|
#: xpack/plugins/cloud/const.py:52 xpack/plugins/cloud/manager.py:98
|
||||||
msgid "Unsync"
|
msgid "Unsync"
|
||||||
msgstr "未同步"
|
msgstr "未同步"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/const.py:53 xpack/plugins/cloud/manager.py:94
|
#: xpack/plugins/cloud/const.py:53 xpack/plugins/cloud/manager.py:97
|
||||||
msgid "New Sync"
|
msgid "New Sync"
|
||||||
msgstr "新同步"
|
msgstr "新同步"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/const.py:54 xpack/plugins/cloud/manager.py:94
|
#: xpack/plugins/cloud/const.py:54 xpack/plugins/cloud/manager.py:97
|
||||||
msgid "Synced"
|
msgid "Synced"
|
||||||
msgstr "已同步"
|
msgstr "已同步"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/const.py:55 xpack/plugins/cloud/manager.py:96
|
#: xpack/plugins/cloud/const.py:55 xpack/plugins/cloud/manager.py:99
|
||||||
msgid "Released"
|
msgid "Released"
|
||||||
msgstr "已释放"
|
msgstr "已释放"
|
||||||
|
|
||||||
|
@ -10037,45 +10038,45 @@ msgstr "已同步组织"
|
||||||
msgid "Imported"
|
msgid "Imported"
|
||||||
msgstr "导入"
|
msgstr "导入"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:48
|
#: xpack/plugins/cloud/manager.py:51
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Task \"%s\" starts executing"
|
msgid "Task \"%s\" starts executing"
|
||||||
msgstr "任务 \"%s\" 开始执行"
|
msgstr "任务 \"%s\" 开始执行"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:87
|
#: xpack/plugins/cloud/manager.py:90
|
||||||
msgid "View the task details path: "
|
msgid "View the task details path: "
|
||||||
msgstr "查看详情"
|
msgstr "查看详情"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:90
|
#: xpack/plugins/cloud/manager.py:93
|
||||||
msgid "Account Details"
|
msgid "Account Details"
|
||||||
msgstr "账号"
|
msgstr "账号"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:91
|
#: xpack/plugins/cloud/manager.py:94
|
||||||
msgid "Synchronization History List"
|
msgid "Synchronization History List"
|
||||||
msgstr "同步历史列表"
|
msgstr "同步历史列表"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:91
|
#: xpack/plugins/cloud/manager.py:94
|
||||||
msgid "Synchronization Instance List"
|
msgid "Synchronization Instance List"
|
||||||
msgstr "同步实例列表"
|
msgstr "同步实例列表"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:95
|
#: xpack/plugins/cloud/manager.py:98
|
||||||
msgid "To be released"
|
msgid "To be released"
|
||||||
msgstr "待释放"
|
msgstr "待释放"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:99
|
#: xpack/plugins/cloud/manager.py:102
|
||||||
msgid "Task execution completed"
|
msgid "Task execution completed"
|
||||||
msgstr "任务执行完成"
|
msgstr "任务执行完成"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:104
|
#: xpack/plugins/cloud/manager.py:107
|
||||||
msgid "Synchronization regions"
|
msgid "Synchronization regions"
|
||||||
msgstr "同步地区"
|
msgstr "同步地区"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:129
|
#: xpack/plugins/cloud/manager.py:132
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Get instances of region \"%s\" error, error: %s"
|
msgid "Get instances of region \"%s\" error, error: %s"
|
||||||
msgstr "获取区域 \"%s\" 的实例错误,错误:%s"
|
msgstr "获取区域 \"%s\" 的实例错误,错误:%s"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:175
|
#: xpack/plugins/cloud/manager.py:178
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to synchronize the instance \"%s\""
|
msgid "Failed to synchronize the instance \"%s\""
|
||||||
msgstr "无法同步实例 %s"
|
msgstr "无法同步实例 %s"
|
||||||
|
@ -10087,42 +10088,42 @@ msgid ""
|
||||||
"platform type. Skip platform and protocol updates"
|
"platform type. Skip platform and protocol updates"
|
||||||
msgstr "资产“%s”的更新平台与原平台类型不一致。跳过平台和协议更新"
|
msgstr "资产“%s”的更新平台与原平台类型不一致。跳过平台和协议更新"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:399
|
#: xpack/plugins/cloud/manager.py:406
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "The asset \"%s\" already exists"
|
msgid "The asset \"%s\" already exists"
|
||||||
msgstr "资产 \"%s\" 已存在"
|
msgstr "资产 \"%s\" 已存在"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:401
|
#: xpack/plugins/cloud/manager.py:408
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Update asset \"%s\""
|
msgid "Update asset \"%s\""
|
||||||
msgstr "更新资产 \"%s\""
|
msgstr "更新资产 \"%s\""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:404
|
#: xpack/plugins/cloud/manager.py:411
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Asset \"%s\" has been updated"
|
msgid "Asset \"%s\" has been updated"
|
||||||
msgstr "资产 \"%s\" 已更新"
|
msgstr "资产 \"%s\" 已更新"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:413
|
#: xpack/plugins/cloud/manager.py:420
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Prepare to create asset \"%s\""
|
msgid "Prepare to create asset \"%s\""
|
||||||
msgstr "准备创建资产 %s"
|
msgstr "准备创建资产 %s"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:434
|
#: xpack/plugins/cloud/manager.py:441
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Set nodes \"%s\""
|
msgid "Set nodes \"%s\""
|
||||||
msgstr "删除节点: \"%s\""
|
msgstr "设置节点: \"%s\""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:460
|
#: xpack/plugins/cloud/manager.py:467
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Set accounts \"%s\""
|
msgid "Set accounts \"%s\""
|
||||||
msgstr "删除账号: %s"
|
msgstr "设置账号: %s"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:476
|
#: xpack/plugins/cloud/manager.py:483
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Set protocols \"%s\""
|
msgid "Set protocols \"%s\""
|
||||||
msgstr "设置协议 \"%s\""
|
msgstr "设置协议 \"%s\""
|
||||||
|
|
||||||
#: xpack/plugins/cloud/manager.py:490 xpack/plugins/cloud/tasks.py:31
|
#: xpack/plugins/cloud/manager.py:497 xpack/plugins/cloud/tasks.py:31
|
||||||
msgid "Run sync instance task"
|
msgid "Run sync instance task"
|
||||||
msgstr "执行同步实例任务"
|
msgstr "执行同步实例任务"
|
||||||
|
|
||||||
|
@ -10516,51 +10517,55 @@ msgstr "Access key id"
|
||||||
msgid "Subscription ID"
|
msgid "Subscription ID"
|
||||||
msgstr "订阅 ID"
|
msgstr "订阅 ID"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:98
|
#: xpack/plugins/cloud/serializers/account_attrs.py:74
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:102
|
msgid "Auto node classification"
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:126
|
msgstr "自动节点分类"
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:156
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:206
|
#: xpack/plugins/cloud/serializers/account_attrs.py:99
|
||||||
|
#: xpack/plugins/cloud/serializers/account_attrs.py:103
|
||||||
|
#: xpack/plugins/cloud/serializers/account_attrs.py:127
|
||||||
|
#: xpack/plugins/cloud/serializers/account_attrs.py:157
|
||||||
|
#: xpack/plugins/cloud/serializers/account_attrs.py:207
|
||||||
msgid "API Endpoint"
|
msgid "API Endpoint"
|
||||||
msgstr "API 端点"
|
msgstr "API 端点"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:108
|
#: xpack/plugins/cloud/serializers/account_attrs.py:109
|
||||||
msgid "Auth url"
|
msgid "Auth url"
|
||||||
msgstr "认证地址"
|
msgstr "认证地址"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:109
|
#: xpack/plugins/cloud/serializers/account_attrs.py:110
|
||||||
msgid "eg: http://openstack.example.com:5000/v3"
|
msgid "eg: http://openstack.example.com:5000/v3"
|
||||||
msgstr "如: http://openstack.example.com:5000/v3"
|
msgstr "如: http://openstack.example.com:5000/v3"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:112
|
#: xpack/plugins/cloud/serializers/account_attrs.py:113
|
||||||
msgid "User domain"
|
msgid "User domain"
|
||||||
msgstr "用户域"
|
msgstr "用户域"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:127
|
#: xpack/plugins/cloud/serializers/account_attrs.py:128
|
||||||
msgid "Cert File"
|
msgid "Cert File"
|
||||||
msgstr "证书文件"
|
msgstr "证书文件"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:128
|
#: xpack/plugins/cloud/serializers/account_attrs.py:129
|
||||||
msgid "Key File"
|
msgid "Key File"
|
||||||
msgstr "密钥文件"
|
msgstr "密钥文件"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:144
|
#: xpack/plugins/cloud/serializers/account_attrs.py:145
|
||||||
msgid "Service account key"
|
msgid "Service account key"
|
||||||
msgstr "服务账号密钥"
|
msgstr "服务账号密钥"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:145
|
#: xpack/plugins/cloud/serializers/account_attrs.py:146
|
||||||
msgid "The file is in JSON format"
|
msgid "The file is in JSON format"
|
||||||
msgstr "JSON 格式的文件"
|
msgstr "JSON 格式的文件"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:163
|
#: xpack/plugins/cloud/serializers/account_attrs.py:164
|
||||||
msgid "IP address invalid `{}`, {}"
|
msgid "IP address invalid `{}`, {}"
|
||||||
msgstr "IP 地址无效: `{}`, {}"
|
msgstr "IP 地址无效: `{}`, {}"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:179
|
#: xpack/plugins/cloud/serializers/account_attrs.py:180
|
||||||
msgid "Such as: 192.168.1.0/24, 10.0.0.0-10.0.0.255"
|
msgid "Such as: 192.168.1.0/24, 10.0.0.0-10.0.0.255"
|
||||||
msgstr "例: 192.168.1.0/24,10.0.0.0-10.0.0.255"
|
msgstr "例: 192.168.1.0/24,10.0.0.0-10.0.0.255"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:182
|
#: xpack/plugins/cloud/serializers/account_attrs.py:183
|
||||||
msgid ""
|
msgid ""
|
||||||
"The port is used to detect the validity of the IP address. When the "
|
"The port is used to detect the validity of the IP address. When the "
|
||||||
"synchronization task is executed, only the valid IP address will be "
|
"synchronization task is executed, only the valid IP address will be "
|
||||||
|
@ -10569,23 +10574,23 @@ msgstr ""
|
||||||
"端口用来检测 IP 地址的有效性,在同步任务执行时,只会同步有效的 IP 地址。 <br>"
|
"端口用来检测 IP 地址的有效性,在同步任务执行时,只会同步有效的 IP 地址。 <br>"
|
||||||
"如果端口为 0,则表示所有 IP 地址均有效。"
|
"如果端口为 0,则表示所有 IP 地址均有效。"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:190
|
#: xpack/plugins/cloud/serializers/account_attrs.py:191
|
||||||
msgid "Hostname prefix"
|
msgid "Hostname prefix"
|
||||||
msgstr "主机名前缀"
|
msgstr "主机名前缀"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:193
|
#: xpack/plugins/cloud/serializers/account_attrs.py:194
|
||||||
msgid "IP segment"
|
msgid "IP segment"
|
||||||
msgstr "IP 网段"
|
msgstr "IP 网段"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:197
|
#: xpack/plugins/cloud/serializers/account_attrs.py:198
|
||||||
msgid "Test port"
|
msgid "Test port"
|
||||||
msgstr "测试端口"
|
msgstr "测试端口"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:200
|
#: xpack/plugins/cloud/serializers/account_attrs.py:201
|
||||||
msgid "Test timeout"
|
msgid "Test timeout"
|
||||||
msgstr "测试超时时间"
|
msgstr "测试超时时间"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:216
|
#: xpack/plugins/cloud/serializers/account_attrs.py:217
|
||||||
msgid "Project"
|
msgid "Project"
|
||||||
msgstr "project"
|
msgstr "project"
|
||||||
|
|
||||||
|
@ -10678,3 +10683,9 @@ msgstr "许可证导入成功"
|
||||||
#: xpack/plugins/license/api.py:53
|
#: xpack/plugins/license/api.py:53
|
||||||
msgid "Invalid license"
|
msgid "Invalid license"
|
||||||
msgstr "许可证无效"
|
msgstr "许可证无效"
|
||||||
|
|
||||||
|
#~ msgid "Start sending backup emails"
|
||||||
|
#~ msgstr "发送备份邮件"
|
||||||
|
|
||||||
|
#~ msgid "domain_name"
|
||||||
|
#~ msgstr "域名"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -98,7 +98,7 @@
|
||||||
"AppletHelpText": "In the upload process, if the application does not exist, create the application; if it exists, update the application.",
|
"AppletHelpText": "In the upload process, if the application does not exist, create the application; if it exists, update the application.",
|
||||||
"AppletHostCreate": "Add RemoteApp machine",
|
"AppletHostCreate": "Add RemoteApp machine",
|
||||||
"AppletHostDetail": "RemoteApp machine",
|
"AppletHostDetail": "RemoteApp machine",
|
||||||
"AppletHostSelectHelpMessage": "When connecting to an asset, the selection of the application publishing machine is random (but the last used one is preferred). if you want to assign a specific publishing machine to an asset, you can tag it as <publishing machine: publishing machine name> or <applethost: publishing machine name>; <br>when selecting an account for the publishing machine, the following situations will choose the user's own <b>account with the same name or proprietary account (starting with js)</b>, otherwise use a public account (starting with jms):<br> 1. both the publishing machine and application support concurrent;<br> 2. the publishing machine supports concurrent, but the application does not, and the current application does not use a proprietary account;<br> 3. the publishing machine does not support concurrent, the application either supports or does not support concurrent, and no application uses a proprietary account;<br> note: whether the application supports concurrent connections is decided by the developer, and whether the host supports concurrent connections is decided by the single user single session setting in the publishing machine configuration",
|
"AppletHostSelectHelpMessage": "When connecting to an asset, the selection of the application publishing machine is random (but the last used one is preferred). if you want to assign a specific publishing machine to an asset, you can tag it as [publishing machine: publishing machine name] or [AppletHost: publishing machine name]; <br>when selecting an account for the publishing machine, the following situations will choose the user's own <b>account with the same name or proprietary account (starting with js)</b>, otherwise use a public account (starting with jms):<br> 1. both the publishing machine and application support concurrent;<br> 2. the publishing machine supports concurrent, but the application does not, and the current application does not use a proprietary account;<br> 3. the publishing machine does not support concurrent, the application either supports or does not support concurrent, and no application uses a proprietary account;<br> note: whether the application supports concurrent connections is decided by the developer, and whether the host supports concurrent connections is decided by the single user single session setting in the publishing machine configuration",
|
||||||
"AppletHostUpdate": "Update the remote app publishing machine",
|
"AppletHostUpdate": "Update the remote app publishing machine",
|
||||||
"AppletHostZoneHelpText": "This domain belongs to the system organization",
|
"AppletHostZoneHelpText": "This domain belongs to the system organization",
|
||||||
"AppletHosts": "RemoteApp machine",
|
"AppletHosts": "RemoteApp machine",
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
"AppletHelpText": "在上传过程中,如果应用不存在,则创建该应用;如果已存在,则进行应用更新。",
|
"AppletHelpText": "在上传过程中,如果应用不存在,则创建该应用;如果已存在,则进行应用更新。",
|
||||||
"AppletHostCreate": "添加远程应用发布机",
|
"AppletHostCreate": "添加远程应用发布机",
|
||||||
"AppletHostDetail": "远程应用发布机详情",
|
"AppletHostDetail": "远程应用发布机详情",
|
||||||
"AppletHostSelectHelpMessage": "连接资产时,应用发布机选择是随机的(但优先选择上次使用的),如果想为某个资产固定发布机,可以指定标签 <发布机:发布机名称> 或 <AppletHost:发布机名称>; <br>连接该发布机选择账号时,以下情况会选择用户的 <b>同名账号 或 专有账号(js开头)</b>,否则使用公用账号(jms开头):<br> 1. 发布机和应用都支持并发; <br> 2. 发布机支持并发,应用不支持并发,当前应用没有使用专有账号; <br> 3. 发布机不支持并发,应用支持并发或不支持,没有任一应用使用专有账号; <br> 注意: 应用支不支持并发是开发者决定,主机支不支持是发布机配置中的 单用户单会话决定",
|
"AppletHostSelectHelpMessage": "连接资产时,应用发布机选择是随机的(但优先选择上次使用的),如果想为某个资产固定发布机,可以指定标签 [发布机:发布机名称] 或 [AppletHost:发布机名称]; <br>连接该发布机选择账号时,以下情况会选择用户的 <b>同名账号 或 专有账号(js开头)</b>,否则使用公用账号(jms开头):<br> 1. 发布机和应用都支持并发; <br> 2. 发布机支持并发,应用不支持并发,当前应用没有使用专有账号; <br> 3. 发布机不支持并发,应用支持并发或不支持,没有任一应用使用专有账号; <br> 注意: 应用支不支持并发是开发者决定,主机支不支持是发布机配置中的 单用户单会话决定",
|
||||||
"AppletHostUpdate": "更新远程应用发布机",
|
"AppletHostUpdate": "更新远程应用发布机",
|
||||||
"AppletHostZoneHelpText": "这里的网域属于 System 组织",
|
"AppletHostZoneHelpText": "这里的网域属于 System 组织",
|
||||||
"AppletHosts": "应用发布机",
|
"AppletHosts": "应用发布机",
|
||||||
|
|
|
@ -71,6 +71,9 @@
|
||||||
"Expand all": "Expandir Tudo",
|
"Expand all": "Expandir Tudo",
|
||||||
"Expand all asset": "Expanda todos os ativos abaixo do nó",
|
"Expand all asset": "Expanda todos os ativos abaixo do nó",
|
||||||
"Expire time": "Tempo de Expiração",
|
"Expire time": "Tempo de Expiração",
|
||||||
|
"Face online required": "Este login precisa de verificação facial e monitoramento, deseja continuar?",
|
||||||
|
"Face verify required": "Este login requer verificação facial, deseja continuar? ",
|
||||||
|
"Face verify success": "Verificação facial bem-sucedida. ",
|
||||||
"Failed to open address": "Falha ao abrir o endereço",
|
"Failed to open address": "Falha ao abrir o endereço",
|
||||||
"Favorite": "Favoritos",
|
"Favorite": "Favoritos",
|
||||||
"File Manager": "Arquivo gerenciar",
|
"File Manager": "Arquivo gerenciar",
|
||||||
|
@ -121,6 +124,7 @@
|
||||||
"No": "Não",
|
"No": "Não",
|
||||||
"No account available": "Não há contas disponíveis",
|
"No account available": "Não há contas disponíveis",
|
||||||
"No available connect method": "Nenhum método de conexão disponível",
|
"No available connect method": "Nenhum método de conexão disponível",
|
||||||
|
"No facial features": "Não há características faciais disponíveis no momento, por favor, dirija-se à página de informações pessoais para vincular. ",
|
||||||
"No matching found": "Sem correspondências",
|
"No matching found": "Sem correspondências",
|
||||||
"No permission": "Sem permissão",
|
"No permission": "Sem permissão",
|
||||||
"No protocol available": "Não há protocolos disponíveis",
|
"No protocol available": "Não há protocolos disponíveis",
|
||||||
|
@ -168,7 +172,7 @@
|
||||||
"Send text to all ssh terminals": "Enviar texto para todos os terminais ssh",
|
"Send text to all ssh terminals": "Enviar texto para todos os terminais ssh",
|
||||||
"Set reusable": "Iniciar reutilização",
|
"Set reusable": "Iniciar reutilização",
|
||||||
"Setting": "Configurações",
|
"Setting": "Configurações",
|
||||||
"Settings or basic settings": "Menu 设置 → Configurações básicas",
|
"Settings or basic settings": "Menu configurar → Configurações básicas",
|
||||||
"ShareSession": "Compartilhamento de sessão",
|
"ShareSession": "Compartilhamento de sessão",
|
||||||
"Show left manager": "Mostrar Barra Lateral Esquerda",
|
"Show left manager": "Mostrar Barra Lateral Esquerda",
|
||||||
"Skip": "Pular",
|
"Skip": "Pular",
|
||||||
|
|
|
@ -290,7 +290,7 @@ class Config(dict):
|
||||||
'AUTH_LDAP_START_TLS': False,
|
'AUTH_LDAP_START_TLS': False,
|
||||||
'AUTH_LDAP_USER_ATTR_MAP': {"username": "cn", "name": "sn", "email": "mail"},
|
'AUTH_LDAP_USER_ATTR_MAP': {"username": "cn", "name": "sn", "email": "mail"},
|
||||||
'AUTH_LDAP_CONNECT_TIMEOUT': 10,
|
'AUTH_LDAP_CONNECT_TIMEOUT': 10,
|
||||||
'AUTH_LDAP_CACHE_TIMEOUT': 3600 * 24 * 30,
|
'AUTH_LDAP_CACHE_TIMEOUT': 0,
|
||||||
'AUTH_LDAP_SEARCH_PAGED_SIZE': 1000,
|
'AUTH_LDAP_SEARCH_PAGED_SIZE': 1000,
|
||||||
'AUTH_LDAP_SYNC_IS_PERIODIC': False,
|
'AUTH_LDAP_SYNC_IS_PERIODIC': False,
|
||||||
'AUTH_LDAP_SYNC_INTERVAL': None,
|
'AUTH_LDAP_SYNC_INTERVAL': None,
|
||||||
|
@ -310,7 +310,7 @@ class Config(dict):
|
||||||
'AUTH_LDAP_HA_START_TLS': False,
|
'AUTH_LDAP_HA_START_TLS': False,
|
||||||
'AUTH_LDAP_HA_USER_ATTR_MAP': {"username": "cn", "name": "sn", "email": "mail"},
|
'AUTH_LDAP_HA_USER_ATTR_MAP': {"username": "cn", "name": "sn", "email": "mail"},
|
||||||
'AUTH_LDAP_HA_CONNECT_TIMEOUT': 10,
|
'AUTH_LDAP_HA_CONNECT_TIMEOUT': 10,
|
||||||
'AUTH_LDAP_HA_CACHE_TIMEOUT': 3600 * 24 * 30,
|
'AUTH_LDAP_HA_CACHE_TIMEOUT': 0,
|
||||||
'AUTH_LDAP_HA_SEARCH_PAGED_SIZE': 1000,
|
'AUTH_LDAP_HA_SEARCH_PAGED_SIZE': 1000,
|
||||||
'AUTH_LDAP_HA_SYNC_IS_PERIODIC': False,
|
'AUTH_LDAP_HA_SYNC_IS_PERIODIC': False,
|
||||||
'AUTH_LDAP_HA_SYNC_INTERVAL': None,
|
'AUTH_LDAP_HA_SYNC_INTERVAL': None,
|
||||||
|
|
|
@ -19,6 +19,7 @@ XPACK_TEMPLATES_DIR = []
|
||||||
XPACK_CONTEXT_PROCESSOR = []
|
XPACK_CONTEXT_PROCESSOR = []
|
||||||
XPACK_LICENSE_IS_VALID = False
|
XPACK_LICENSE_IS_VALID = False
|
||||||
XPACK_LICENSE_EDITION = ""
|
XPACK_LICENSE_EDITION = ""
|
||||||
|
XPACK_LICENSE_EDITION_ULTIMATE = False
|
||||||
XPACK_LICENSE_INFO = {
|
XPACK_LICENSE_INFO = {
|
||||||
'corporation': corporation,
|
'corporation': corporation,
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ class ResourceDownload(TemplateView):
|
||||||
OPENSSH_VERSION=v9.4.0.0
|
OPENSSH_VERSION=v9.4.0.0
|
||||||
TINKER_VERSION=v0.1.6
|
TINKER_VERSION=v0.1.6
|
||||||
VIDEO_PLAYER_VERSION=0.2.0
|
VIDEO_PLAYER_VERSION=0.2.0
|
||||||
CLIENT_VERSION=v3.0.0
|
CLIENT_VERSION=v3.0.1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_meta_json(self):
|
def get_meta_json(self):
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
# Generated by Django 4.1.13 on 2024-10-30 09:38
|
# Generated by Django 4.1.13 on 2024-10-30 09:38
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -34,7 +35,7 @@ class Migration(migrations.Migration):
|
||||||
('comment', models.TextField(blank=True, default='', verbose_name='Comment')),
|
('comment', models.TextField(blank=True, default='', verbose_name='Comment')),
|
||||||
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
|
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
|
||||||
('name', models.CharField(max_length=1024, null=True, verbose_name='Name')),
|
('name', models.CharField(max_length=1024, null=True, verbose_name='Name')),
|
||||||
('var_name', models.CharField(help_text="The variable name used in the script has a fixed prefix 'jms_' followed by the input variable name. For example, if the variable name is 'name,' the final generated environment variable will be 'jms_name'.", max_length=1024, null=True, verbose_name='Variable name')),
|
('var_name', models.CharField(help_text="The variable name used in the script will have a fixed prefix jms_ added to the input variable name. For example, if the input variable name is name, the resulting environment variable will be jms_name, and it can be referenced in the script using {{ jms_name }}", max_length=1024, null=True, verbose_name='Variable name')),
|
||||||
('default_value', models.CharField(max_length=2048, null=True, verbose_name='Default Value')),
|
('default_value', models.CharField(max_length=2048, null=True, verbose_name='Default Value')),
|
||||||
('type', models.CharField(default='text', max_length=64, verbose_name='Variable type')),
|
('type', models.CharField(default='text', max_length=64, verbose_name='Variable type')),
|
||||||
('tips', models.CharField(blank=True, default='', max_length=1024, null=True, verbose_name='Tips')),
|
('tips', models.CharField(blank=True, default='', max_length=1024, null=True, verbose_name='Tips')),
|
||||||
|
|
|
@ -188,11 +188,7 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def average_time_cost(self):
|
def average_time_cost(self):
|
||||||
total_cost = 0
|
return self.last_execution.time_cost if self.last_execution else 0
|
||||||
finished_count = self.executions.filter(status__in=['success', 'failed']).count()
|
|
||||||
for execution in self.executions.filter(status__in=['success', 'failed']).all():
|
|
||||||
total_cost += execution.time_cost
|
|
||||||
return total_cost / finished_count if finished_count else 0
|
|
||||||
|
|
||||||
def get_register_task(self):
|
def get_register_task(self):
|
||||||
from ..tasks import run_ops_job
|
from ..tasks import run_ops_job
|
||||||
|
|
|
@ -9,9 +9,9 @@ class Variable(JMSBaseModel):
|
||||||
name = models.CharField(max_length=1024, verbose_name=_('Name'), null=True)
|
name = models.CharField(max_length=1024, verbose_name=_('Name'), null=True)
|
||||||
var_name = models.CharField(
|
var_name = models.CharField(
|
||||||
max_length=1024, null=True, verbose_name=_('Variable name'),
|
max_length=1024, null=True, verbose_name=_('Variable name'),
|
||||||
help_text=_("The variable name used in the script has a fixed prefix 'jms_' followed by the input variable "
|
help_text=_("The variable name used in the script will have a fixed prefix jms_ added to the input variable "
|
||||||
"name. For example, if the variable name is 'name,' the final generated environment variable will "
|
"name. For example, if the input variable name is name, the resulting environment variable will "
|
||||||
"be 'jms_name'.")
|
"be jms_name, and it can be referenced in the script using {{ jms_name }}")
|
||||||
)
|
)
|
||||||
default_value = models.CharField(max_length=2048, verbose_name=_('Default Value'), null=True)
|
default_value = models.CharField(max_length=2048, verbose_name=_('Default Value'), null=True)
|
||||||
creator = models.ForeignKey('users.User', verbose_name=_("Creator"), on_delete=models.SET_NULL, null=True)
|
creator = models.ForeignKey('users.User', verbose_name=_("Creator"), on_delete=models.SET_NULL, null=True)
|
||||||
|
|
|
@ -20,9 +20,9 @@ class VariableSerializer(CommonBulkModelSerializer):
|
||||||
name = serializers.CharField(max_length=1024, label=_('Name'), required=True)
|
name = serializers.CharField(max_length=1024, label=_('Name'), required=True)
|
||||||
var_name = serializers.CharField(
|
var_name = serializers.CharField(
|
||||||
max_length=1024, required=True, label=_('Variable name'),
|
max_length=1024, required=True, label=_('Variable name'),
|
||||||
help_text=_("The variable name used in the script has a fixed prefix 'jms_' followed by the input variable "
|
help_text=_("The variable name used in the script will have a fixed prefix jms_ added to the input variable "
|
||||||
"name. For example, if the variable name is 'name,' the final generated environment variable will "
|
"name. For example, if the input variable name is name, the resulting environment variable will "
|
||||||
"be 'jms_name'.")
|
"be jms_name, and it can be referenced in the script using {{ jms_name }}")
|
||||||
)
|
)
|
||||||
creator = ReadableHiddenField(default=serializers.CurrentUserDefault())
|
creator = ReadableHiddenField(default=serializers.CurrentUserDefault())
|
||||||
type = LabeledChoiceField(
|
type = LabeledChoiceField(
|
||||||
|
|
|
@ -11,6 +11,7 @@ from django.conf import settings
|
||||||
from common.const.crontab import CRONTAB_AT_AM_TWO
|
from common.const.crontab import CRONTAB_AT_AM_TWO
|
||||||
from common.utils import get_logger, get_object_or_none, get_log_keep_day
|
from common.utils import get_logger, get_object_or_none, get_log_keep_day
|
||||||
from ops.celery import app
|
from ops.celery import app
|
||||||
|
from ops.const import Types
|
||||||
from ops.serializers.job import JobExecutionSerializer
|
from ops.serializers.job import JobExecutionSerializer
|
||||||
from orgs.utils import tmp_to_org, tmp_to_root_org
|
from orgs.utils import tmp_to_org, tmp_to_root_org
|
||||||
from .celery.decorator import (
|
from .celery.decorator import (
|
||||||
|
@ -57,14 +58,13 @@ def _run_ops_job_execution(execution):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
def run_ops_job(job_id):
|
def run_ops_job(job_id):
|
||||||
if not settings.SECURITY_COMMAND_EXECUTION:
|
|
||||||
return
|
|
||||||
with tmp_to_root_org():
|
with tmp_to_root_org():
|
||||||
job = get_object_or_none(Job, id=job_id)
|
job = get_object_or_none(Job, id=job_id)
|
||||||
if not job:
|
if not job:
|
||||||
logger.error("Did not get the execution: {}".format(job_id))
|
logger.error("Did not get the execution: {}".format(job_id))
|
||||||
return
|
return
|
||||||
|
if not settings.SECURITY_COMMAND_EXECUTION and job.type != Types.upload_file:
|
||||||
|
return
|
||||||
with tmp_to_org(job.org):
|
with tmp_to_org(job.org):
|
||||||
execution = job.create_execution()
|
execution = job.create_execution()
|
||||||
execution.creator = job.creator
|
execution.creator = job.creator
|
||||||
|
@ -92,14 +92,13 @@ def job_execution_task_activity_callback(self, execution_id, *args, **kwargs):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
def run_ops_job_execution(execution_id, **kwargs):
|
def run_ops_job_execution(execution_id, **kwargs):
|
||||||
if not settings.SECURITY_COMMAND_EXECUTION:
|
|
||||||
return
|
|
||||||
with tmp_to_root_org():
|
with tmp_to_root_org():
|
||||||
execution = get_object_or_none(JobExecution, id=execution_id)
|
execution = get_object_or_none(JobExecution, id=execution_id)
|
||||||
|
|
||||||
if not execution:
|
if not execution:
|
||||||
logger.error("Did not get the execution: {}".format(execution_id))
|
logger.error("Did not get the execution: {}".format(execution_id))
|
||||||
return
|
return
|
||||||
|
if not settings.SECURITY_COMMAND_EXECUTION and execution.job.type != Types.upload_file:
|
||||||
|
return
|
||||||
_run_ops_job_execution(execution)
|
_run_ops_job_execution(execution)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,17 @@
|
||||||
#
|
#
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.core.cache import cache
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
|
|
||||||
|
from common.utils.http import is_true
|
||||||
|
from common.utils import lazyproperty, is_uuid
|
||||||
from common.exceptions import JMSObjectDoesNotExist
|
from common.exceptions import JMSObjectDoesNotExist
|
||||||
from common.utils import is_uuid
|
|
||||||
from rbac.permissions import RBACPermission
|
from rbac.permissions import RBACPermission
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
from perms.utils import UserPermTreeRefreshUtil
|
||||||
|
|
||||||
__all__ = ['SelfOrPKUserMixin']
|
__all__ = ['SelfOrPKUserMixin', 'RebuildTreeMixin']
|
||||||
|
|
||||||
|
|
||||||
class SelfOrPKUserMixin:
|
class SelfOrPKUserMixin:
|
||||||
|
@ -57,3 +60,33 @@ class SelfOrPKUserMixin:
|
||||||
|
|
||||||
def request_user_is_self(self):
|
def request_user_is_self(self):
|
||||||
return self.kwargs.get('user') in ['my', 'self']
|
return self.kwargs.get('user') in ['my', 'self']
|
||||||
|
|
||||||
|
|
||||||
|
class RebuildTreeMixin:
|
||||||
|
user: User
|
||||||
|
request: Request
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
UserPermTreeRefreshUtil(self.user).refresh_if_need(force=self.is_force_refresh_tree)
|
||||||
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def is_force_refresh_tree(self):
|
||||||
|
force = is_true(self.request.query_params.get('rebuild_tree'))
|
||||||
|
if not force:
|
||||||
|
force = self.compute_is_force_refresh()
|
||||||
|
return force
|
||||||
|
|
||||||
|
def compute_is_force_refresh(self):
|
||||||
|
""" 5s 内连续刷新三次转为强制刷新 """
|
||||||
|
force_timeout = 5
|
||||||
|
force_max_count = 3
|
||||||
|
force_cache_key = '{user_id}:{path}'.format(user_id=self.user.id, path=self.request.path)
|
||||||
|
count = cache.get(force_cache_key, 1)
|
||||||
|
if count >= force_max_count:
|
||||||
|
force = True
|
||||||
|
cache.delete(force_cache_key)
|
||||||
|
else:
|
||||||
|
force = False
|
||||||
|
cache.set(force_cache_key, count + 1, force_timeout)
|
||||||
|
return force
|
||||||
|
|
|
@ -8,7 +8,7 @@ from assets.models import Node
|
||||||
from common.utils import get_logger, lazyproperty
|
from common.utils import get_logger, lazyproperty
|
||||||
from perms import serializers
|
from perms import serializers
|
||||||
from perms.utils import UserPermNodeUtil
|
from perms.utils import UserPermNodeUtil
|
||||||
from .mixin import SelfOrPKUserMixin
|
from .mixin import SelfOrPKUserMixin, RebuildTreeMixin
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ __all__ = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class BaseUserPermedNodesApi(SelfOrPKUserMixin, ListAPIView):
|
class BaseUserPermedNodesApi(SelfOrPKUserMixin, RebuildTreeMixin, ListAPIView):
|
||||||
serializer_class = serializers.NodePermedSerializer
|
serializer_class = serializers.NodePermedSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
|
|
@ -4,7 +4,7 @@ from rest_framework.response import Response
|
||||||
from assets.api import SerializeToTreeNodeMixin
|
from assets.api import SerializeToTreeNodeMixin
|
||||||
from assets.models import Asset
|
from assets.models import Asset
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from .mixin import RebuildTreeMixin
|
from ..mixin import RebuildTreeMixin
|
||||||
from ..assets import UserAllPermedAssetsApi
|
from ..assets import UserAllPermedAssetsApi
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
from django.core.cache import cache
|
|
||||||
|
|
||||||
from rest_framework.request import Request
|
|
||||||
|
|
||||||
from common.utils.http import is_true
|
|
||||||
from common.utils import lazyproperty
|
|
||||||
from perms.utils import UserPermTreeRefreshUtil
|
|
||||||
from users.models import User
|
|
||||||
|
|
||||||
__all__ = ['RebuildTreeMixin']
|
|
||||||
|
|
||||||
|
|
||||||
class RebuildTreeMixin:
|
|
||||||
user: User
|
|
||||||
request: Request
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
UserPermTreeRefreshUtil(self.user).refresh_if_need(force=self.is_force_refresh_tree)
|
|
||||||
return super().get(request, *args, **kwargs)
|
|
||||||
|
|
||||||
@lazyproperty
|
|
||||||
def is_force_refresh_tree(self):
|
|
||||||
force = is_true(self.request.query_params.get('rebuild_tree'))
|
|
||||||
if not force:
|
|
||||||
force = self.compute_is_force_refresh()
|
|
||||||
return force
|
|
||||||
|
|
||||||
def compute_is_force_refresh(self):
|
|
||||||
""" 5s 内连续刷新三次转为强制刷新 """
|
|
||||||
force_timeout = 5
|
|
||||||
force_max_count = 3
|
|
||||||
force_cache_key = '{user_id}:{path}'.format(user_id=self.user.id, path=self.request.path)
|
|
||||||
count = cache.get(force_cache_key, 1)
|
|
||||||
if count >= force_max_count:
|
|
||||||
force = True
|
|
||||||
cache.delete(force_cache_key)
|
|
||||||
else:
|
|
||||||
force = False
|
|
||||||
cache.set(force_cache_key, count + 1, force_timeout)
|
|
||||||
return force
|
|
|
@ -3,7 +3,6 @@ from rest_framework.response import Response
|
||||||
from assets.api import SerializeToTreeNodeMixin
|
from assets.api import SerializeToTreeNodeMixin
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
|
|
||||||
from .mixin import RebuildTreeMixin
|
|
||||||
from ..nodes import (
|
from ..nodes import (
|
||||||
UserAllPermedNodesApi,
|
UserAllPermedNodesApi,
|
||||||
UserPermedNodeChildrenApi,
|
UserPermedNodeChildrenApi,
|
||||||
|
@ -17,7 +16,7 @@ __all__ = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class NodeTreeMixin(RebuildTreeMixin, SerializeToTreeNodeMixin):
|
class NodeTreeMixin(SerializeToTreeNodeMixin):
|
||||||
filter_queryset: callable
|
filter_queryset: callable
|
||||||
get_queryset: callable
|
get_queryset: callable
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,7 @@ from perms.hands import Node
|
||||||
from perms.models import PermNode
|
from perms.models import PermNode
|
||||||
from perms.utils import UserPermAssetUtil
|
from perms.utils import UserPermAssetUtil
|
||||||
from perms.utils import UserPermNodeUtil
|
from perms.utils import UserPermNodeUtil
|
||||||
from .mixin import RebuildTreeMixin
|
from ..mixin import SelfOrPKUserMixin, RebuildTreeMixin
|
||||||
from ..mixin import SelfOrPKUserMixin
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'UserPermedNodesWithAssetsAsTreeApi',
|
'UserPermedNodesWithAssetsAsTreeApi',
|
||||||
|
|
|
@ -23,14 +23,14 @@ class AssetPermissionUtil(object):
|
||||||
# group
|
# group
|
||||||
if with_group:
|
if with_group:
|
||||||
groups = user.groups.all()
|
groups = user.groups.all()
|
||||||
group_perm_ids = self.get_permissions_for_user_groups(groups, flat=True)
|
group_perm_ids = self.get_permissions_for_user_groups(groups, flat=True, with_expired=with_expired)
|
||||||
perm_ids.update(group_perm_ids)
|
perm_ids.update(group_perm_ids)
|
||||||
perms = self.get_permissions(ids=perm_ids, with_expired=with_expired)
|
perms = self.get_permissions(ids=perm_ids, with_expired=with_expired)
|
||||||
if flat:
|
if flat:
|
||||||
return perms.values_list('id', flat=True)
|
return perms.values_list('id', flat=True)
|
||||||
return perms
|
return perms
|
||||||
|
|
||||||
def get_permissions_for_user_groups(self, user_groups, flat=False):
|
def get_permissions_for_user_groups(self, user_groups, flat=False, with_expired=False):
|
||||||
""" 获取用户组的授权规则 """
|
""" 获取用户组的授权规则 """
|
||||||
if isinstance(user_groups, list):
|
if isinstance(user_groups, list):
|
||||||
group_ids = [g.id for g in user_groups]
|
group_ids = [g.id for g in user_groups]
|
||||||
|
@ -39,7 +39,7 @@ class AssetPermissionUtil(object):
|
||||||
perm_ids = AssetPermission.user_groups.through.objects \
|
perm_ids = AssetPermission.user_groups.through.objects \
|
||||||
.filter(usergroup_id__in=group_ids) \
|
.filter(usergroup_id__in=group_ids) \
|
||||||
.values_list('assetpermission_id', flat=True).distinct()
|
.values_list('assetpermission_id', flat=True).distinct()
|
||||||
perms = self.get_permissions(ids=perm_ids)
|
perms = self.get_permissions(ids=perm_ids, with_expired=with_expired)
|
||||||
if flat:
|
if flat:
|
||||||
return perms.values_list('id', flat=True)
|
return perms.values_list('id', flat=True)
|
||||||
return perms
|
return perms
|
||||||
|
|
|
@ -3,6 +3,7 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from common.serializers.fields import EncryptedField
|
from common.serializers.fields import EncryptedField
|
||||||
from .base import OrgListField
|
from .base import OrgListField
|
||||||
|
from .mixin import LDAPSerializerMixin
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'LDAPTestConfigSerializer', 'LDAPUserSerializer', 'LDAPTestLoginSerializer',
|
'LDAPTestConfigSerializer', 'LDAPUserSerializer', 'LDAPTestLoginSerializer',
|
||||||
|
@ -36,7 +37,7 @@ class LDAPUserSerializer(serializers.Serializer):
|
||||||
status = serializers.JSONField(read_only=True)
|
status = serializers.JSONField(read_only=True)
|
||||||
|
|
||||||
|
|
||||||
class LDAPSettingSerializer(serializers.Serializer):
|
class LDAPSettingSerializer(LDAPSerializerMixin, serializers.Serializer):
|
||||||
# encrypt_fields 现在使用 write_only 来判断了
|
# encrypt_fields 现在使用 write_only 来判断了
|
||||||
PREFIX_TITLE = _('LDAP')
|
PREFIX_TITLE = _('LDAP')
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ class LDAPSettingSerializer(serializers.Serializer):
|
||||||
)
|
)
|
||||||
AUTH_LDAP_CACHE_TIMEOUT = serializers.IntegerField(
|
AUTH_LDAP_CACHE_TIMEOUT = serializers.IntegerField(
|
||||||
min_value=0, max_value=3600 * 24 * 30 * 12,
|
min_value=0, max_value=3600 * 24 * 30 * 12,
|
||||||
default=3600 * 24 * 30,
|
default=0,
|
||||||
required=False, label=_('User DN cache timeout (s)'),
|
required=False, label=_('User DN cache timeout (s)'),
|
||||||
help_text=_(
|
help_text=_(
|
||||||
'Caching the User DN obtained during user login authentication can effectively '
|
'Caching the User DN obtained during user login authentication can effectively '
|
||||||
|
@ -103,10 +104,11 @@ class LDAPSettingSerializer(serializers.Serializer):
|
||||||
AUTH_LDAP = serializers.BooleanField(required=False, label=_('LDAP'))
|
AUTH_LDAP = serializers.BooleanField(required=False, label=_('LDAP'))
|
||||||
AUTH_LDAP_SYNC_ORG_IDS = OrgListField()
|
AUTH_LDAP_SYNC_ORG_IDS = OrgListField()
|
||||||
|
|
||||||
def post_save(self):
|
periodic_key = 'AUTH_LDAP_SYNC_IS_PERIODIC'
|
||||||
keys = ['AUTH_LDAP_SYNC_IS_PERIODIC', 'AUTH_LDAP_SYNC_INTERVAL', 'AUTH_LDAP_SYNC_CRONTAB']
|
interval_key = 'AUTH_LDAP_SYNC_INTERVAL'
|
||||||
kwargs = {k: self.validated_data[k] for k in keys if k in self.validated_data}
|
crontab_key = 'AUTH_LDAP_SYNC_CRONTAB'
|
||||||
if not kwargs:
|
|
||||||
return
|
@staticmethod
|
||||||
|
def import_task_function(**kwargs):
|
||||||
from settings.tasks import import_ldap_user_periodic
|
from settings.tasks import import_ldap_user_periodic
|
||||||
import_ldap_user_periodic(**kwargs)
|
import_ldap_user_periodic(**kwargs)
|
||||||
|
|
|
@ -3,6 +3,8 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from common.serializers.fields import EncryptedField
|
from common.serializers.fields import EncryptedField
|
||||||
from .base import OrgListField
|
from .base import OrgListField
|
||||||
|
from .mixin import LDAPSerializerMixin
|
||||||
|
from ops.mixin import PeriodTaskSerializerMixin
|
||||||
|
|
||||||
__all__ = ['LDAPHATestConfigSerializer', 'LDAPHASettingSerializer']
|
__all__ = ['LDAPHATestConfigSerializer', 'LDAPHASettingSerializer']
|
||||||
|
|
||||||
|
@ -18,7 +20,7 @@ class LDAPHATestConfigSerializer(serializers.Serializer):
|
||||||
AUTH_LDAP_HA = serializers.BooleanField(required=False)
|
AUTH_LDAP_HA = serializers.BooleanField(required=False)
|
||||||
|
|
||||||
|
|
||||||
class LDAPHASettingSerializer(serializers.Serializer):
|
class LDAPHASettingSerializer(LDAPSerializerMixin, serializers.Serializer):
|
||||||
# encrypt_fields 现在使用 write_only 来判断了
|
# encrypt_fields 现在使用 write_only 来判断了
|
||||||
PREFIX_TITLE = _('LDAP HA')
|
PREFIX_TITLE = _('LDAP HA')
|
||||||
|
|
||||||
|
@ -67,7 +69,7 @@ class LDAPHASettingSerializer(serializers.Serializer):
|
||||||
)
|
)
|
||||||
AUTH_LDAP_HA_CACHE_TIMEOUT = serializers.IntegerField(
|
AUTH_LDAP_HA_CACHE_TIMEOUT = serializers.IntegerField(
|
||||||
min_value=0, max_value=3600 * 24 * 30 * 12,
|
min_value=0, max_value=3600 * 24 * 30 * 12,
|
||||||
default=3600 * 24 * 30,
|
default=0,
|
||||||
required=False, label=_('User DN cache timeout (s)'),
|
required=False, label=_('User DN cache timeout (s)'),
|
||||||
help_text=_(
|
help_text=_(
|
||||||
'Caching the User DN obtained during user login authentication can effectively'
|
'Caching the User DN obtained during user login authentication can effectively'
|
||||||
|
@ -85,10 +87,11 @@ class LDAPHASettingSerializer(serializers.Serializer):
|
||||||
AUTH_LDAP_HA = serializers.BooleanField(required=False, label=_('LDAP HA'))
|
AUTH_LDAP_HA = serializers.BooleanField(required=False, label=_('LDAP HA'))
|
||||||
AUTH_LDAP_HA_SYNC_ORG_IDS = OrgListField()
|
AUTH_LDAP_HA_SYNC_ORG_IDS = OrgListField()
|
||||||
|
|
||||||
def post_save(self):
|
periodic_key = 'AUTH_LDAP_HA_SYNC_IS_PERIODIC'
|
||||||
keys = ['AUTH_LDAP_HA_SYNC_IS_PERIODIC', 'AUTH_LDAP_HA_SYNC_INTERVAL', 'AUTH_LDAP_HA_SYNC_CRONTAB']
|
interval_key = 'AUTH_LDAP_HA_SYNC_INTERVAL'
|
||||||
kwargs = {k: self.validated_data[k] for k in keys if k in self.validated_data}
|
crontab_key = 'AUTH_LDAP_HA_SYNC_CRONTAB'
|
||||||
if not kwargs:
|
|
||||||
return
|
@staticmethod
|
||||||
|
def import_task_function(**kwargs):
|
||||||
from settings.tasks import import_ldap_ha_user_periodic
|
from settings.tasks import import_ldap_ha_user_periodic
|
||||||
import_ldap_ha_user_periodic(**kwargs)
|
import_ldap_ha_user_periodic(**kwargs)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from rest_framework import serializers
|
||||||
|
from ops.mixin import PeriodTaskSerializerMixin
|
||||||
|
|
||||||
|
|
||||||
|
class LDAPSerializerMixin:
|
||||||
|
def validate(self, attrs):
|
||||||
|
is_periodic = attrs.get(self.periodic_key)
|
||||||
|
crontab = attrs.get(self.crontab_key)
|
||||||
|
interval = attrs.get(self.interval_key)
|
||||||
|
if is_periodic and not any([crontab, interval]):
|
||||||
|
msg = _("Require interval or crontab setting")
|
||||||
|
raise serializers.ValidationError(msg)
|
||||||
|
return super().validate(attrs)
|
||||||
|
|
||||||
|
def post_save(self):
|
||||||
|
keys = [self.periodic_key, self.interval_key, self.crontab_key]
|
||||||
|
kwargs = {k: self.validated_data[k] for k in keys if k in self.validated_data}
|
||||||
|
if not kwargs:
|
||||||
|
return
|
||||||
|
self.import_task_function(**kwargs)
|
|
@ -34,6 +34,8 @@ class PrivateSettingSerializer(PublicSettingSerializer):
|
||||||
PASSWORD_RULE = serializers.DictField()
|
PASSWORD_RULE = serializers.DictField()
|
||||||
SECURITY_SESSION_SHARE = serializers.BooleanField()
|
SECURITY_SESSION_SHARE = serializers.BooleanField()
|
||||||
XPACK_LICENSE_IS_VALID = serializers.BooleanField()
|
XPACK_LICENSE_IS_VALID = serializers.BooleanField()
|
||||||
|
XPACK_LICENSE_EDITION_ULTIMATE = serializers.BooleanField()
|
||||||
|
FACE_RECOGNITION_ENABLED = serializers.BooleanField()
|
||||||
XPACK_LICENSE_INFO = serializers.DictField()
|
XPACK_LICENSE_INFO = serializers.DictField()
|
||||||
HELP_DOCUMENT_URL = serializers.CharField()
|
HELP_DOCUMENT_URL = serializers.CharField()
|
||||||
HELP_SUPPORT_URL = serializers.CharField()
|
HELP_SUPPORT_URL = serializers.CharField()
|
||||||
|
|
|
@ -9,7 +9,7 @@ from common.utils import get_logger
|
||||||
from common.utils.timezone import local_now_display
|
from common.utils.timezone import local_now_display
|
||||||
from ops.celery.decorator import after_app_ready_start
|
from ops.celery.decorator import after_app_ready_start
|
||||||
from ops.celery.utils import (
|
from ops.celery.utils import (
|
||||||
create_or_update_celery_periodic_tasks
|
create_or_update_celery_periodic_tasks, disable_celery_periodic_task
|
||||||
)
|
)
|
||||||
from orgs.models import Organization
|
from orgs.models import Organization
|
||||||
from settings.notifications import LDAPImportMessage
|
from settings.notifications import LDAPImportMessage
|
||||||
|
@ -90,9 +90,12 @@ def import_ldap_ha_user():
|
||||||
|
|
||||||
|
|
||||||
def register_periodic_task(task_name, task_func, interval_key, enabled_key, crontab_key, **kwargs):
|
def register_periodic_task(task_name, task_func, interval_key, enabled_key, crontab_key, **kwargs):
|
||||||
interval = kwargs.get(interval_key, settings.AUTH_LDAP_SYNC_INTERVAL)
|
interval = kwargs.get(interval_key, getattr(settings, interval_key))
|
||||||
enabled = kwargs.get(enabled_key, settings.AUTH_LDAP_SYNC_IS_PERIODIC)
|
enabled = kwargs.get(enabled_key, getattr(settings, enabled_key))
|
||||||
crontab = kwargs.get(crontab_key, settings.AUTH_LDAP_SYNC_CRONTAB)
|
crontab = kwargs.get(crontab_key, getattr(settings, crontab_key))
|
||||||
|
|
||||||
|
if not enabled:
|
||||||
|
disable_celery_periodic_task(task_name)
|
||||||
|
|
||||||
if isinstance(interval, int):
|
if isinstance(interval, int):
|
||||||
interval = interval * 3600
|
interval = interval * 3600
|
||||||
|
|
|
@ -147,6 +147,9 @@ function activeNav(prefix) {
|
||||||
}
|
}
|
||||||
var path = document.location.pathname;
|
var path = document.location.pathname;
|
||||||
path = path.replace(prefix, '');
|
path = path.replace(prefix, '');
|
||||||
|
if (path === '/core/download/') {
|
||||||
|
return
|
||||||
|
}
|
||||||
var urlArray = path.split("/");
|
var urlArray = path.split("/");
|
||||||
var app = urlArray[1];
|
var app = urlArray[1];
|
||||||
var resource = urlArray[2];
|
var resource = urlArray[2];
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<!-- Custom and plugin javascript -->
|
<!-- Custom and plugin javascript -->
|
||||||
<script src="{% static "js/plugins/toastr/toastr.min.js" %}"></script>
|
<script src="{% static "js/plugins/toastr/toastr.min.js" %}"></script>
|
||||||
<script src="{% static "js/inspinia.js" %}"></script>
|
<script src="{% static "js/inspinia.js" %}"></script>
|
||||||
<script src="{% static "js/jumpserver.js" %}?v=9"></script>
|
<script src="{% static "js/jumpserver.js" %}?v=10"></script>
|
||||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||||
<script src="{% static 'js/plugins/select2/i18n/zh-CN.js' %}"></script>
|
<script src="{% static 'js/plugins/select2/i18n/zh-CN.js' %}"></script>
|
||||||
<script src="{% static 'js/plugins/markdown-it.min.js' %}"></script>
|
<script src="{% static 'js/plugins/markdown-it.min.js' %}"></script>
|
||||||
|
|
|
@ -97,10 +97,10 @@ class ComponentsPrometheusMetricsUtil(TypedComponentsStatusMetricsUtil):
|
||||||
def convert_status_metrics(metrics):
|
def convert_status_metrics(metrics):
|
||||||
return {
|
return {
|
||||||
'any': metrics['total'],
|
'any': metrics['total'],
|
||||||
'normal': metrics['normal'],
|
'normal': len(metrics['normal']),
|
||||||
'high': metrics['high'],
|
'high': len(metrics['high']),
|
||||||
'critical': metrics['critical'],
|
'critical': len(metrics['critical']),
|
||||||
'offline': metrics['offline']
|
'offline': len(metrics['offline'])
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_component_status_metrics(self):
|
def get_component_status_metrics(self):
|
||||||
|
@ -112,8 +112,8 @@ class ComponentsPrometheusMetricsUtil(TypedComponentsStatusMetricsUtil):
|
||||||
tp = metric['type']
|
tp = metric['type']
|
||||||
prometheus_metrics.append(f'## 组件: {tp}')
|
prometheus_metrics.append(f'## 组件: {tp}')
|
||||||
status_metrics = self.convert_status_metrics(metric)
|
status_metrics = self.convert_status_metrics(metric)
|
||||||
for status, value in status_metrics.items():
|
for status, count in status_metrics.items():
|
||||||
metric_text = status_metric_text % (tp, status, value)
|
metric_text = status_metric_text % (tp, status, count)
|
||||||
prometheus_metrics.append(metric_text)
|
prometheus_metrics.append(metric_text)
|
||||||
return prometheus_metrics
|
return prometheus_metrics
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue