mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-17 17:42:37 +00:00
Compare commits
109 Commits
pr@dev@ter
...
debug_mcp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
777b655e90 | ||
|
|
6e1736c1a7 | ||
|
|
fe31eb0a44 | ||
|
|
3e93034fbc | ||
|
|
f4b3a7d73a | ||
|
|
3781c40179 | ||
|
|
fab6219cea | ||
|
|
dd0cacb4bc | ||
|
|
b8639601a1 | ||
|
|
ab9882c9c1 | ||
|
|
77a7b74b15 | ||
|
|
4bc05865f1 | ||
|
|
bec9e4f3a7 | ||
|
|
359adf3dbb | ||
|
|
ac54bb672c | ||
|
|
9e3ba00bc4 | ||
|
|
2ec9a43317 | ||
|
|
06be56ef06 | ||
|
|
b2a618b206 | ||
|
|
1039c2e320 | ||
|
|
8d7267400d | ||
|
|
d67e473884 | ||
|
|
70068c9253 | ||
|
|
d68babb2e1 | ||
|
|
afb6f466d5 | ||
|
|
453ad331ee | ||
|
|
d309d11a8f | ||
|
|
4771693a56 | ||
|
|
cefc820ac1 | ||
|
|
d007afdb43 | ||
|
|
e8921a43be | ||
|
|
a9b44103d4 | ||
|
|
4abf2bded6 | ||
|
|
54693089a0 | ||
|
|
0b859dd502 | ||
|
|
3fb27f969a | ||
|
|
45627a1d92 | ||
|
|
245e2dab66 | ||
|
|
8f0a41b1a8 | ||
|
|
1a9e56c520 | ||
|
|
67c2f471b4 | ||
|
|
b04f96f5f2 | ||
|
|
30f03b7d89 | ||
|
|
28a97d0b5a | ||
|
|
3410686690 | ||
|
|
6860e2327f | ||
|
|
20253e760c | ||
|
|
a63cfde8d2 | ||
|
|
92e250e03b | ||
|
|
098f0950cb | ||
|
|
39b0830a6b | ||
|
|
2e847bc2bc | ||
|
|
f82f31876a | ||
|
|
cde182c015 | ||
|
|
b990cdf561 | ||
|
|
c9a062823d | ||
|
|
643ba4fc15 | ||
|
|
d16a55bbe2 | ||
|
|
ae31554729 | ||
|
|
53b47980a2 | ||
|
|
d31b5ee570 | ||
|
|
65aea1ea36 | ||
|
|
5abb5c5d5a | ||
|
|
93e41a5004 | ||
|
|
95f51bbe48 | ||
|
|
0184d292ec | ||
|
|
23a6d320c7 | ||
|
|
b16304c48a | ||
|
|
7cd1e4d3a0 | ||
|
|
64a9987c3f | ||
|
|
18bfe312fa | ||
|
|
c593f91d77 | ||
|
|
46da05652a | ||
|
|
9249aba1a9 | ||
|
|
eca637c120 | ||
|
|
ddacd5fce1 | ||
|
|
3ca5c04099 | ||
|
|
6603a073ec | ||
|
|
d745f7495a | ||
|
|
76f1667c89 | ||
|
|
1ab1954299 | ||
|
|
c8335999a4 | ||
|
|
5b4a67362d | ||
|
|
e025073da2 | ||
|
|
2155bc6862 | ||
|
|
953b515817 | ||
|
|
7f7a354b2d | ||
|
|
2b2f7ea3f0 | ||
|
|
529123e1b5 | ||
|
|
e156ab6ad8 | ||
|
|
3c1fd134ae | ||
|
|
b15f663c87 | ||
|
|
93906dff0a | ||
|
|
307befdacd | ||
|
|
dbfc4d3981 | ||
|
|
849edd33c1 | ||
|
|
37cceec8fe | ||
|
|
d2494c25cc | ||
|
|
023952582e | ||
|
|
863fe95100 | ||
|
|
4b0bdb18c9 | ||
|
|
10da053a95 | ||
|
|
c40bc46520 | ||
|
|
a732cc614e | ||
|
|
bb29d519c6 | ||
|
|
b56c3a76a7 | ||
|
|
ab908d24a7 | ||
|
|
79cabe1b3c | ||
|
|
231b7287c1 |
46
.github/workflows/build-python-image.yml
vendored
Normal file
46
.github/workflows/build-python-image.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: Build and Push Python Base Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: 'Tag to build'
|
||||||
|
required: true
|
||||||
|
default: '3.11-slim-bullseye-v1'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.ref }}
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
with:
|
||||||
|
image: tonistiigi/binfmt:qemu-v7.0.0-28
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract repository name
|
||||||
|
id: repo
|
||||||
|
run: echo "REPO=$(basename ${{ github.repository }})" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Build and push multi-arch image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
file: Dockerfile-python
|
||||||
|
tags: jumpserver/core-base:python-${{ inputs.tag }}
|
||||||
|
|
||||||
123
.github/workflows/cleanup-branches.yml
vendored
Normal file
123
.github/workflows/cleanup-branches.yml
vendored
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
name: Cleanup PR Branches
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# 每天凌晨2点运行
|
||||||
|
- cron: '0 2 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
# 允许手动触发
|
||||||
|
inputs:
|
||||||
|
dry_run:
|
||||||
|
description: 'Dry run mode (default: true)'
|
||||||
|
required: false
|
||||||
|
default: 'true'
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cleanup-branches:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # 获取所有分支和提交历史
|
||||||
|
|
||||||
|
- name: Setup Git
|
||||||
|
run: |
|
||||||
|
git config --global user.name "GitHub Actions"
|
||||||
|
git config --global user.email "actions@github.com"
|
||||||
|
|
||||||
|
- name: Get dry run setting
|
||||||
|
id: dry-run
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||||
|
echo "dry_run=${{ github.event.inputs.dry_run }}" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "dry_run=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Cleanup branches
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
DRY_RUN: ${{ steps.dry-run.outputs.dry_run }}
|
||||||
|
run: |
|
||||||
|
echo "Starting branch cleanup..."
|
||||||
|
echo "Dry run mode: $DRY_RUN"
|
||||||
|
|
||||||
|
# 获取所有本地分支
|
||||||
|
git fetch --all --prune
|
||||||
|
|
||||||
|
# 获取以 pr 或 repr 开头的分支
|
||||||
|
branches=$(git branch -r | grep -E 'origin/(pr|repr)' | sed 's/origin\///' | grep -v 'HEAD')
|
||||||
|
|
||||||
|
echo "Found branches matching pattern:"
|
||||||
|
echo "$branches"
|
||||||
|
|
||||||
|
deleted_count=0
|
||||||
|
skipped_count=0
|
||||||
|
|
||||||
|
for branch in $branches; do
|
||||||
|
echo ""
|
||||||
|
echo "Processing branch: $branch"
|
||||||
|
|
||||||
|
# 检查分支是否有未合并的PR
|
||||||
|
pr_info=$(gh pr list --head "$branch" --state open --json number,title,state 2>/dev/null)
|
||||||
|
|
||||||
|
if [ $? -eq 0 ] && [ "$pr_info" != "[]" ]; then
|
||||||
|
echo " ⚠️ Branch has open PR(s), skipping deletion"
|
||||||
|
echo " PR info: $pr_info"
|
||||||
|
skipped_count=$((skipped_count + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查分支是否有已合并的PR(可选:如果PR已合并也可以删除)
|
||||||
|
merged_pr_info=$(gh pr list --head "$branch" --state merged --json number,title,state 2>/dev/null)
|
||||||
|
|
||||||
|
if [ $? -eq 0 ] && [ "$merged_pr_info" != "[]" ]; then
|
||||||
|
echo " ✅ Branch has merged PR(s), safe to delete"
|
||||||
|
echo " Merged PR info: $merged_pr_info"
|
||||||
|
else
|
||||||
|
echo " ℹ️ No PRs found for this branch"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 执行删除操作
|
||||||
|
if [ "$DRY_RUN" = "true" ]; then
|
||||||
|
echo " 🔍 [DRY RUN] Would delete branch: $branch"
|
||||||
|
deleted_count=$((deleted_count + 1))
|
||||||
|
else
|
||||||
|
echo " 🗑️ Deleting branch: $branch"
|
||||||
|
|
||||||
|
# 删除远程分支
|
||||||
|
if git push origin --delete "$branch" 2>/dev/null; then
|
||||||
|
echo " ✅ Successfully deleted remote branch: $branch"
|
||||||
|
deleted_count=$((deleted_count + 1))
|
||||||
|
else
|
||||||
|
echo " ❌ Failed to delete remote branch: $branch"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Cleanup Summary ==="
|
||||||
|
echo "Branches processed: $(echo "$branches" | wc -l)"
|
||||||
|
echo "Branches deleted: $deleted_count"
|
||||||
|
echo "Branches skipped: $skipped_count"
|
||||||
|
|
||||||
|
if [ "$DRY_RUN" = "true" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "🔍 This was a DRY RUN - no branches were actually deleted"
|
||||||
|
echo "To perform actual deletion, run this workflow manually with dry_run=false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create summary
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
echo "## Branch Cleanup Summary" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Workflow:** ${{ github.workflow }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Run ID:** ${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Dry Run:** ${{ steps.dry-run.outputs.dry_run }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Triggered by:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "Check the logs above for detailed information about processed branches." >> $GITHUB_STEP_SUMMARY
|
||||||
9
.github/workflows/sync-gitee.yml
vendored
9
.github/workflows/sync-gitee.yml
vendored
@@ -1,11 +1,9 @@
|
|||||||
name: 🔀 Sync mirror to Gitee
|
name: 🔀 Sync mirror to Gitee
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
schedule:
|
||||||
branches:
|
# 每天凌晨3点运行
|
||||||
- master
|
- cron: '0 3 * * *'
|
||||||
- dev
|
|
||||||
create:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
mirror:
|
mirror:
|
||||||
@@ -14,7 +12,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: mirror
|
- name: mirror
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
if: github.event_name == 'push' || (github.event_name == 'create' && github.event.ref_type == 'tag')
|
|
||||||
uses: wearerequired/git-mirror-action@v1
|
uses: wearerequired/git-mirror-action@v1
|
||||||
env:
|
env:
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.GITEE_SSH_PRIVATE_KEY }}
|
SSH_PRIVATE_KEY: ${{ secrets.GITEE_SSH_PRIVATE_KEY }}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM jumpserver/core-base:20250827_025554 AS stage-build
|
FROM jumpserver/core-base:20251014_095903 AS stage-build
|
||||||
|
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ RUN set -ex \
|
|||||||
&& python manage.py compilemessages
|
&& python manage.py compilemessages
|
||||||
|
|
||||||
|
|
||||||
FROM python:3.11-slim-bullseye
|
FROM jumpserver/core-base:python-3.11-slim-bullseye-v1
|
||||||
ENV LANG=en_US.UTF-8 \
|
ENV LANG=en_US.UTF-8 \
|
||||||
PATH=/opt/py3/bin:$PATH
|
PATH=/opt/py3/bin:$PATH
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM python:3.11-slim-bullseye
|
FROM jumpserver/core-base:python-3.11-slim-bullseye-v1
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
COPY --from=ghcr.io/astral-sh/uv:0.6.14 /uv /uvx /usr/local/bin/
|
COPY --from=ghcr.io/astral-sh/uv:0.6.14 /uv /uvx /usr/local/bin/
|
||||||
# Install APT dependencies
|
# Install APT dependencies
|
||||||
@@ -28,7 +28,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \
|
|||||||
&& echo "no" | dpkg-reconfigure dash
|
&& echo "no" | dpkg-reconfigure dash
|
||||||
|
|
||||||
# Install bin tools
|
# Install bin tools
|
||||||
ARG CHECK_VERSION=v1.0.4
|
ARG CHECK_VERSION=v1.0.5
|
||||||
RUN set -ex \
|
RUN set -ex \
|
||||||
&& wget https://github.com/jumpserver-dev/healthcheck/releases/download/${CHECK_VERSION}/check-${CHECK_VERSION}-linux-${TARGETARCH}.tar.gz \
|
&& wget https://github.com/jumpserver-dev/healthcheck/releases/download/${CHECK_VERSION}/check-${CHECK_VERSION}-linux-${TARGETARCH}.tar.gz \
|
||||||
&& tar -xf check-${CHECK_VERSION}-linux-${TARGETARCH}.tar.gz \
|
&& tar -xf check-${CHECK_VERSION}-linux-${TARGETARCH}.tar.gz \
|
||||||
|
|||||||
11
Dockerfile-python
Normal file
11
Dockerfile-python
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
FROM python:3.11-slim-bullseye
|
||||||
|
ARG TARGETARCH
|
||||||
|
# Install APT dependencies
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
RUN set -eux; \
|
||||||
|
apt-get update; \
|
||||||
|
apt-get -y --no-install-recommends upgrade; \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# upgrade pip and setuptools
|
||||||
|
RUN pip install --no-cache-dir --upgrade pip setuptools wheel
|
||||||
@@ -11,6 +11,7 @@ from accounts.const import ChangeSecretRecordStatusChoice
|
|||||||
from accounts.filters import AccountFilterSet, NodeFilterBackend
|
from accounts.filters import AccountFilterSet, NodeFilterBackend
|
||||||
from accounts.mixins import AccountRecordViewLogMixin
|
from accounts.mixins import AccountRecordViewLogMixin
|
||||||
from accounts.models import Account, ChangeSecretRecord
|
from accounts.models import Account, ChangeSecretRecord
|
||||||
|
from assets.const.gpt import create_or_update_chatx_resources
|
||||||
from assets.models import Asset, Node
|
from assets.models import Asset, Node
|
||||||
from authentication.permissions import UserConfirmation, ConfirmType
|
from authentication.permissions import UserConfirmation, ConfirmType
|
||||||
from common.api.mixin import ExtraFilterFieldsMixin
|
from common.api.mixin import ExtraFilterFieldsMixin
|
||||||
@@ -18,6 +19,7 @@ from common.drf.filters import AttrRulesFilterBackend
|
|||||||
from common.permissions import IsValidUser
|
from common.permissions import IsValidUser
|
||||||
from common.utils import lazyproperty, get_logger
|
from common.utils import lazyproperty, get_logger
|
||||||
from orgs.mixins.api import OrgBulkModelViewSet
|
from orgs.mixins.api import OrgBulkModelViewSet
|
||||||
|
from orgs.utils import tmp_to_root_org
|
||||||
from rbac.permissions import RBACPermission
|
from rbac.permissions import RBACPermission
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
@@ -43,6 +45,7 @@ class AccountViewSet(OrgBulkModelViewSet):
|
|||||||
'clear_secret': 'accounts.change_account',
|
'clear_secret': 'accounts.change_account',
|
||||||
'move_to_assets': 'accounts.delete_account',
|
'move_to_assets': 'accounts.delete_account',
|
||||||
'copy_to_assets': 'accounts.add_account',
|
'copy_to_assets': 'accounts.add_account',
|
||||||
|
'chat': 'accounts.view_account',
|
||||||
}
|
}
|
||||||
export_as_zip = True
|
export_as_zip = True
|
||||||
|
|
||||||
@@ -152,6 +155,13 @@ class AccountViewSet(OrgBulkModelViewSet):
|
|||||||
def copy_to_assets(self, request, *args, **kwargs):
|
def copy_to_assets(self, request, *args, **kwargs):
|
||||||
return self._copy_or_move_to_assets(request, move=False)
|
return self._copy_or_move_to_assets(request, move=False)
|
||||||
|
|
||||||
|
@action(methods=['get'], detail=False, url_path='chat')
|
||||||
|
def chat(self, request, *args, **kwargs):
|
||||||
|
with tmp_to_root_org():
|
||||||
|
__, account = create_or_update_chatx_resources()
|
||||||
|
serializer = self.get_serializer(account)
|
||||||
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
class AccountSecretsViewSet(AccountRecordViewLogMixin, AccountViewSet):
|
class AccountSecretsViewSet(AccountRecordViewLogMixin, AccountViewSet):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ class IntegrationApplicationViewSet(OrgBulkModelViewSet):
|
|||||||
}
|
}
|
||||||
rbac_perms = {
|
rbac_perms = {
|
||||||
'get_once_secret': 'accounts.change_integrationapplication',
|
'get_once_secret': 'accounts.change_integrationapplication',
|
||||||
'get_account_secret': 'accounts.view_integrationapplication'
|
'get_account_secret': 'accounts.view_integrationapplication',
|
||||||
|
'get_sdks_info': 'accounts.view_integrationapplication'
|
||||||
}
|
}
|
||||||
|
|
||||||
def read_file(self, path):
|
def read_file(self, path):
|
||||||
@@ -36,7 +37,6 @@ class IntegrationApplicationViewSet(OrgBulkModelViewSet):
|
|||||||
|
|
||||||
@action(
|
@action(
|
||||||
['GET'], detail=False, url_path='sdks',
|
['GET'], detail=False, url_path='sdks',
|
||||||
permission_classes=[IsValidUser]
|
|
||||||
)
|
)
|
||||||
def get_sdks_info(self, request, *args, **kwargs):
|
def get_sdks_info(self, request, *args, **kwargs):
|
||||||
code_suffix_mapper = {
|
code_suffix_mapper = {
|
||||||
|
|||||||
@@ -235,8 +235,8 @@ class AccountBackupHandler:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
error = str(e)
|
error = str(e)
|
||||||
print(f'\033[31m>>> {error}\033[0m')
|
print(f'\033[31m>>> {error}\033[0m')
|
||||||
self.execution.status = Status.error
|
self.manager.status = Status.error
|
||||||
self.execution.summary['error'] = error
|
self.manager.summary['error'] = error
|
||||||
|
|
||||||
def backup_by_obj_storage(self):
|
def backup_by_obj_storage(self):
|
||||||
object_id = self.execution.snapshot.get('id')
|
object_id = self.execution.snapshot.get('id')
|
||||||
|
|||||||
@@ -118,12 +118,10 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
|
|||||||
if self.secret_type == SecretType.SSH_KEY:
|
if self.secret_type == SecretType.SSH_KEY:
|
||||||
host['error'] = _("Windows does not support SSH key authentication")
|
host['error'] = _("Windows does not support SSH key authentication")
|
||||||
return host
|
return host
|
||||||
|
new_secret = self.get_secret(account)
|
||||||
if self.secret_strategy == SecretStrategy.custom:
|
if '>' in new_secret or '^' in new_secret:
|
||||||
new_secret = self.execution.snapshot['secret']
|
host['error'] = _("Windows password cannot contain special characters like > ^")
|
||||||
if '>' in new_secret or '^' in new_secret:
|
return host
|
||||||
host['error'] = _("Windows password cannot contain special characters like > ^")
|
|
||||||
return host
|
|
||||||
|
|
||||||
host['ssh_params'] = {}
|
host['ssh_params'] = {}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
|
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
|
||||||
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
|
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
|
||||||
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
|
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
|
||||||
|
group: "{{ params.group if params.group | length > 0 else omit }}"
|
||||||
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
|
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
|
||||||
append: "{{ true if params.groups | length > 0 else false }}"
|
append: "{{ true if params.groups | length > 0 else false }}"
|
||||||
expires: -1
|
expires: -1
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ params:
|
|||||||
default: ''
|
default: ''
|
||||||
help_text: "{{ 'Params home help text' | trans }}"
|
help_text: "{{ 'Params home help text' | trans }}"
|
||||||
|
|
||||||
|
- name: group
|
||||||
|
type: str
|
||||||
|
label: "{{ 'Params group label' | trans }}"
|
||||||
|
default: ''
|
||||||
|
help_text: "{{ 'Params group help text' | trans }}"
|
||||||
|
|
||||||
- name: groups
|
- name: groups
|
||||||
type: str
|
type: str
|
||||||
label: "{{ 'Params groups label' | trans }}"
|
label: "{{ 'Params groups label' | trans }}"
|
||||||
@@ -61,6 +67,11 @@ i18n:
|
|||||||
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
|
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
|
||||||
en: 'Default home directory /home/{account username}'
|
en: 'Default home directory /home/{account username}'
|
||||||
|
|
||||||
|
Params group help text:
|
||||||
|
zh: '请输入用户组(名字或数字),只能输入一个(需填写已存在的用户组)'
|
||||||
|
ja: 'ユーザー グループ (名前または番号) を入力してください。入力できるのは 1 つだけです (既存のユーザー グループを入力する必要があります)'
|
||||||
|
en: 'Please enter a user group (name or number), only one can be entered (must fill in an existing user group)'
|
||||||
|
|
||||||
Params groups help text:
|
Params groups help text:
|
||||||
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
|
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
|
||||||
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
|
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
|
||||||
@@ -86,6 +97,11 @@ i18n:
|
|||||||
ja: 'グループ'
|
ja: 'グループ'
|
||||||
en: 'Groups'
|
en: 'Groups'
|
||||||
|
|
||||||
|
Params group label:
|
||||||
|
zh: '主组'
|
||||||
|
ja: '主组'
|
||||||
|
en: 'Main group'
|
||||||
|
|
||||||
Params uid label:
|
Params uid label:
|
||||||
zh: '用户ID'
|
zh: '用户ID'
|
||||||
ja: 'ユーザーID'
|
ja: 'ユーザーID'
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
|
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
|
||||||
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
|
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
|
||||||
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
|
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
|
||||||
|
group: "{{ params.group if params.group | length > 0 else omit }}"
|
||||||
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
|
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
|
||||||
append: "{{ true if params.groups | length > 0 else false }}"
|
append: "{{ true if params.groups | length > 0 else false }}"
|
||||||
expires: -1
|
expires: -1
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ params:
|
|||||||
default: ''
|
default: ''
|
||||||
help_text: "{{ 'Params home help text' | trans }}"
|
help_text: "{{ 'Params home help text' | trans }}"
|
||||||
|
|
||||||
|
- name: group
|
||||||
|
type: str
|
||||||
|
label: "{{ 'Params group label' | trans }}"
|
||||||
|
default: ''
|
||||||
|
help_text: "{{ 'Params group help text' | trans }}"
|
||||||
|
|
||||||
- name: groups
|
- name: groups
|
||||||
type: str
|
type: str
|
||||||
label: "{{ 'Params groups label' | trans }}"
|
label: "{{ 'Params groups label' | trans }}"
|
||||||
@@ -63,6 +69,11 @@ i18n:
|
|||||||
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
|
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
|
||||||
en: 'Default home directory /home/{account username}'
|
en: 'Default home directory /home/{account username}'
|
||||||
|
|
||||||
|
Params group help text:
|
||||||
|
zh: '请输入用户组(名字或数字),只能输入一个(需填写已存在的用户组)'
|
||||||
|
ja: 'ユーザー グループ (名前または番号) を入力してください。入力できるのは 1 つだけです (既存のユーザー グループを入力する必要があります)'
|
||||||
|
en: 'Please enter a user group (name or number), only one can be entered (must fill in an existing user group)'
|
||||||
|
|
||||||
Params groups help text:
|
Params groups help text:
|
||||||
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
|
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
|
||||||
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
|
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
|
||||||
@@ -88,6 +99,11 @@ i18n:
|
|||||||
ja: 'グループ'
|
ja: 'グループ'
|
||||||
en: 'Groups'
|
en: 'Groups'
|
||||||
|
|
||||||
|
Params group label:
|
||||||
|
zh: '主组'
|
||||||
|
ja: '主组'
|
||||||
|
en: 'Main group'
|
||||||
|
|
||||||
Params uid label:
|
Params uid label:
|
||||||
zh: '用户ID'
|
zh: '用户ID'
|
||||||
ja: 'ユーザーID'
|
ja: 'ユーザーID'
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
|
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
|
||||||
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
|
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
|
||||||
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
|
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
|
||||||
|
group: "{{ params.group if params.group | length > 0 else omit }}"
|
||||||
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
|
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
|
||||||
append: "{{ true if params.groups | length > 0 else false }}"
|
append: "{{ true if params.groups | length > 0 else false }}"
|
||||||
expires: -1
|
expires: -1
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ params:
|
|||||||
default: ''
|
default: ''
|
||||||
help_text: "{{ 'Params home help text' | trans }}"
|
help_text: "{{ 'Params home help text' | trans }}"
|
||||||
|
|
||||||
|
- name: group
|
||||||
|
type: str
|
||||||
|
label: "{{ 'Params group label' | trans }}"
|
||||||
|
default: ''
|
||||||
|
help_text: "{{ 'Params group help text' | trans }}"
|
||||||
|
|
||||||
- name: groups
|
- name: groups
|
||||||
type: str
|
type: str
|
||||||
label: "{{ 'Params groups label' | trans }}"
|
label: "{{ 'Params groups label' | trans }}"
|
||||||
@@ -61,6 +67,11 @@ i18n:
|
|||||||
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
|
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
|
||||||
en: 'Default home directory /home/{account username}'
|
en: 'Default home directory /home/{account username}'
|
||||||
|
|
||||||
|
Params group help text:
|
||||||
|
zh: '请输入用户组(名字或数字),只能输入一个(需填写已存在的用户组)'
|
||||||
|
ja: 'ユーザー グループ (名前または番号) を入力してください。入力できるのは 1 つだけです (既存のユーザー グループを入力する必要があります)'
|
||||||
|
en: 'Please enter a user group (name or number), only one can be entered (must fill in an existing user group)'
|
||||||
|
|
||||||
Params groups help text:
|
Params groups help text:
|
||||||
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
|
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
|
||||||
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
|
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
|
||||||
@@ -86,6 +97,11 @@ i18n:
|
|||||||
ja: 'グループ'
|
ja: 'グループ'
|
||||||
en: 'Groups'
|
en: 'Groups'
|
||||||
|
|
||||||
|
Params group label:
|
||||||
|
zh: '主组'
|
||||||
|
ja: '主组'
|
||||||
|
en: 'Main group'
|
||||||
|
|
||||||
Params uid label:
|
Params uid label:
|
||||||
zh: '用户ID'
|
zh: '用户ID'
|
||||||
ja: 'ユーザーID'
|
ja: 'ユーザーID'
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
|
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
|
||||||
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
|
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
|
||||||
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
|
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
|
||||||
|
group: "{{ params.group if params.group | length > 0 else omit }}"
|
||||||
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
|
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
|
||||||
append: "{{ true if params.groups | length > 0 else false }}"
|
append: "{{ true if params.groups | length > 0 else false }}"
|
||||||
expires: -1
|
expires: -1
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ params:
|
|||||||
default: ''
|
default: ''
|
||||||
help_text: "{{ 'Params home help text' | trans }}"
|
help_text: "{{ 'Params home help text' | trans }}"
|
||||||
|
|
||||||
|
- name: group
|
||||||
|
type: str
|
||||||
|
label: "{{ 'Params group label' | trans }}"
|
||||||
|
default: ''
|
||||||
|
help_text: "{{ 'Params group help text' | trans }}"
|
||||||
|
|
||||||
- name: groups
|
- name: groups
|
||||||
type: str
|
type: str
|
||||||
label: "{{ 'Params groups label' | trans }}"
|
label: "{{ 'Params groups label' | trans }}"
|
||||||
@@ -63,6 +69,11 @@ i18n:
|
|||||||
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
|
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
|
||||||
en: 'Default home directory /home/{account username}'
|
en: 'Default home directory /home/{account username}'
|
||||||
|
|
||||||
|
Params group help text:
|
||||||
|
zh: '请输入用户组(名字或数字),只能输入一个(需填写已存在的用户组)'
|
||||||
|
ja: 'ユーザー グループ (名前または番号) を入力してください。入力できるのは 1 つだけです (既存のユーザー グループを入力する必要があります)'
|
||||||
|
en: 'Please enter a user group (name or number), only one can be entered (must fill in an existing user group)'
|
||||||
|
|
||||||
Params groups help text:
|
Params groups help text:
|
||||||
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
|
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
|
||||||
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
|
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
|
||||||
@@ -84,9 +95,14 @@ i18n:
|
|||||||
en: 'Home'
|
en: 'Home'
|
||||||
|
|
||||||
Params groups label:
|
Params groups label:
|
||||||
zh: '用户组'
|
zh: '附加组'
|
||||||
ja: 'グループ'
|
ja: '追加グループ'
|
||||||
en: 'Groups'
|
en: 'Additional Group'
|
||||||
|
|
||||||
|
Params group label:
|
||||||
|
zh: '主组'
|
||||||
|
ja: '主组'
|
||||||
|
en: 'Main group'
|
||||||
|
|
||||||
Params uid label:
|
Params uid label:
|
||||||
zh: '用户ID'
|
zh: '用户ID'
|
||||||
|
|||||||
@@ -309,10 +309,10 @@ class AssetAccountBulkSerializer(
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Account
|
model = Account
|
||||||
fields = [
|
fields = [
|
||||||
'name', 'username', 'secret', 'secret_type', 'passphrase',
|
'name', 'username', 'secret', 'secret_type', 'secret_reset',
|
||||||
'privileged', 'is_active', 'comment', 'template',
|
'passphrase', 'privileged', 'is_active', 'comment', 'template',
|
||||||
'on_invalid', 'push_now', 'params', 'assets',
|
'on_invalid', 'push_now', 'params', 'assets', 'su_from_username',
|
||||||
'su_from_username', 'source', 'source_id',
|
'source', 'source_id',
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'name': {'required': False},
|
'name': {'required': False},
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ from .connect_method import *
|
|||||||
from .login_acl import *
|
from .login_acl import *
|
||||||
from .login_asset_acl import *
|
from .login_asset_acl import *
|
||||||
from .login_asset_check import *
|
from .login_asset_check import *
|
||||||
|
from .data_masking import *
|
||||||
20
apps/acls/api/data_masking.py
Normal file
20
apps/acls/api/data_masking.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from orgs.mixins.api import OrgBulkModelViewSet
|
||||||
|
|
||||||
|
from .common import ACLUserFilterMixin
|
||||||
|
from ..models import DataMaskingRule
|
||||||
|
from .. import serializers
|
||||||
|
|
||||||
|
__all__ = ['DataMaskingRuleViewSet']
|
||||||
|
|
||||||
|
|
||||||
|
class DataMaskingRuleFilter(ACLUserFilterMixin):
|
||||||
|
class Meta:
|
||||||
|
model = DataMaskingRule
|
||||||
|
fields = ('name',)
|
||||||
|
|
||||||
|
|
||||||
|
class DataMaskingRuleViewSet(OrgBulkModelViewSet):
|
||||||
|
model = DataMaskingRule
|
||||||
|
filterset_class = DataMaskingRuleFilter
|
||||||
|
search_fields = ('name',)
|
||||||
|
serializer_class = serializers.DataMaskingRuleSerializer
|
||||||
@@ -8,7 +8,7 @@ __all__ = ['LoginAssetACLViewSet']
|
|||||||
class LoginAssetACLFilter(ACLUserAssetFilterMixin):
|
class LoginAssetACLFilter(ACLUserAssetFilterMixin):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.LoginAssetACL
|
model = models.LoginAssetACL
|
||||||
fields = ['name', ]
|
fields = ['name', 'action']
|
||||||
|
|
||||||
|
|
||||||
class LoginAssetACLViewSet(OrgBulkModelViewSet):
|
class LoginAssetACLViewSet(OrgBulkModelViewSet):
|
||||||
|
|||||||
45
apps/acls/migrations/0003_datamaskingrule.py
Normal file
45
apps/acls/migrations/0003_datamaskingrule.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Generated by Django 4.1.13 on 2025-10-07 16:16
|
||||||
|
|
||||||
|
import common.db.fields
|
||||||
|
from django.conf import settings
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('acls', '0002_auto_20210926_1047'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='DataMaskingRule',
|
||||||
|
fields=[
|
||||||
|
('created_by', models.CharField(blank=True, max_length=128, null=True, verbose_name='Created by')),
|
||||||
|
('updated_by', models.CharField(blank=True, max_length=128, null=True, verbose_name='Updated by')),
|
||||||
|
('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')),
|
||||||
|
('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
|
||||||
|
('comment', models.TextField(blank=True, default='', verbose_name='Comment')),
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
|
||||||
|
('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
|
||||||
|
('priority', models.IntegerField(default=50, help_text='1-100, the lower the value will be match first', validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)], verbose_name='Priority')),
|
||||||
|
('action', models.CharField(default='reject', max_length=64, verbose_name='Action')),
|
||||||
|
('is_active', models.BooleanField(default=True, verbose_name='Active')),
|
||||||
|
('users', common.db.fields.JSONManyToManyField(default=dict, to='users.User', verbose_name='Users')),
|
||||||
|
('assets', common.db.fields.JSONManyToManyField(default=dict, to='assets.Asset', verbose_name='Assets')),
|
||||||
|
('accounts', models.JSONField(default=list, verbose_name='Accounts')),
|
||||||
|
('name', models.CharField(max_length=128, verbose_name='Name')),
|
||||||
|
('fields_pattern', models.CharField(default='password', max_length=128, verbose_name='Fields pattern')),
|
||||||
|
('masking_method', models.CharField(choices=[('fixed_char', 'Fixed Character Replacement'), ('hide_middle', 'Hide Middle Characters'), ('keep_prefix', 'Keep Prefix Only'), ('keep_suffix', 'Keep Suffix Only')], default='fixed_char', max_length=32, verbose_name='Masking Method')),
|
||||||
|
('mask_pattern', models.CharField(blank=True, default='######', max_length=128, null=True, verbose_name='Mask Pattern')),
|
||||||
|
('reviewers', models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL, verbose_name='Reviewers')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Data Masking Rule',
|
||||||
|
'unique_together': {('org_id', 'name')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -2,3 +2,4 @@ from .command_acl import *
|
|||||||
from .connect_method import *
|
from .connect_method import *
|
||||||
from .login_acl import *
|
from .login_acl import *
|
||||||
from .login_asset_acl import *
|
from .login_asset_acl import *
|
||||||
|
from .data_masking import *
|
||||||
42
apps/acls/models/data_masking.py
Normal file
42
apps/acls/models/data_masking.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from acls.models import UserAssetAccountBaseACL
|
||||||
|
from common.utils import get_logger
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
__all__ = ['MaskingMethod', 'DataMaskingRule']
|
||||||
|
|
||||||
|
|
||||||
|
class MaskingMethod(models.TextChoices):
|
||||||
|
fixed_char = "fixed_char", _("Fixed Character Replacement") # 固定字符替换
|
||||||
|
hide_middle = "hide_middle", _("Hide Middle Characters") # 隐藏中间几位
|
||||||
|
keep_prefix = "keep_prefix", _("Keep Prefix Only") # 只保留前缀
|
||||||
|
keep_suffix = "keep_suffix", _("Keep Suffix Only") # 只保留后缀
|
||||||
|
|
||||||
|
|
||||||
|
class DataMaskingRule(UserAssetAccountBaseACL):
|
||||||
|
name = models.CharField(max_length=128, verbose_name=_("Name"))
|
||||||
|
fields_pattern = models.CharField(max_length=128, default='password', verbose_name=_("Fields pattern"))
|
||||||
|
|
||||||
|
masking_method = models.CharField(
|
||||||
|
max_length=32,
|
||||||
|
choices=MaskingMethod.choices,
|
||||||
|
default=MaskingMethod.fixed_char,
|
||||||
|
verbose_name=_("Masking Method"),
|
||||||
|
)
|
||||||
|
mask_pattern = models.CharField(
|
||||||
|
max_length=128,
|
||||||
|
verbose_name=_("Mask Pattern"),
|
||||||
|
default="######",
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = [('org_id', 'name')]
|
||||||
|
verbose_name = _("Data Masking Rule")
|
||||||
@@ -1,30 +1,52 @@
|
|||||||
from django.template.loader import render_to_string
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from accounts.models import Account
|
from accounts.models import Account
|
||||||
|
from acls.models import LoginACL, LoginAssetACL
|
||||||
from assets.models import Asset
|
from assets.models import Asset
|
||||||
from audits.models import UserLoginLog
|
from audits.models import UserLoginLog
|
||||||
|
from common.views.template import custom_render_to_string
|
||||||
from notifications.notifications import UserMessage
|
from notifications.notifications import UserMessage
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
|
||||||
|
|
||||||
class UserLoginReminderMsg(UserMessage):
|
class UserLoginReminderMsg(UserMessage):
|
||||||
subject = _('User login reminder')
|
subject = _('User login reminder')
|
||||||
|
template_name = 'acls/user_login_reminder.html'
|
||||||
|
contexts = [
|
||||||
|
{"name": "city", "label": _('Login city'), "default": "Shanghai"},
|
||||||
|
{"name": "username", "label": _('User'), "default": "john"},
|
||||||
|
{"name": "ip", "label": "IP", "default": "192.168.1.1"},
|
||||||
|
{"name": "recipient_name", "label": _("Recipient name"), "default": "John"},
|
||||||
|
{"name": "recipient_username", "label": _("Recipient username"), "default": "john"},
|
||||||
|
{"name": "user_agent", "label": _('User agent'), "default": "Mozilla/5.0"},
|
||||||
|
{"name": "acl_name", "label": _('ACL name'), "default": "login acl"},
|
||||||
|
{"name": "login_from", "label": _('Login from'), "default": "web"},
|
||||||
|
{"name": "time", "label": _('Login time'), "default": "2025-01-01 12:00:00"},
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self, user, user_log: UserLoginLog):
|
def __init__(self, user, user_log: UserLoginLog, acl: LoginACL):
|
||||||
self.user_log = user_log
|
self.user_log = user_log
|
||||||
|
self.acl_name = str(acl)
|
||||||
|
self.login_from = user_log.get_type_display()
|
||||||
|
now = timezone.localtime(user_log.datetime)
|
||||||
|
self.time = now.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
super().__init__(user)
|
super().__init__(user)
|
||||||
|
|
||||||
def get_html_msg(self) -> dict:
|
def get_html_msg(self) -> dict:
|
||||||
user_log = self.user_log
|
user_log = self.user_log
|
||||||
context = {
|
context = {
|
||||||
'ip': user_log.ip,
|
'ip': user_log.ip,
|
||||||
|
'time': self.time,
|
||||||
'city': user_log.city,
|
'city': user_log.city,
|
||||||
|
'acl_name': self.acl_name,
|
||||||
|
'login_from': self.login_from,
|
||||||
'username': user_log.username,
|
'username': user_log.username,
|
||||||
'recipient': self.user,
|
'recipient_name': self.user.name,
|
||||||
|
'recipient_username': self.user.username,
|
||||||
'user_agent': user_log.user_agent,
|
'user_agent': user_log.user_agent,
|
||||||
}
|
}
|
||||||
message = render_to_string('acls/user_login_reminder.html', context)
|
message = custom_render_to_string(self.template_name, context)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'subject': str(self.subject),
|
'subject': str(self.subject),
|
||||||
@@ -40,24 +62,55 @@ class UserLoginReminderMsg(UserMessage):
|
|||||||
|
|
||||||
class AssetLoginReminderMsg(UserMessage):
|
class AssetLoginReminderMsg(UserMessage):
|
||||||
subject = _('User login alert for asset')
|
subject = _('User login alert for asset')
|
||||||
|
template_name = 'acls/asset_login_reminder.html'
|
||||||
|
contexts = [
|
||||||
|
{"name": "city", "label": _('Login city'), "default": "Shanghai"},
|
||||||
|
{"name": "username", "label": _('User'), "default": "john"},
|
||||||
|
{"name": "name", "label": _('Name'), "default": "John"},
|
||||||
|
{"name": "asset", "label": _('Asset'), "default": "dev server"},
|
||||||
|
{"name": "recipient_name", "label": _('Recipient name'), "default": "John"},
|
||||||
|
{"name": "recipient_username", "label": _('Recipient username'), "default": "john"},
|
||||||
|
{"name": "account", "label": _('Account Input username'), "default": "root"},
|
||||||
|
{"name": "account_name", "label": _('Account name'), "default": "root"},
|
||||||
|
{"name": "acl_name", "label": _('ACL name'), "default": "login acl"},
|
||||||
|
{"name": "ip", "label": "IP", "default": "192.168.1.1"},
|
||||||
|
{"name": "login_from", "label": _('Login from'), "default": "web"},
|
||||||
|
{"name": "time", "label": _('Login time'), "default": "2025-01-01 12:00:00"}
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self, user, asset: Asset, login_user: User, account: Account, input_username):
|
def __init__(
|
||||||
|
self, user, asset: Asset, login_user: User,
|
||||||
|
account: Account, acl: LoginAssetACL,
|
||||||
|
ip, input_username, login_from
|
||||||
|
):
|
||||||
|
self.ip = ip
|
||||||
self.asset = asset
|
self.asset = asset
|
||||||
self.login_user = login_user
|
self.login_user = login_user
|
||||||
self.account = account
|
self.account = account
|
||||||
|
self.acl_name = str(acl)
|
||||||
|
self.login_from = login_from
|
||||||
|
self.login_user = login_user
|
||||||
self.input_username = input_username
|
self.input_username = input_username
|
||||||
|
|
||||||
|
now = timezone.localtime(timezone.now())
|
||||||
|
self.time = now.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
super().__init__(user)
|
super().__init__(user)
|
||||||
|
|
||||||
def get_html_msg(self) -> dict:
|
def get_html_msg(self) -> dict:
|
||||||
context = {
|
context = {
|
||||||
'recipient': self.user,
|
'ip': self.ip,
|
||||||
|
'time': self.time,
|
||||||
|
'login_from': self.login_from,
|
||||||
|
'recipient_name': self.user.name,
|
||||||
|
'recipient_username': self.user.username,
|
||||||
'username': self.login_user.username,
|
'username': self.login_user.username,
|
||||||
'name': self.login_user.name,
|
'name': self.login_user.name,
|
||||||
'asset': str(self.asset),
|
'asset': str(self.asset),
|
||||||
'account': self.input_username,
|
'account': self.input_username,
|
||||||
'account_name': self.account.name,
|
'account_name': self.account.name,
|
||||||
|
'acl_name': self.acl_name,
|
||||||
}
|
}
|
||||||
message = render_to_string('acls/asset_login_reminder.html', context)
|
message = custom_render_to_string(self.template_name, context)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'subject': str(self.subject),
|
'subject': str(self.subject),
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ from .connect_method import *
|
|||||||
from .login_acl import *
|
from .login_acl import *
|
||||||
from .login_asset_acl import *
|
from .login_asset_acl import *
|
||||||
from .login_asset_check import *
|
from .login_asset_check import *
|
||||||
|
from .data_masking import *
|
||||||
@@ -90,7 +90,7 @@ class BaseACLSerializer(ActionAclSerializer, serializers.Serializer):
|
|||||||
fields_small = fields_mini + [
|
fields_small = fields_mini + [
|
||||||
"is_active", "priority", "action",
|
"is_active", "priority", "action",
|
||||||
"date_created", "date_updated",
|
"date_created", "date_updated",
|
||||||
"comment", "created_by", "org_id",
|
"comment", "created_by"
|
||||||
]
|
]
|
||||||
fields_m2m = ["reviewers", ]
|
fields_m2m = ["reviewers", ]
|
||||||
fields = fields_small + fields_m2m
|
fields = fields_small + fields_m2m
|
||||||
@@ -100,6 +100,20 @@ class BaseACLSerializer(ActionAclSerializer, serializers.Serializer):
|
|||||||
'reviewers': {'label': _('Recipients')},
|
'reviewers': {'label': _('Recipients')},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BaseUserACLSerializer(BaseACLSerializer):
|
||||||
|
users = JSONManyToManyField(label=_('User'))
|
||||||
|
|
||||||
|
class Meta(BaseACLSerializer.Meta):
|
||||||
|
fields = BaseACLSerializer.Meta.fields + ['users']
|
||||||
|
|
||||||
|
|
||||||
|
class BaseUserAssetAccountACLSerializer(BaseUserACLSerializer):
|
||||||
|
assets = JSONManyToManyField(label=_('Asset'))
|
||||||
|
accounts = serializers.ListField(label=_('Account'))
|
||||||
|
|
||||||
|
class Meta(BaseUserACLSerializer.Meta):
|
||||||
|
fields = BaseUserACLSerializer.Meta.fields + ['assets', 'accounts', 'org_id']
|
||||||
|
|
||||||
def validate_reviewers(self, reviewers):
|
def validate_reviewers(self, reviewers):
|
||||||
action = self.initial_data.get('action')
|
action = self.initial_data.get('action')
|
||||||
if not action and self.instance:
|
if not action and self.instance:
|
||||||
@@ -118,19 +132,4 @@ class BaseACLSerializer(ActionAclSerializer, serializers.Serializer):
|
|||||||
"None of the reviewers belong to Organization `{}`".format(org.name)
|
"None of the reviewers belong to Organization `{}`".format(org.name)
|
||||||
)
|
)
|
||||||
raise serializers.ValidationError(error)
|
raise serializers.ValidationError(error)
|
||||||
return valid_reviewers
|
return valid_reviewers
|
||||||
|
|
||||||
|
|
||||||
class BaseUserACLSerializer(BaseACLSerializer):
|
|
||||||
users = JSONManyToManyField(label=_('User'))
|
|
||||||
|
|
||||||
class Meta(BaseACLSerializer.Meta):
|
|
||||||
fields = BaseACLSerializer.Meta.fields + ['users']
|
|
||||||
|
|
||||||
|
|
||||||
class BaseUserAssetAccountACLSerializer(BaseUserACLSerializer):
|
|
||||||
assets = JSONManyToManyField(label=_('Asset'))
|
|
||||||
accounts = serializers.ListField(label=_('Account'))
|
|
||||||
|
|
||||||
class Meta(BaseUserACLSerializer.Meta):
|
|
||||||
fields = BaseUserACLSerializer.Meta.fields + ['assets', 'accounts']
|
|
||||||
19
apps/acls/serializers/data_masking.py
Normal file
19
apps/acls/serializers/data_masking.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from acls.models import MaskingMethod, DataMaskingRule
|
||||||
|
from common.serializers.fields import LabeledChoiceField
|
||||||
|
from common.serializers.mixin import CommonBulkModelSerializer
|
||||||
|
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
|
from .base import BaseUserAssetAccountACLSerializer as BaseSerializer
|
||||||
|
|
||||||
|
__all__ = ['DataMaskingRuleSerializer']
|
||||||
|
|
||||||
|
|
||||||
|
class DataMaskingRuleSerializer(BaseSerializer, BulkOrgResourceModelSerializer):
|
||||||
|
masking_method = LabeledChoiceField(
|
||||||
|
choices=MaskingMethod.choices, default=MaskingMethod.fixed_char, label=_('Masking Method')
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(BaseSerializer.Meta):
|
||||||
|
model = DataMaskingRule
|
||||||
|
fields = BaseSerializer.Meta.fields + ['fields_pattern', 'masking_method', 'mask_pattern']
|
||||||
@@ -17,7 +17,7 @@ class LoginACLSerializer(BaseUserACLSerializer, CommonBulkModelSerializer):
|
|||||||
|
|
||||||
class Meta(BaseUserACLSerializer.Meta):
|
class Meta(BaseUserACLSerializer.Meta):
|
||||||
model = LoginACL
|
model = LoginACL
|
||||||
fields = list((set(BaseUserACLSerializer.Meta.fields) | {'rules'}) - {'org_id'})
|
fields = list((set(BaseUserACLSerializer.Meta.fields) | {'rules'}))
|
||||||
action_choices_exclude = [
|
action_choices_exclude = [
|
||||||
ActionChoices.warning,
|
ActionChoices.warning,
|
||||||
ActionChoices.notify_and_warn,
|
ActionChoices.notify_and_warn,
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<h3>{% trans 'Dear' %}: {{ recipient.name }}[{{ recipient.username }}]</h3>
|
<h3>{% trans 'Dear' %}: {{ recipient_name }}[{{ recipient_username }}]</h3>
|
||||||
<hr>
|
<hr>
|
||||||
<p>{% trans 'We would like to inform you that a user has recently logged into the following asset:' %}<p>
|
<p>{% trans 'We would like to inform you that a user has recently logged into the following asset:' %}<p>
|
||||||
<p><strong>{% trans 'Asset details' %}:</strong></p>
|
<p><strong>{% trans 'Asset details' %}:</strong></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>{% trans 'User' %}:</strong> [{{ name }}({{ username }})]</li>
|
<li><strong>{% trans 'User' %}:</strong> [{{ name }}({{ username }})]</li>
|
||||||
|
<li><strong>IP:</strong> [{{ ip }}]</li>
|
||||||
<li><strong>{% trans 'Assets' %}:</strong> [{{ asset }}]</li>
|
<li><strong>{% trans 'Assets' %}:</strong> [{{ asset }}]</li>
|
||||||
<li><strong>{% trans 'Account' %}:</strong> [{{ account_name }}({{ account }})]</li>
|
<li><strong>{% trans 'Account' %}:</strong> [{{ account_name }}({{ account }})]</li>
|
||||||
|
<li><strong>{% trans 'Login asset acl' %}:</strong> [{{ acl_name }}]</li>
|
||||||
|
<li><strong>{% trans 'Login from' %}:</strong> [{{ login_from }}]</li>
|
||||||
|
<li><strong>{% trans 'Time' %}:</strong> [{{ time }}]</li>
|
||||||
</ul>
|
</ul>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<h3>{% trans 'Dear' %}: {{ recipient.name }}[{{ recipient.username }}]</h3>
|
<h3>{% trans 'Dear' %}: {{ recipient_name }}[{{ recipient_username }}]</h3>
|
||||||
<hr>
|
<hr>
|
||||||
<p>{% trans 'We would like to inform you that a user has recently logged:' %}<p>
|
<p>{% trans 'We would like to inform you that a user has recently logged:' %}<p>
|
||||||
<p><strong>{% trans 'User details' %}:</strong></p>
|
<p><strong>{% trans 'User details' %}:</strong></p>
|
||||||
@@ -8,7 +8,10 @@
|
|||||||
<li><strong>{% trans 'User' %}:</strong> [{{ username }}]</li>
|
<li><strong>{% trans 'User' %}:</strong> [{{ username }}]</li>
|
||||||
<li><strong>IP:</strong> [{{ ip }}]</li>
|
<li><strong>IP:</strong> [{{ ip }}]</li>
|
||||||
<li><strong>{% trans 'Login city' %}:</strong> [{{ city }}]</li>
|
<li><strong>{% trans 'Login city' %}:</strong> [{{ city }}]</li>
|
||||||
|
<li><strong>{% trans 'Login from' %}:</strong> [{{ login_from }}]</li>
|
||||||
<li><strong>{% trans 'User agent' %}:</strong> [{{ user_agent }}]</li>
|
<li><strong>{% trans 'User agent' %}:</strong> [{{ user_agent }}]</li>
|
||||||
|
<li><strong>{% trans 'Login acl' %}:</strong> [{{ acl_name }}]</li>
|
||||||
|
<li><strong>{% trans 'Time' %}:</strong> [{{ time }}]</li>
|
||||||
</ul>
|
</ul>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ router.register(r'login-asset-acls', api.LoginAssetACLViewSet, 'login-asset-acl'
|
|||||||
router.register(r'command-filter-acls', api.CommandFilterACLViewSet, 'command-filter-acl')
|
router.register(r'command-filter-acls', api.CommandFilterACLViewSet, 'command-filter-acl')
|
||||||
router.register(r'command-groups', api.CommandGroupViewSet, 'command-group')
|
router.register(r'command-groups', api.CommandGroupViewSet, 'command-group')
|
||||||
router.register(r'connect-method-acls', api.ConnectMethodACLViewSet, 'connect-method-acl')
|
router.register(r'connect-method-acls', api.ConnectMethodACLViewSet, 'connect-method-acl')
|
||||||
|
router.register(r'data-masking-rules', api.DataMaskingRuleViewSet, 'data-masking-rule')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('login-asset/check/', api.LoginAssetCheckAPI.as_view(), name='login-asset-check'),
|
path('login-asset/check/', api.LoginAssetCheckAPI.as_view(), name='login-asset-check'),
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class BaseAssetViewSet(OrgBulkModelViewSet):
|
|||||||
("accounts", AccountSerializer),
|
("accounts", AccountSerializer),
|
||||||
)
|
)
|
||||||
rbac_perms = (
|
rbac_perms = (
|
||||||
("match", "assets.match_asset"),
|
("match", "assets.view_asset"),
|
||||||
("platform", "assets.view_platform"),
|
("platform", "assets.view_platform"),
|
||||||
("gateways", "assets.view_gateway"),
|
("gateways", "assets.view_gateway"),
|
||||||
("accounts", "assets.view_account"),
|
("accounts", "assets.view_account"),
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ class CategoryViewSet(ListModelMixin, JMSGenericViewSet):
|
|||||||
'types': TypeSerializer,
|
'types': TypeSerializer,
|
||||||
}
|
}
|
||||||
permission_classes = (IsValidUser,)
|
permission_classes = (IsValidUser,)
|
||||||
default_limit = None
|
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return AllTypes.categories()
|
return AllTypes.categories()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class FavoriteAssetViewSet(BulkModelViewSet):
|
|||||||
serializer_class = FavoriteAssetSerializer
|
serializer_class = FavoriteAssetSerializer
|
||||||
permission_classes = (IsValidUser,)
|
permission_classes = (IsValidUser,)
|
||||||
filterset_fields = ['asset']
|
filterset_fields = ['asset']
|
||||||
default_limit = None
|
page_no_limit = True
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
with tmp_to_root_org():
|
with tmp_to_root_org():
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class NodeViewSet(SuggestionMixin, OrgBulkModelViewSet):
|
|||||||
search_fields = ('full_value',)
|
search_fields = ('full_value',)
|
||||||
serializer_class = serializers.NodeSerializer
|
serializer_class = serializers.NodeSerializer
|
||||||
rbac_perms = {
|
rbac_perms = {
|
||||||
'match': 'assets.match_node',
|
'match': 'assets.view_node',
|
||||||
'check_assets_amount_task': 'assets.change_node'
|
'check_assets_amount_task': 'assets.change_node'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class AssetPlatformViewSet(JMSModelViewSet):
|
|||||||
'ops_methods': 'assets.view_platform',
|
'ops_methods': 'assets.view_platform',
|
||||||
'filter_nodes_assets': 'assets.view_platform',
|
'filter_nodes_assets': 'assets.view_platform',
|
||||||
}
|
}
|
||||||
default_limit = None
|
page_no_limit = True
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
# 因为没有走分页逻辑,所以需要这里 prefetch
|
# 因为没有走分页逻辑,所以需要这里 prefetch
|
||||||
@@ -112,8 +112,10 @@ class PlatformProtocolViewSet(JMSModelViewSet):
|
|||||||
|
|
||||||
|
|
||||||
class PlatformAutomationMethodsApi(generics.ListAPIView):
|
class PlatformAutomationMethodsApi(generics.ListAPIView):
|
||||||
permission_classes = (IsValidUser,)
|
|
||||||
queryset = PlatformAutomation.objects.none()
|
queryset = PlatformAutomation.objects.none()
|
||||||
|
rbac_perms = {
|
||||||
|
'list': 'assets.view_platform'
|
||||||
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def automation_methods():
|
def automation_methods():
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
from rest_framework.generics import ListAPIView
|
from rest_framework.generics import ListAPIView
|
||||||
|
|
||||||
from assets import serializers
|
from assets import serializers
|
||||||
|
from assets.const import Protocol
|
||||||
from common.permissions import IsValidUser
|
from common.permissions import IsValidUser
|
||||||
from assets.models import Protocol
|
|
||||||
|
|
||||||
__all__ = ['ProtocolListApi']
|
__all__ = ['ProtocolListApi']
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from orgs.models import Organization
|
||||||
from .base import BaseType
|
from .base import BaseType
|
||||||
|
|
||||||
|
|
||||||
@@ -52,3 +53,41 @@ class GPTTypes(BaseType):
|
|||||||
return [
|
return [
|
||||||
cls.CHATGPT,
|
cls.CHATGPT,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
CHATX_NAME = 'ChatX'
|
||||||
|
|
||||||
|
|
||||||
|
def create_or_update_chatx_resources(chatx_name=CHATX_NAME, org_id=Organization.SYSTEM_ID):
|
||||||
|
from django.apps import apps
|
||||||
|
|
||||||
|
platform_model = apps.get_model('assets', 'Platform')
|
||||||
|
asset_model = apps.get_model('assets', 'Asset')
|
||||||
|
account_model = apps.get_model('accounts', 'Account')
|
||||||
|
|
||||||
|
platform, __ = platform_model.objects.get_or_create(
|
||||||
|
name=chatx_name,
|
||||||
|
defaults={
|
||||||
|
'internal': True,
|
||||||
|
'type': chatx_name,
|
||||||
|
'category': 'ai',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
asset, __ = asset_model.objects.get_or_create(
|
||||||
|
address=chatx_name,
|
||||||
|
defaults={
|
||||||
|
'name': chatx_name,
|
||||||
|
'platform': platform,
|
||||||
|
'org_id': org_id
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
account, __ = account_model.objects.get_or_create(
|
||||||
|
username=chatx_name,
|
||||||
|
defaults={
|
||||||
|
'name': chatx_name,
|
||||||
|
'asset': asset,
|
||||||
|
'org_id': org_id
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return asset, account
|
||||||
|
|||||||
@@ -59,7 +59,10 @@ class DatabaseSerializer(AssetSerializer):
|
|||||||
if not platform:
|
if not platform:
|
||||||
return
|
return
|
||||||
|
|
||||||
if platform.type in ['mysql', 'mariadb']:
|
if platform.type in [
|
||||||
|
'mysql', 'mariadb', 'oracle', 'sqlserver',
|
||||||
|
'db2', 'dameng', 'clickhouse', 'redis'
|
||||||
|
]:
|
||||||
db_field.required = False
|
db_field.required = False
|
||||||
db_field.allow_blank = True
|
db_field.allow_blank = True
|
||||||
db_field.allow_null = True
|
db_field.allow_null = True
|
||||||
|
|||||||
@@ -26,4 +26,13 @@ class WebSerializer(AssetSerializer):
|
|||||||
'submit_selector': {
|
'submit_selector': {
|
||||||
'default': 'id=login_button',
|
'default': 'id=login_button',
|
||||||
},
|
},
|
||||||
|
'script': {
|
||||||
|
'default': [],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def to_internal_value(self, data):
|
||||||
|
data = data.copy()
|
||||||
|
if data.get('script') in ("", None):
|
||||||
|
data.pop('script', None)
|
||||||
|
return super().to_internal_value(data)
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ def send_login_info_to_reviewers(instance: UserLoginLog | str, auth_acl_id):
|
|||||||
|
|
||||||
reviewers = acl.reviewers.all()
|
reviewers = acl.reviewers.all()
|
||||||
for reviewer in reviewers:
|
for reviewer in reviewers:
|
||||||
UserLoginReminderMsg(reviewer, instance).publish_async()
|
UserLoginReminderMsg(reviewer, instance, acl).publish_async()
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_auth_success)
|
@receiver(post_auth_success)
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ class RDPFileClientProtocolURLMixin:
|
|||||||
'autoreconnection enabled:i': '1',
|
'autoreconnection enabled:i': '1',
|
||||||
'bookmarktype:i': '3',
|
'bookmarktype:i': '3',
|
||||||
'use redirection server name:i': '0',
|
'use redirection server name:i': '0',
|
||||||
|
'bitmapcachepersistenable:i': '0',
|
||||||
|
'bitmapcachesize:i': '1500',
|
||||||
}
|
}
|
||||||
|
|
||||||
# copy from
|
# copy from
|
||||||
@@ -76,7 +78,6 @@ class RDPFileClientProtocolURLMixin:
|
|||||||
rdp_low_speed_broadband_option = {
|
rdp_low_speed_broadband_option = {
|
||||||
"connection type:i": 2,
|
"connection type:i": 2,
|
||||||
"disable wallpaper:i": 1,
|
"disable wallpaper:i": 1,
|
||||||
"bitmapcachepersistenable:i": 1,
|
|
||||||
"disable full window drag:i": 1,
|
"disable full window drag:i": 1,
|
||||||
"disable menu anims:i": 1,
|
"disable menu anims:i": 1,
|
||||||
"allow font smoothing:i": 0,
|
"allow font smoothing:i": 0,
|
||||||
@@ -87,7 +88,6 @@ class RDPFileClientProtocolURLMixin:
|
|||||||
rdp_high_speed_broadband_option = {
|
rdp_high_speed_broadband_option = {
|
||||||
"connection type:i": 4,
|
"connection type:i": 4,
|
||||||
"disable wallpaper:i": 0,
|
"disable wallpaper:i": 0,
|
||||||
"bitmapcachepersistenable:i": 1,
|
|
||||||
"disable full window drag:i": 1,
|
"disable full window drag:i": 1,
|
||||||
"disable menu anims:i": 0,
|
"disable menu anims:i": 0,
|
||||||
"allow font smoothing:i": 0,
|
"allow font smoothing:i": 0,
|
||||||
@@ -362,6 +362,7 @@ class ConnectionTokenViewSet(AuthFaceMixin, ExtraActionApiMixin, RootOrgViewMixi
|
|||||||
self.validate_serializer(serializer)
|
self.validate_serializer(serializer)
|
||||||
return super().perform_create(serializer)
|
return super().perform_create(serializer)
|
||||||
|
|
||||||
|
|
||||||
def _insert_connect_options(self, data, user):
|
def _insert_connect_options(self, data, user):
|
||||||
connect_options = data.pop('connect_options', {})
|
connect_options = data.pop('connect_options', {})
|
||||||
default_name_opts = {
|
default_name_opts = {
|
||||||
@@ -375,7 +376,7 @@ class ConnectionTokenViewSet(AuthFaceMixin, ExtraActionApiMixin, RootOrgViewMixi
|
|||||||
for name in default_name_opts.keys():
|
for name in default_name_opts.keys():
|
||||||
value = preferences.get(name, default_name_opts[name])
|
value = preferences.get(name, default_name_opts[name])
|
||||||
connect_options[name] = value
|
connect_options[name] = value
|
||||||
connect_options['lang'] = getattr(user, 'lang', settings.LANGUAGE_CODE)
|
connect_options['lang'] = getattr(user, 'lang') or settings.LANGUAGE_CODE
|
||||||
data['connect_options'] = connect_options
|
data['connect_options'] = connect_options
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -431,7 +432,7 @@ class ConnectionTokenViewSet(AuthFaceMixin, ExtraActionApiMixin, RootOrgViewMixi
|
|||||||
if account.username != AliasAccount.INPUT:
|
if account.username != AliasAccount.INPUT:
|
||||||
data['input_username'] = ''
|
data['input_username'] = ''
|
||||||
|
|
||||||
ticket = self._validate_acl(user, asset, account, connect_method)
|
ticket = self._validate_acl(user, asset, account, connect_method, protocol)
|
||||||
if ticket:
|
if ticket:
|
||||||
data['from_ticket'] = ticket
|
data['from_ticket'] = ticket
|
||||||
|
|
||||||
@@ -470,7 +471,7 @@ class ConnectionTokenViewSet(AuthFaceMixin, ExtraActionApiMixin, RootOrgViewMixi
|
|||||||
after=after, object_name=object_name
|
after=after, object_name=object_name
|
||||||
)
|
)
|
||||||
|
|
||||||
def _validate_acl(self, user, asset, account, connect_method):
|
def _validate_acl(self, user, asset, account, connect_method, protocol):
|
||||||
from acls.models import LoginAssetACL
|
from acls.models import LoginAssetACL
|
||||||
kwargs = {'user': user, 'asset': asset, 'account': account}
|
kwargs = {'user': user, 'asset': asset, 'account': account}
|
||||||
if account.username == AliasAccount.INPUT:
|
if account.username == AliasAccount.INPUT:
|
||||||
@@ -523,9 +524,15 @@ class ConnectionTokenViewSet(AuthFaceMixin, ExtraActionApiMixin, RootOrgViewMixi
|
|||||||
return
|
return
|
||||||
|
|
||||||
self._record_operate_log(acl, asset)
|
self._record_operate_log(acl, asset)
|
||||||
|
os = get_request_os(self.request) if self.request else 'windows'
|
||||||
|
method = ConnectMethodUtil.get_connect_method(
|
||||||
|
connect_method, protocol=protocol, os=os
|
||||||
|
)
|
||||||
|
login_from = method['label'] if method else connect_method
|
||||||
for reviewer in reviewers:
|
for reviewer in reviewers:
|
||||||
AssetLoginReminderMsg(
|
AssetLoginReminderMsg(
|
||||||
reviewer, asset, user, account, self.input_username
|
reviewer, asset, user, account, acl,
|
||||||
|
ip, self.input_username, login_from
|
||||||
).publish_async()
|
).publish_async()
|
||||||
|
|
||||||
def create_face_verify(self, response):
|
def create_face_verify(self, response):
|
||||||
@@ -558,7 +565,9 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
|
|||||||
rbac_perms = {
|
rbac_perms = {
|
||||||
'create': 'authentication.add_superconnectiontoken',
|
'create': 'authentication.add_superconnectiontoken',
|
||||||
'renewal': 'authentication.add_superconnectiontoken',
|
'renewal': 'authentication.add_superconnectiontoken',
|
||||||
|
'list': 'authentication.view_superconnectiontoken',
|
||||||
'check': 'authentication.view_superconnectiontoken',
|
'check': 'authentication.view_superconnectiontoken',
|
||||||
|
'retrieve': 'authentication.view_superconnectiontoken',
|
||||||
'get_secret_detail': 'authentication.view_superconnectiontokensecret',
|
'get_secret_detail': 'authentication.view_superconnectiontokensecret',
|
||||||
'get_applet_info': 'authentication.view_superconnectiontoken',
|
'get_applet_info': 'authentication.view_superconnectiontoken',
|
||||||
'release_applet_account': 'authentication.view_superconnectiontoken',
|
'release_applet_account': 'authentication.view_superconnectiontoken',
|
||||||
@@ -566,7 +575,12 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return ConnectionToken.objects.all()
|
return ConnectionToken.objects.none()
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
pk = self.kwargs.get(self.lookup_field)
|
||||||
|
token = get_object_or_404(ConnectionToken, pk=pk)
|
||||||
|
return token
|
||||||
|
|
||||||
def get_user(self, serializer):
|
def get_user(self, serializer):
|
||||||
return serializer.validated_data.get('user')
|
return serializer.validated_data.get('user')
|
||||||
|
|||||||
@@ -67,8 +67,9 @@ class UserResetPasswordSendCodeApi(CreateAPIView):
|
|||||||
|
|
||||||
code = random_string(settings.SMS_CODE_LENGTH, lower=False, upper=False)
|
code = random_string(settings.SMS_CODE_LENGTH, lower=False, upper=False)
|
||||||
subject = '%s: %s' % (get_login_title(), _('Forgot password'))
|
subject = '%s: %s' % (get_login_title(), _('Forgot password'))
|
||||||
|
tip = _('The validity period of the verification code is {} minute').format(settings.VERIFY_CODE_TTL // 60)
|
||||||
context = {
|
context = {
|
||||||
'user': user, 'title': subject, 'code': code,
|
'user': user, 'title': subject, 'code': code, 'tip': tip,
|
||||||
}
|
}
|
||||||
message = render_to_string('authentication/_msg_reset_password_code.html', context)
|
message = render_to_string('authentication/_msg_reset_password_code.html', context)
|
||||||
content = {'subject': subject, 'message': message}
|
content = {'subject': subject, 'message': message}
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ class JMSBaseAuthBackend:
|
|||||||
"""
|
"""
|
||||||
# 三方用户认证完成后,在后续的 get_user 获取逻辑中,也应该需要检查用户是否有效
|
# 三方用户认证完成后,在后续的 get_user 获取逻辑中,也应该需要检查用户是否有效
|
||||||
is_valid = getattr(user, 'is_valid', None)
|
is_valid = getattr(user, 'is_valid', None)
|
||||||
return is_valid or is_valid is None
|
if not is_valid:
|
||||||
|
logger.info("User %s is not valid", getattr(user, "username", "<unknown>"))
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
# allow user to authenticate
|
# allow user to authenticate
|
||||||
def username_allow_authenticate(self, username):
|
def username_allow_authenticate(self, username):
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ class SignatureAuthentication(signature.SignatureAuthentication):
|
|||||||
# example implementation:
|
# example implementation:
|
||||||
try:
|
try:
|
||||||
key = AccessKey.objects.get(id=key_id)
|
key = AccessKey.objects.get(id=key_id)
|
||||||
if not key.is_active:
|
if not key.is_valid:
|
||||||
return None, None
|
return None, None
|
||||||
user, secret = key.user, str(key.secret)
|
user, secret = key.user, str(key.secret)
|
||||||
after_authenticate_update_date(user, key)
|
after_authenticate_update_date(user, key)
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ class OIDCAuthCallbackView(View, FlashMessageMixin):
|
|||||||
log_prompt = "Process GET requests [OIDCAuthCallbackView]: {}"
|
log_prompt = "Process GET requests [OIDCAuthCallbackView]: {}"
|
||||||
logger.debug(log_prompt.format('Start'))
|
logger.debug(log_prompt.format('Start'))
|
||||||
callback_params = request.GET
|
callback_params = request.GET
|
||||||
|
error_title = _("OpenID Error")
|
||||||
|
|
||||||
# Retrieve the state value that was previously generated. No state means that we cannot
|
# Retrieve the state value that was previously generated. No state means that we cannot
|
||||||
# authenticate the user (so a failure should be returned).
|
# authenticate the user (so a failure should be returned).
|
||||||
@@ -172,10 +173,9 @@ class OIDCAuthCallbackView(View, FlashMessageMixin):
|
|||||||
try:
|
try:
|
||||||
user = auth.authenticate(nonce=nonce, request=request, code_verifier=code_verifier)
|
user = auth.authenticate(nonce=nonce, request=request, code_verifier=code_verifier)
|
||||||
except IntegrityError as e:
|
except IntegrityError as e:
|
||||||
title = _("OpenID Error")
|
|
||||||
msg = _('Please check if a user with the same username or email already exists')
|
msg = _('Please check if a user with the same username or email already exists')
|
||||||
logger.error(e, exc_info=True)
|
logger.error(e, exc_info=True)
|
||||||
response = self.get_failed_response('/', title, msg)
|
response = self.get_failed_response('/', error_title, msg)
|
||||||
return response
|
return response
|
||||||
if user:
|
if user:
|
||||||
logger.debug(log_prompt.format('Login: {}'.format(user)))
|
logger.debug(log_prompt.format('Login: {}'.format(user)))
|
||||||
@@ -194,7 +194,6 @@ class OIDCAuthCallbackView(View, FlashMessageMixin):
|
|||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
next_url or settings.AUTH_OPENID_AUTHENTICATION_REDIRECT_URI
|
next_url or settings.AUTH_OPENID_AUTHENTICATION_REDIRECT_URI
|
||||||
)
|
)
|
||||||
|
|
||||||
if 'error' in callback_params:
|
if 'error' in callback_params:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
log_prompt.format('Error in callback params: {}'.format(callback_params['error']))
|
log_prompt.format('Error in callback params: {}'.format(callback_params['error']))
|
||||||
@@ -205,9 +204,12 @@ class OIDCAuthCallbackView(View, FlashMessageMixin):
|
|||||||
# OpenID Connect Provider authenticate endpoint.
|
# OpenID Connect Provider authenticate endpoint.
|
||||||
logger.debug(log_prompt.format('Logout'))
|
logger.debug(log_prompt.format('Logout'))
|
||||||
auth.logout(request)
|
auth.logout(request)
|
||||||
|
redirect_url = settings.AUTH_OPENID_AUTHENTICATION_FAILURE_REDIRECT_URI
|
||||||
|
if not user and getattr(request, 'error_message', ''):
|
||||||
|
response = self.get_failed_response(redirect_url, title=error_title, msg=request.error_message)
|
||||||
|
return response
|
||||||
logger.debug(log_prompt.format('Redirect'))
|
logger.debug(log_prompt.format('Redirect'))
|
||||||
return HttpResponseRedirect(settings.AUTH_OPENID_AUTHENTICATION_FAILURE_REDIRECT_URI)
|
return HttpResponseRedirect(redirect_url)
|
||||||
|
|
||||||
|
|
||||||
class OIDCAuthCallbackClientView(BaseAuthCallbackClientView):
|
class OIDCAuthCallbackClientView(BaseAuthCallbackClientView):
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class BaseMFA(abc.ABC):
|
|||||||
if not ok:
|
if not ok:
|
||||||
return False, msg
|
return False, msg
|
||||||
|
|
||||||
cache.set(cache_key, code, 60)
|
cache.set(cache_key, code, settings.VERIFY_CODE_TTL)
|
||||||
return True, msg
|
return True, msg
|
||||||
|
|
||||||
def is_authenticated(self):
|
def is_authenticated(self):
|
||||||
|
|||||||
@@ -39,13 +39,14 @@ class MFAEmail(BaseMFA):
|
|||||||
def send_challenge(self):
|
def send_challenge(self):
|
||||||
code = random_string(settings.SMS_CODE_LENGTH, lower=False, upper=False)
|
code = random_string(settings.SMS_CODE_LENGTH, lower=False, upper=False)
|
||||||
subject = '%s: %s' % (get_login_title(), _('MFA code'))
|
subject = '%s: %s' % (get_login_title(), _('MFA code'))
|
||||||
|
tip = _('The validity period of the verification code is {} minute').format(settings.VERIFY_CODE_TTL // 60)
|
||||||
context = {
|
context = {
|
||||||
'user': self.user, 'title': subject, 'code': code,
|
'user': self.user, 'title': subject, 'code': code, 'tip': tip,
|
||||||
}
|
}
|
||||||
message = render_to_string('authentication/_msg_mfa_email_code.html', context)
|
message = render_to_string('authentication/_msg_mfa_email_code.html', context)
|
||||||
content = {'subject': subject, 'message': message}
|
content = {'subject': subject, 'message': message}
|
||||||
sender_util = SendAndVerifyCodeUtil(
|
sender_util = SendAndVerifyCodeUtil(
|
||||||
self.user.email, code=code, backend=self.name, timeout=60, **content
|
self.user.email, code=code, backend=self.name, **content
|
||||||
)
|
)
|
||||||
sender_util.gen_and_send_async()
|
sender_util.gen_and_send_async()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
import inspect
|
import inspect
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
from functools import partial
|
from functools import partial
|
||||||
@@ -12,6 +13,7 @@ from django.contrib.auth import (
|
|||||||
BACKEND_SESSION_KEY, load_backend,
|
BACKEND_SESSION_KEY, load_backend,
|
||||||
PermissionDenied, user_login_failed, _clean_credentials,
|
PermissionDenied, user_login_failed, _clean_credentials,
|
||||||
)
|
)
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.shortcuts import reverse, redirect, get_object_or_404
|
from django.shortcuts import reverse, redirect, get_object_or_404
|
||||||
@@ -46,6 +48,10 @@ def _get_backends(return_tuples=False):
|
|||||||
return backends
|
return backends
|
||||||
|
|
||||||
|
|
||||||
|
class OnlyAllowExistUserAuthError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
auth._get_backends = _get_backends
|
auth._get_backends = _get_backends
|
||||||
|
|
||||||
|
|
||||||
@@ -54,6 +60,24 @@ 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 这个 authenticate
|
之所以 hack 这个 authenticate
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
UserModel = get_user_model()
|
||||||
|
original_get_or_create = UserModel.objects.get_or_create
|
||||||
|
|
||||||
|
thread_local = threading.local()
|
||||||
|
thread_local.thread_id = threading.get_ident()
|
||||||
|
|
||||||
|
def custom_get_or_create(self, *args, **kwargs):
|
||||||
|
logger.debug(f"get_or_create: thread_id={threading.get_ident()}, username={username}")
|
||||||
|
if threading.get_ident() != thread_local.thread_id or not settings.ONLY_ALLOW_EXIST_USER_AUTH:
|
||||||
|
return original_get_or_create(*args, **kwargs)
|
||||||
|
create_username = kwargs.get('username')
|
||||||
|
try:
|
||||||
|
UserModel.objects.get(username=create_username)
|
||||||
|
except UserModel.DoesNotExist:
|
||||||
|
raise OnlyAllowExistUserAuthError
|
||||||
|
return original_get_or_create(*args, **kwargs)
|
||||||
|
|
||||||
username = credentials.get('username')
|
username = credentials.get('username')
|
||||||
|
|
||||||
temp_user = None
|
temp_user = None
|
||||||
@@ -71,10 +95,19 @@ def authenticate(request=None, **credentials):
|
|||||||
# This backend doesn't accept these credentials as arguments. Try the next one.
|
# This backend doesn't accept these credentials as arguments. Try the next one.
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
|
UserModel.objects.get_or_create = custom_get_or_create.__get__(UserModel.objects)
|
||||||
user = backend.authenticate(request, **credentials)
|
user = backend.authenticate(request, **credentials)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
# This backend says to stop in our tracks - this user should not be allowed in at all.
|
# This backend says to stop in our tracks - this user should not be allowed in at all.
|
||||||
break
|
break
|
||||||
|
except OnlyAllowExistUserAuthError:
|
||||||
|
request.error_message = _(
|
||||||
|
'''The administrator has enabled "Only allow existing users to log in",
|
||||||
|
and the current user is not in the user list. Please contact the administrator.'''
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
finally:
|
||||||
|
UserModel.objects.get_or_create = original_get_or_create
|
||||||
if user is None:
|
if user is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ class AccessKey(models.Model):
|
|||||||
date_last_used = models.DateTimeField(null=True, blank=True, verbose_name=_('Date last used'))
|
date_last_used = models.DateTimeField(null=True, blank=True, verbose_name=_('Date last used'))
|
||||||
date_created = models.DateTimeField(auto_now_add=True)
|
date_created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_valid(self):
|
||||||
|
return self.is_active and self.user.is_valid
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return str(self.id)
|
return str(self.id)
|
||||||
|
|
||||||
|
|||||||
@@ -338,6 +338,18 @@ class ConnectionToken(JMSOrgBaseModel):
|
|||||||
acls = CommandFilterACL.filter_queryset(**kwargs).valid()
|
acls = CommandFilterACL.filter_queryset(**kwargs).valid()
|
||||||
return acls
|
return acls
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def data_masking_rules(self):
|
||||||
|
from acls.models import DataMaskingRule
|
||||||
|
kwargs = {
|
||||||
|
'user': self.user,
|
||||||
|
'asset': self.asset,
|
||||||
|
'account': self.account_object,
|
||||||
|
}
|
||||||
|
with tmp_to_org(self.asset.org_id):
|
||||||
|
rules = DataMaskingRule.filter_queryset(**kwargs).valid()
|
||||||
|
return rules
|
||||||
|
|
||||||
|
|
||||||
class SuperConnectionToken(ConnectionToken):
|
class SuperConnectionToken(ConnectionToken):
|
||||||
_type = ConnectionTokenType.SUPER
|
_type = ConnectionTokenType.SUPER
|
||||||
|
|||||||
@@ -1,14 +1,24 @@
|
|||||||
from django.template.loader import render_to_string
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
|
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from common.utils.timezone import local_now_display
|
from common.utils.timezone import local_now_display
|
||||||
|
from common.views.template import custom_render_to_string
|
||||||
from notifications.notifications import UserMessage
|
from notifications.notifications import UserMessage
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
class DifferentCityLoginMessage(UserMessage):
|
class DifferentCityLoginMessage(UserMessage):
|
||||||
|
subject = _('Different city login reminder')
|
||||||
|
template_name = 'authentication/_msg_different_city.html'
|
||||||
|
contexts = [
|
||||||
|
{"name": "city", "label": _('Login city'), "default": "Shanghai"},
|
||||||
|
{"name": "username", "label": _('User'), "default": "john"},
|
||||||
|
{"name": "name", "label": _('Name'), "default": "John"},
|
||||||
|
{"name": "ip", "label": "IP", "default": "192.168.1.1"},
|
||||||
|
{"name": "time", "label": _('Login Date'), "default": "2025-01-01 12:00:00"},
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self, user, ip, city):
|
def __init__(self, user, ip, city):
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.city = city
|
self.city = city
|
||||||
@@ -16,18 +26,16 @@ class DifferentCityLoginMessage(UserMessage):
|
|||||||
|
|
||||||
def get_html_msg(self) -> dict:
|
def get_html_msg(self) -> dict:
|
||||||
now = local_now_display()
|
now = local_now_display()
|
||||||
subject = _('Different city login reminder')
|
|
||||||
context = dict(
|
context = dict(
|
||||||
subject=subject,
|
|
||||||
name=self.user.name,
|
name=self.user.name,
|
||||||
username=self.user.username,
|
username=self.user.username,
|
||||||
ip=self.ip,
|
ip=self.ip,
|
||||||
time=now,
|
time=now,
|
||||||
city=self.city,
|
city=self.city,
|
||||||
)
|
)
|
||||||
message = render_to_string('authentication/_msg_different_city.html', context)
|
message = custom_render_to_string(self.template_name, context)
|
||||||
return {
|
return {
|
||||||
'subject': subject,
|
'subject': str(self.subject),
|
||||||
'message': message
|
'message': message
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +49,16 @@ class DifferentCityLoginMessage(UserMessage):
|
|||||||
|
|
||||||
|
|
||||||
class OAuthBindMessage(UserMessage):
|
class OAuthBindMessage(UserMessage):
|
||||||
|
subject = _('OAuth binding reminder')
|
||||||
|
template_name = 'authentication/_msg_oauth_bind.html'
|
||||||
|
contexts = [
|
||||||
|
{"name": "username", "label": _('User'), "default": "john"},
|
||||||
|
{"name": "name", "label": _('Name'), "default": "John"},
|
||||||
|
{"name": "ip", "label": "IP", "default": "192.168.1.1"},
|
||||||
|
{"name": "oauth_name", "label": _('OAuth name'), "default": "WeCom"},
|
||||||
|
{"name": "oauth_id", "label": _('OAuth ID'), "default": "000001"},
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self, user, ip, oauth_name, oauth_id):
|
def __init__(self, user, ip, oauth_name, oauth_id):
|
||||||
super().__init__(user)
|
super().__init__(user)
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
@@ -51,7 +69,6 @@ class OAuthBindMessage(UserMessage):
|
|||||||
now = local_now_display()
|
now = local_now_display()
|
||||||
subject = self.oauth_name + ' ' + _('binding reminder')
|
subject = self.oauth_name + ' ' + _('binding reminder')
|
||||||
context = dict(
|
context = dict(
|
||||||
subject=subject,
|
|
||||||
name=self.user.name,
|
name=self.user.name,
|
||||||
username=self.user.username,
|
username=self.user.username,
|
||||||
ip=self.ip,
|
ip=self.ip,
|
||||||
@@ -59,9 +76,9 @@ class OAuthBindMessage(UserMessage):
|
|||||||
oauth_name=self.oauth_name,
|
oauth_name=self.oauth_name,
|
||||||
oauth_id=self.oauth_id
|
oauth_id=self.oauth_id
|
||||||
)
|
)
|
||||||
message = render_to_string('authentication/_msg_oauth_bind.html', context)
|
message = custom_render_to_string(self.template_name, context)
|
||||||
return {
|
return {
|
||||||
'subject': subject,
|
'subject': str(subject),
|
||||||
'message': message
|
'message': message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
from accounts.const import SecretType
|
from accounts.const import SecretType
|
||||||
from accounts.models import Account
|
from accounts.models import Account
|
||||||
from acls.models import CommandGroup, CommandFilterACL
|
from acls.models import CommandGroup, CommandFilterACL, DataMaskingRule
|
||||||
from assets.models import Asset, Platform, Gateway, Zone
|
from assets.models import Asset, Platform, Gateway, Zone
|
||||||
from assets.serializers.asset import AssetProtocolsSerializer
|
from assets.serializers.asset import AssetProtocolsSerializer
|
||||||
from assets.serializers.platform import PlatformSerializer
|
from assets.serializers.platform import PlatformSerializer
|
||||||
@@ -83,6 +83,14 @@ class _ConnectionTokenGatewaySerializer(serializers.ModelSerializer):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class _ConnectionTokenDataMaskingRuleSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = DataMaskingRule
|
||||||
|
fields = ['id', 'name', 'fields_pattern',
|
||||||
|
'masking_method', 'mask_pattern',
|
||||||
|
'is_active', 'priority']
|
||||||
|
|
||||||
|
|
||||||
class _ConnectionTokenCommandFilterACLSerializer(serializers.ModelSerializer):
|
class _ConnectionTokenCommandFilterACLSerializer(serializers.ModelSerializer):
|
||||||
command_groups = ObjectRelatedField(
|
command_groups = ObjectRelatedField(
|
||||||
many=True, required=False, queryset=CommandGroup.objects,
|
many=True, required=False, queryset=CommandGroup.objects,
|
||||||
@@ -105,7 +113,7 @@ class _ConnectionTokenPlatformSerializer(PlatformSerializer):
|
|||||||
class Meta(PlatformSerializer.Meta):
|
class Meta(PlatformSerializer.Meta):
|
||||||
model = Platform
|
model = Platform
|
||||||
fields = [field for field in PlatformSerializer.Meta.fields
|
fields = [field for field in PlatformSerializer.Meta.fields
|
||||||
if field not in PlatformSerializer.Meta.fields_m2m]
|
if field not in PlatformSerializer.Meta.fields_m2m]
|
||||||
|
|
||||||
def get_field_names(self, declared_fields, info):
|
def get_field_names(self, declared_fields, info):
|
||||||
names = super().get_field_names(declared_fields, info)
|
names = super().get_field_names(declared_fields, info)
|
||||||
@@ -139,6 +147,7 @@ class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin):
|
|||||||
platform = _ConnectionTokenPlatformSerializer(read_only=True)
|
platform = _ConnectionTokenPlatformSerializer(read_only=True)
|
||||||
zone = ObjectRelatedField(queryset=Zone.objects, required=False, label=_('Domain'))
|
zone = ObjectRelatedField(queryset=Zone.objects, required=False, label=_('Domain'))
|
||||||
command_filter_acls = _ConnectionTokenCommandFilterACLSerializer(read_only=True, many=True)
|
command_filter_acls = _ConnectionTokenCommandFilterACLSerializer(read_only=True, many=True)
|
||||||
|
data_masking_rules = _ConnectionTokenDataMaskingRuleSerializer(read_only=True, many=True)
|
||||||
expire_now = serializers.BooleanField(label=_('Expired now'), write_only=True, default=True)
|
expire_now = serializers.BooleanField(label=_('Expired now'), write_only=True, default=True)
|
||||||
connect_method = _ConnectTokenConnectMethodSerializer(read_only=True, source='connect_method_object')
|
connect_method = _ConnectTokenConnectMethodSerializer(read_only=True, source='connect_method_object')
|
||||||
connect_options = serializers.JSONField(read_only=True)
|
connect_options = serializers.JSONField(read_only=True)
|
||||||
@@ -149,7 +158,7 @@ class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin):
|
|||||||
model = ConnectionToken
|
model = ConnectionToken
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'value', 'user', 'asset', 'account',
|
'id', 'value', 'user', 'asset', 'account',
|
||||||
'platform', 'command_filter_acls', 'protocol',
|
'platform', 'command_filter_acls', 'data_masking_rules', 'protocol',
|
||||||
'zone', 'gateway', 'actions', 'expire_at',
|
'zone', 'gateway', 'actions', 'expire_at',
|
||||||
'from_ticket', 'expire_now', 'connect_method',
|
'from_ticket', 'expire_now', 'connect_method',
|
||||||
'connect_options', 'face_monitor_token'
|
'connect_options', 'face_monitor_token'
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<td style="height: 50px;">{% trans 'MFA code' %}: <span style="font-weight: bold;">{{ code }}</span></td>
|
<td style="height: 50px;">{% trans 'MFA code' %}: <span style="font-weight: bold;">{{ code }}</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="border: 1px solid #eee">
|
<tr style="border: 1px solid #eee">
|
||||||
<td style="height: 30px;">{% trans 'The validity period of the verification code is one minute' %}</td>
|
<td style="height: 30px;">{{ tip }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
<b>{% trans 'Time' %}:</b> {{ time }}<br>
|
<b>{% trans 'Time' %}:</b> {{ time }}<br>
|
||||||
<b>{% trans 'IP' %}:</b> {{ ip }}
|
<b>{% trans 'IP' %}:</b> {{ ip }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
-
|
|
||||||
<p>
|
<p>
|
||||||
{% trans 'If the operation is not your own, unbind and change the password.' %}
|
{% trans 'If the operation is not your own, unbind and change the password.' %}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -6,12 +6,12 @@
|
|||||||
{% trans 'Please click the link below to reset your password, if not your request, concern your account security' %}
|
{% trans 'Please click the link below to reset your password, if not your request, concern your account security' %}
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<a href="{{ rest_password_url }}?token={{ rest_password_token}}" class='showLink' target="_blank">
|
<a href="{{ rest_password_url }}?token={{ rest_password_token }}" class='showLink' target="_blank">
|
||||||
{% trans 'Click here reset password' %}
|
{% trans 'Click here reset password' %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<br>
|
<br>
|
||||||
<p>
|
<p>
|
||||||
{% trans 'This link is valid for 1 hour. After it expires' %}
|
{% trans 'This link is valid for 1 hour. After it expires' %}
|
||||||
<a href="{{ forget_password_url }}?email={{ user.email }}">{% trans 'request new one' %}</a>
|
<a href="{{ forget_password_url }}?email={{ email }}">{% trans 'request new one' %}</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<td style="height: 30px;"> {% trans 'Copy the verification code to the Reset Password page to reset the password.' %} </td>
|
<td style="height: 30px;"> {% trans 'Copy the verification code to the Reset Password page to reset the password.' %} </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="border: 1px solid #eee">
|
<tr style="border: 1px solid #eee">
|
||||||
<td style="height: 30px;">{% trans 'The validity period of the verification code is one minute' %}</td>
|
<td style="height: 30px;">{{ tip }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from common.utils import get_logger
|
|||||||
from common.utils.common import get_request_ip
|
from common.utils.common import get_request_ip
|
||||||
from common.utils.django import reverse, get_object_or_none
|
from common.utils.django import reverse, get_object_or_none
|
||||||
from users.models import User
|
from users.models import User
|
||||||
from users.signal_handlers import check_only_allow_exist_user_auth, bind_user_to_org_role
|
from users.signal_handlers import bind_user_to_org_role, check_only_allow_exist_user_auth
|
||||||
from .mixins import FlashMessageMixin
|
from .mixins import FlashMessageMixin
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
@@ -55,7 +55,6 @@ class BaseLoginCallbackView(AuthMixin, FlashMessageMixin, IMClientMixin, View):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not check_only_allow_exist_user_auth(create):
|
if not check_only_allow_exist_user_auth(create):
|
||||||
user.delete()
|
|
||||||
return user, (self.msg_client_err, self.request.error_message)
|
return user, (self.msg_client_err, self.request.error_message)
|
||||||
|
|
||||||
setattr(user, f'{self.user_type}_id', user_id)
|
setattr(user, f'{self.user_type}_id', user_id)
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
from django.conf import settings
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.throttling import UserRateThrottle
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
@@ -14,8 +16,12 @@ from orgs.utils import current_org
|
|||||||
__all__ = ['SuggestionMixin', 'RenderToJsonMixin']
|
__all__ = ['SuggestionMixin', 'RenderToJsonMixin']
|
||||||
|
|
||||||
|
|
||||||
|
class CustomUserRateThrottle(UserRateThrottle):
|
||||||
|
rate = '60/m'
|
||||||
|
|
||||||
|
|
||||||
class SuggestionMixin:
|
class SuggestionMixin:
|
||||||
suggestion_limit = 10
|
suggestion_limit = settings.SUGGESTION_LIMIT
|
||||||
|
|
||||||
filter_queryset: Callable
|
filter_queryset: Callable
|
||||||
get_queryset: Callable
|
get_queryset: Callable
|
||||||
@@ -35,6 +41,7 @@ class SuggestionMixin:
|
|||||||
queryset = queryset.none()
|
queryset = queryset.none()
|
||||||
|
|
||||||
queryset = self.filter_queryset(queryset)
|
queryset = self.filter_queryset(queryset)
|
||||||
|
|
||||||
queryset = queryset[:self.suggestion_limit]
|
queryset = queryset[:self.suggestion_limit]
|
||||||
page = self.paginate_queryset(queryset)
|
page = self.paginate_queryset(queryset)
|
||||||
|
|
||||||
@@ -45,6 +52,11 @@ class SuggestionMixin:
|
|||||||
serializer = self.get_serializer(queryset, many=True)
|
serializer = self.get_serializer(queryset, many=True)
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
def get_throttles(self):
|
||||||
|
if self.action == 'match':
|
||||||
|
return [CustomUserRateThrottle()]
|
||||||
|
return super().get_throttles()
|
||||||
|
|
||||||
|
|
||||||
class RenderToJsonMixin:
|
class RenderToJsonMixin:
|
||||||
@action(methods=[POST, PUT], detail=False, url_path='render-to-json')
|
@action(methods=[POST, PUT], detail=False, url_path='render-to-json')
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from contextlib import nullcontext
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.signals import m2m_changed
|
from django.db.models.signals import m2m_changed
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
@@ -16,6 +17,7 @@ from common.drf.filters import (
|
|||||||
IDNotFilterBackend, NotOrRelFilterBackend, LabelFilterBackend
|
IDNotFilterBackend, NotOrRelFilterBackend, LabelFilterBackend
|
||||||
)
|
)
|
||||||
from common.utils import get_logger, lazyproperty
|
from common.utils import get_logger, lazyproperty
|
||||||
|
from common.utils import is_uuid
|
||||||
from orgs.utils import tmp_to_org, tmp_to_root_org
|
from orgs.utils import tmp_to_org, tmp_to_root_org
|
||||||
from .action import RenderToJsonMixin
|
from .action import RenderToJsonMixin
|
||||||
from .serializer import SerializerMixin
|
from .serializer import SerializerMixin
|
||||||
@@ -95,9 +97,33 @@ class QuerySetMixin:
|
|||||||
request: Request
|
request: Request
|
||||||
get_serializer_class: Callable
|
get_serializer_class: Callable
|
||||||
get_queryset: Callable
|
get_queryset: Callable
|
||||||
|
slug_field = 'name'
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_object(self):
|
||||||
return super().get_queryset()
|
pk = self.kwargs.get(self.lookup_field)
|
||||||
|
if not pk or is_uuid(pk) or pk.isdigit():
|
||||||
|
return super().get_object()
|
||||||
|
return self.get_queryset().get(**{self.slug_field: pk})
|
||||||
|
|
||||||
|
def limit_queryset_if_no_page(self, queryset):
|
||||||
|
if self.request.query_params.get('format') in ['csv', 'xlsx']:
|
||||||
|
return queryset
|
||||||
|
action = getattr(self, 'action', None)
|
||||||
|
if action != 'list':
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
# 如果分页器有设置 limit,则不限制
|
||||||
|
if self.paginator and self.paginator.get_limit(self.request):
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
# 如果分页器没有设置 limit,则不限制
|
||||||
|
if getattr(self, 'page_no_limit', False):
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
if not settings.DEFAULT_PAGE_SIZE:
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
return queryset[:settings.DEFAULT_PAGE_SIZE]
|
||||||
|
|
||||||
def filter_queryset(self, queryset):
|
def filter_queryset(self, queryset):
|
||||||
queryset = super().filter_queryset(queryset)
|
queryset = super().filter_queryset(queryset)
|
||||||
@@ -106,6 +132,7 @@ class QuerySetMixin:
|
|||||||
if self.action == 'metadata':
|
if self.action == 'metadata':
|
||||||
queryset = queryset.none()
|
queryset = queryset.none()
|
||||||
queryset = self.setup_eager_loading(queryset)
|
queryset = self.setup_eager_loading(queryset)
|
||||||
|
queryset = self.limit_queryset_if_no_page(queryset)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def setup_eager_loading(self, queryset, is_paginated=False):
|
def setup_eager_loading(self, queryset, is_paginated=False):
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ class Language(models.TextChoices):
|
|||||||
es = 'es', 'Español'
|
es = 'es', 'Español'
|
||||||
ru = 'ru', 'Русский'
|
ru = 'ru', 'Русский'
|
||||||
ko = 'ko', '한국어'
|
ko = 'ko', '한국어'
|
||||||
|
vi = 'vi', 'Tiếng Việt'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_code_mapper(cls):
|
def get_code_mapper(cls):
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
from rest_framework.filters import SearchFilter as SearchFilterBase
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
@@ -35,6 +36,14 @@ __all__ = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class SearchFilter(SearchFilterBase):
|
||||||
|
def get_search_terms(self, request):
|
||||||
|
params = request.query_params.get(self.search_param, '') or request.query_params.get('search', '')
|
||||||
|
params = params.replace('\x00', '') # strip null characters
|
||||||
|
params = params.replace(',', ' ')
|
||||||
|
return params.split()
|
||||||
|
|
||||||
|
|
||||||
class BaseFilterSet(drf_filters.FilterSet):
|
class BaseFilterSet(drf_filters.FilterSet):
|
||||||
days = drf_filters.NumberFilter(method="filter_days")
|
days = drf_filters.NumberFilter(method="filter_days")
|
||||||
days__lt = drf_filters.NumberFilter(method="filter_days")
|
days__lt = drf_filters.NumberFilter(method="filter_days")
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import re
|
import re
|
||||||
|
import uuid
|
||||||
|
import time
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.test import Client
|
from django.test import Client
|
||||||
from django.urls import URLPattern, URLResolver
|
from django.urls import URLPattern, URLResolver
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.contrib.auth.models import AnonymousUser
|
||||||
|
|
||||||
from jumpserver.urls import api_v1
|
from jumpserver.urls import api_v1
|
||||||
|
|
||||||
@@ -85,50 +89,262 @@ known_error_urls = [
|
|||||||
'/api/v1/terminal/sessions/00000000-0000-0000-0000-000000000000/replay/download/',
|
'/api/v1/terminal/sessions/00000000-0000-0000-0000-000000000000/replay/download/',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# API 白名单 - 普通用户可以访问的 API
|
||||||
|
user_accessible_urls = known_unauth_urls + [
|
||||||
|
# 添加更多普通用户可以访问的 API
|
||||||
|
"/api/v1/settings/public/",
|
||||||
|
"/api/v1/users/profile/",
|
||||||
|
"/api/v1/users/change-password/",
|
||||||
|
"/api/v1/users/logout/",
|
||||||
|
"/api/v1/settings/chatai-prompts/",
|
||||||
|
"/api/v1/authentication/confirm/",
|
||||||
|
"/api/v1/users/connection-token/",
|
||||||
|
"/api/v1/authentication/temp-tokens/",
|
||||||
|
"/api/v1/notifications/backends/",
|
||||||
|
"/api/v1/authentication/passkeys/",
|
||||||
|
"/api/v1/orgs/orgs/current/",
|
||||||
|
"/api/v1/tickets/apply-asset-tickets/",
|
||||||
|
"/api/v1/ops/celery/task/00000000-0000-0000-0000-000000000000/task-execution/00000000-0000-0000-0000-000000000000/log/",
|
||||||
|
"/api/v1/assets/favorite-assets/",
|
||||||
|
"/api/v1/authentication/connection-token/",
|
||||||
|
"/api/v1/ops/jobs/",
|
||||||
|
"/api/v1/assets/categories/",
|
||||||
|
"/api/v1/tickets/tickets/",
|
||||||
|
"/api/v1/authentication/ssh-key/",
|
||||||
|
"/api/v1/terminal/my-sessions/",
|
||||||
|
"/api/v1/authentication/access-keys/",
|
||||||
|
"/api/v1/users/profile/permissions/",
|
||||||
|
"/api/v1/tickets/apply-login-asset-tickets/",
|
||||||
|
"/api/v1/resources/",
|
||||||
|
"/api/v1/ops/celery/task/00000000-0000-0000-0000-000000000000/task-execution/00000000-0000-0000-0000-000000000000/result/",
|
||||||
|
"/api/v1/notifications/site-messages/",
|
||||||
|
"/api/v1/notifications/site-messages/unread-total/",
|
||||||
|
"/api/v1/assets/assets/suggestions/",
|
||||||
|
"/api/v1/search/",
|
||||||
|
"/api/v1/notifications/user-msg-subscription/",
|
||||||
|
"/api/v1/ops/ansible/job-execution/00000000-0000-0000-0000-000000000000/log/",
|
||||||
|
"/api/v1/tickets/apply-login-tickets/",
|
||||||
|
"/api/v1/ops/variables/form-data/",
|
||||||
|
"/api/v1/ops/variables/help/",
|
||||||
|
"/api/v1/users/profile/password/",
|
||||||
|
"/api/v1/tickets/apply-command-tickets/",
|
||||||
|
"/api/v1/ops/job-executions/",
|
||||||
|
"/api/v1/audits/my-login-logs/",
|
||||||
|
"/api/v1/terminal/components/connect-methods/"
|
||||||
|
"/api/v1/ops/task-executions/",
|
||||||
|
"/api/v1/terminal/sessions/online-info/",
|
||||||
|
"/api/v1/ops/adhocs/",
|
||||||
|
"/api/v1/tickets/apply-nodes/suggestions/",
|
||||||
|
"/api/v1/tickets/apply-assets/suggestions/",
|
||||||
|
"/api/v1/settings/server-info/",
|
||||||
|
"/api/v1/ops/playbooks/",
|
||||||
|
"/api/v1/assets/categories/types/",
|
||||||
|
"/api/v1/assets/protocols/",
|
||||||
|
"/api/v1/common/countries/",
|
||||||
|
"/api/v1/audits/jobs/",
|
||||||
|
"/api/v1/terminal/components/connect-methods/",
|
||||||
|
"/api/v1/ops/task-executions/",
|
||||||
|
]
|
||||||
|
|
||||||
errors = {}
|
errors = {}
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Check api if unauthorized'
|
"""
|
||||||
|
Check API authorization and user access permissions.
|
||||||
|
|
||||||
|
This command performs two types of checks:
|
||||||
|
1. Anonymous access check - finds APIs that can be accessed without authentication
|
||||||
|
2. User access check - finds APIs that can be accessed by a normal user
|
||||||
|
|
||||||
|
The functionality is split into two methods:
|
||||||
|
- check_anonymous_access(): Checks for APIs accessible without authentication
|
||||||
|
- check_user_access(): Checks for APIs accessible by a normal user
|
||||||
|
|
||||||
|
Usage examples:
|
||||||
|
# Check both anonymous and user access (default behavior)
|
||||||
|
python manage.py check_api
|
||||||
|
|
||||||
|
# Check only anonymous access
|
||||||
|
python manage.py check_api --skip-user-check
|
||||||
|
|
||||||
|
# Check only user access
|
||||||
|
python manage.py check_api --skip-anonymous-check
|
||||||
|
|
||||||
|
# Check user access and update whitelist
|
||||||
|
python manage.py check_api --update-whitelist
|
||||||
|
"""
|
||||||
|
help = 'Check API authorization and user access permissions'
|
||||||
|
password = uuid.uuid4().hex
|
||||||
|
unauth_urls = []
|
||||||
|
error_urls = []
|
||||||
|
unformat_urls = []
|
||||||
|
# 用户可以访问的 API,但不在白名单中的 API
|
||||||
|
unexpected_access = []
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def add_arguments(self, parser):
|
||||||
settings.LOG_LEVEL = 'ERROR'
|
parser.add_argument(
|
||||||
urls = get_api_urls()
|
'--skip-anonymous-check',
|
||||||
|
action='store_true',
|
||||||
|
help='Skip anonymous access check (only check user access)',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--skip-user-check',
|
||||||
|
action='store_true',
|
||||||
|
help='Skip user access check (only check anonymous access)',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--update-whitelist',
|
||||||
|
action='store_true',
|
||||||
|
help='Update the user accessible URLs whitelist based on current scan results',
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_test_user(self):
|
||||||
|
"""创建测试用户"""
|
||||||
|
User = get_user_model()
|
||||||
|
username = 'test_user_api_check'
|
||||||
|
email = 'test@example.com'
|
||||||
|
|
||||||
|
# 删除可能存在的测试用户
|
||||||
|
User.objects.filter(username=username).delete()
|
||||||
|
|
||||||
|
# 创建新的测试用户
|
||||||
|
user = User.objects.create_user(
|
||||||
|
username=username,
|
||||||
|
email=email,
|
||||||
|
password=self.password,
|
||||||
|
is_active=True
|
||||||
|
)
|
||||||
|
return user
|
||||||
|
|
||||||
|
def check_user_api_access(self, urls):
|
||||||
|
"""检查普通用户可以访问的 API"""
|
||||||
|
user = self.create_test_user()
|
||||||
client = Client()
|
client = Client()
|
||||||
client.defaults['HTTP_HOST'] = 'localhost'
|
client.defaults['HTTP_HOST'] = 'localhost'
|
||||||
unauth_urls = []
|
|
||||||
|
# 登录用户
|
||||||
|
login_success = client.login(username=user.username, password=self.password)
|
||||||
|
if not login_success:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.ERROR('Failed to login test user')
|
||||||
|
)
|
||||||
|
return [], []
|
||||||
|
|
||||||
|
accessible_urls = []
|
||||||
error_urls = []
|
error_urls = []
|
||||||
unformat_urls = []
|
|
||||||
|
self.stdout.write('Checking user API access...')
|
||||||
|
|
||||||
|
for url, ourl in urls:
|
||||||
|
if '(' in url or '<' in url:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = client.get(url, follow=True)
|
||||||
|
time.sleep(0.1)
|
||||||
|
# 如果状态码是 200 或 201,说明用户可以访问
|
||||||
|
if response.status_code in [200, 201]:
|
||||||
|
accessible_urls.append((url, ourl, response.status_code))
|
||||||
|
elif response.status_code == 403:
|
||||||
|
# 403 表示权限不足,这是正常的
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# 其他状态码可能是错误
|
||||||
|
error_urls.append((url, ourl, response.status_code))
|
||||||
|
except Exception as e:
|
||||||
|
error_urls.append((url, ourl, str(e)))
|
||||||
|
|
||||||
|
# 清理测试用户
|
||||||
|
user.delete()
|
||||||
|
|
||||||
|
return accessible_urls, error_urls
|
||||||
|
|
||||||
|
def check_anonymous_access(self, urls):
|
||||||
|
"""检查匿名访问权限"""
|
||||||
|
client = Client()
|
||||||
|
client.defaults['HTTP_HOST'] = 'localhost'
|
||||||
|
|
||||||
for url, ourl in urls:
|
for url, ourl in urls:
|
||||||
if '(' in url or '<' in url:
|
if '(' in url or '<' in url:
|
||||||
unformat_urls.append([url, ourl])
|
self.unformat_urls.append([url, ourl])
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = client.get(url, follow=True)
|
response = client.get(url, follow=True)
|
||||||
if response.status_code != 401:
|
if response.status_code != 401:
|
||||||
errors[url] = str(response.status_code) + ' ' + str(ourl)
|
errors[url] = str(response.status_code) + ' ' + str(ourl)
|
||||||
unauth_urls.append(url)
|
self.unauth_urls.append(url)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
errors[url] = str(e)
|
errors[url] = str(e)
|
||||||
error_urls.append(url)
|
self.error_urls.append(url)
|
||||||
|
|
||||||
unauth_urls = set(unauth_urls) - set(known_unauth_urls)
|
self.unauth_urls = set(self.unauth_urls) - set(known_unauth_urls)
|
||||||
print("\nUnauthorized urls:")
|
self.error_urls = set(self.error_urls)
|
||||||
if not unauth_urls:
|
self.unformat_urls = set(self.unformat_urls)
|
||||||
|
|
||||||
|
def print_anonymous_access_result(self):
|
||||||
|
print("\n=== Anonymous Access Check ===")
|
||||||
|
print("Unauthorized urls:")
|
||||||
|
if not self.unauth_urls:
|
||||||
print(" Empty, very good!")
|
print(" Empty, very good!")
|
||||||
for url in unauth_urls:
|
for url in self.unauth_urls:
|
||||||
print('"{}", {}'.format(url, errors.get(url, '')))
|
print('"{}", {}'.format(url, errors.get(url, '')))
|
||||||
|
|
||||||
print("\nError urls:")
|
print("\nError urls:")
|
||||||
if not error_urls:
|
if not self.error_urls:
|
||||||
print(" Empty, very good!")
|
print(" Empty, very good!")
|
||||||
for url in set(error_urls):
|
for url in set(self.error_urls):
|
||||||
print(url, ': ' + errors.get(url))
|
print(url, ': ' + errors.get(url))
|
||||||
|
|
||||||
print("\nUnformat urls:")
|
print("\nUnformat urls:")
|
||||||
if not unformat_urls:
|
if not self.unformat_urls:
|
||||||
print(" Empty, very good!")
|
print(" Empty, very good!")
|
||||||
for url in unformat_urls:
|
for url in self.unformat_urls:
|
||||||
print(url)
|
print(url)
|
||||||
|
|
||||||
|
def check_user_access(self, urls, update_whitelist=False):
|
||||||
|
"""检查用户访问权限"""
|
||||||
|
print("\n=== User Access Check ===")
|
||||||
|
accessible_urls, user_error_urls = self.check_user_api_access(urls)
|
||||||
|
|
||||||
|
# 检查是否有不在白名单中的可访问 API
|
||||||
|
accessible_url_list = [url for url, _, _ in accessible_urls]
|
||||||
|
unexpected_access = set(accessible_url_list) - set(user_accessible_urls)
|
||||||
|
self.unexpected_access = unexpected_access
|
||||||
|
|
||||||
|
# 如果启用了更新白名单选项
|
||||||
|
if update_whitelist:
|
||||||
|
print("\n=== Updating Whitelist ===")
|
||||||
|
new_whitelist = sorted(set(user_accessible_urls + accessible_url_list))
|
||||||
|
print("Updated whitelist would include:")
|
||||||
|
for url in new_whitelist:
|
||||||
|
print(f' "{url}",')
|
||||||
|
print(f"\nTotal URLs in whitelist: {len(new_whitelist)}")
|
||||||
|
|
||||||
|
def print_user_access_result(self):
|
||||||
|
print("\n=== User Access Check ===")
|
||||||
|
|
||||||
|
print("User unexpected urls:")
|
||||||
|
if self.unexpected_access:
|
||||||
|
print(f" Error: Found {len(self.unexpected_access)} URLs accessible by user but not in whitelist:")
|
||||||
|
for url in self.unexpected_access:
|
||||||
|
print(f' "{url}"')
|
||||||
|
else:
|
||||||
|
print(" Empty, very good!")
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
settings.LOG_LEVEL = 'ERROR'
|
||||||
|
urls = get_api_urls()
|
||||||
|
|
||||||
|
# 检查匿名访问权限(默认执行)
|
||||||
|
if not options['skip_anonymous_check']:
|
||||||
|
self.check_anonymous_access(urls)
|
||||||
|
|
||||||
|
# 检查用户访问权限(默认执行)
|
||||||
|
if not options['skip_user_check']:
|
||||||
|
self.check_user_access(urls, options['update_whitelist'])
|
||||||
|
|
||||||
|
print("\nCheck total urls: ", len(urls))
|
||||||
|
self.print_anonymous_access_result()
|
||||||
|
self.print_user_access_result()
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ class FeiShu(RequestMixin):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f'Get user detail error: {e} data={data}')
|
logger.error(f'Get user detail error: {e} data={data}')
|
||||||
|
|
||||||
|
data.update(kwargs['other_info'] if 'other_info' in kwargs else {})
|
||||||
info = flatten_dict(data)
|
info = flatten_dict(data)
|
||||||
default_detail = self.default_user_detail(data, user_id)
|
default_detail = self.default_user_detail(data, user_id)
|
||||||
detail = map_attributes(default_detail, info, self.attributes)
|
detail = map_attributes(default_detail, info, self.attributes)
|
||||||
|
|||||||
@@ -207,7 +207,8 @@ class WeComTool(object):
|
|||||||
|
|
||||||
def check_state(self, state, request=None):
|
def check_state(self, state, request=None):
|
||||||
return cache.get(state) == self.WECOM_STATE_VALUE or \
|
return cache.get(state) == self.WECOM_STATE_VALUE or \
|
||||||
request.session[self.WECOM_STATE_SESSION_KEY] == state
|
request.session.get(self.WECOM_STATE_SESSION_KEY) == state or \
|
||||||
|
request.GET.get('state') == state # 在企业微信桌面端打开的话,重新创建了个 session,会导致 session 校验失败
|
||||||
|
|
||||||
def wrap_redirect_url(self, next_url):
|
def wrap_redirect_url(self, next_url):
|
||||||
params = {
|
params = {
|
||||||
|
|||||||
@@ -97,10 +97,7 @@ def send_mail_attachment_async(subject, message, recipient_list, attachment_list
|
|||||||
for attachment in attachment_list:
|
for attachment in attachment_list:
|
||||||
email.attach_file(attachment)
|
email.attach_file(attachment)
|
||||||
os.remove(attachment)
|
os.remove(attachment)
|
||||||
try:
|
return email.send()
|
||||||
return email.send()
|
|
||||||
except Exception as e:
|
|
||||||
logger.error("Sending mail attachment error: {}".format(e))
|
|
||||||
|
|
||||||
|
|
||||||
@shared_task(
|
@shared_task(
|
||||||
|
|||||||
@@ -1,16 +1,137 @@
|
|||||||
import json
|
import json
|
||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import redis
|
import redis
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from redis.client import PubSub
|
|
||||||
|
|
||||||
from common.db.utils import safe_db_connection
|
from common.db.utils import safe_db_connection
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
import threading
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
|
_PUBSUB_HUBS = {}
|
||||||
|
|
||||||
|
|
||||||
|
def _get_pubsub_hub(db=10):
|
||||||
|
hub = _PUBSUB_HUBS.get(db)
|
||||||
|
if not hub:
|
||||||
|
hub = PubSubHub(db=db)
|
||||||
|
_PUBSUB_HUBS[db] = hub
|
||||||
|
return hub
|
||||||
|
|
||||||
|
|
||||||
|
class PubSubHub:
|
||||||
|
|
||||||
|
def __init__(self, db=10):
|
||||||
|
self.db = db
|
||||||
|
self.redis = get_redis_client(db)
|
||||||
|
self.pubsub = self.redis.pubsub()
|
||||||
|
self.handlers = {}
|
||||||
|
self.lock = threading.RLock()
|
||||||
|
self.listener = None
|
||||||
|
self.running = False
|
||||||
|
self.executor = ThreadPoolExecutor(max_workers=8, thread_name_prefix='pubsub_handler')
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.executor.shutdown(wait=True)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
with self.lock:
|
||||||
|
if self.listener and self.listener.is_alive():
|
||||||
|
return
|
||||||
|
self.running = True
|
||||||
|
self.listener = threading.Thread(name='pubsub_listen', target=self._listen_loop, daemon=True)
|
||||||
|
self.listener.start()
|
||||||
|
|
||||||
|
def _listen_loop(self):
|
||||||
|
backoff = 1
|
||||||
|
while self.running:
|
||||||
|
try:
|
||||||
|
for msg in self.pubsub.listen():
|
||||||
|
if msg.get("type") != "message":
|
||||||
|
continue
|
||||||
|
ch = msg.get("channel")
|
||||||
|
if isinstance(ch, bytes):
|
||||||
|
ch = ch.decode()
|
||||||
|
data = msg.get("data")
|
||||||
|
try:
|
||||||
|
if isinstance(data, bytes):
|
||||||
|
item = json.loads(data.decode())
|
||||||
|
elif isinstance(data, str):
|
||||||
|
item = json.loads(data)
|
||||||
|
else:
|
||||||
|
item = data
|
||||||
|
except Exception:
|
||||||
|
item = data
|
||||||
|
# 使用线程池处理消息
|
||||||
|
future = self.executor.submit(self._dispatch, ch, msg, item)
|
||||||
|
future.add_done_callback(
|
||||||
|
lambda f: f.exception() and logger.error(f"handle pubsub msg {msg} failed: {f.exception()}"))
|
||||||
|
backoff = 1
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'PubSub listen error: {e}')
|
||||||
|
time.sleep(backoff)
|
||||||
|
backoff = min(backoff * 2, 30)
|
||||||
|
try:
|
||||||
|
self._reconnect()
|
||||||
|
except Exception as re:
|
||||||
|
logger.error(f'PubSub reconnect error: {re}')
|
||||||
|
|
||||||
|
def _dispatch(self, ch, raw_msg, item):
|
||||||
|
with self.lock:
|
||||||
|
handler = self.handlers.get(ch)
|
||||||
|
if not handler:
|
||||||
|
return
|
||||||
|
_next, error, _complete = handler
|
||||||
|
try:
|
||||||
|
with safe_db_connection():
|
||||||
|
_next(item)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'Subscribe handler handle msg error: {e}')
|
||||||
|
try:
|
||||||
|
if error:
|
||||||
|
error(raw_msg, item)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def add_subscription(self, pb, _next, error, complete):
|
||||||
|
ch = pb.ch
|
||||||
|
with self.lock:
|
||||||
|
existed = bool(self.handlers.get(ch))
|
||||||
|
self.handlers[ch] = (_next, error, complete)
|
||||||
|
try:
|
||||||
|
if not existed:
|
||||||
|
self.pubsub.subscribe(ch)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'Subscribe channel {ch} error: {e}')
|
||||||
|
self.start()
|
||||||
|
return Subscription(pb=pb, hub=self, ch=ch, handler=(_next, error, complete))
|
||||||
|
|
||||||
|
def remove_subscription(self, sub):
|
||||||
|
ch = sub.ch
|
||||||
|
with self.lock:
|
||||||
|
existed = self.handlers.pop(ch, None)
|
||||||
|
if existed:
|
||||||
|
try:
|
||||||
|
self.pubsub.unsubscribe(ch)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f'Unsubscribe {ch} error: {e}')
|
||||||
|
|
||||||
|
def _reconnect(self):
|
||||||
|
with self.lock:
|
||||||
|
channels = [ch for ch, h in self.handlers.items() if h]
|
||||||
|
try:
|
||||||
|
self.pubsub.close()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
self.redis = get_redis_client(self.db)
|
||||||
|
self.pubsub = self.redis.pubsub()
|
||||||
|
if channels:
|
||||||
|
self.pubsub.subscribe(channels)
|
||||||
|
|
||||||
|
|
||||||
def get_redis_client(db=0):
|
def get_redis_client(db=0):
|
||||||
client = cache.client.get_client()
|
client = cache.client.get_client()
|
||||||
@@ -25,15 +146,11 @@ class RedisPubSub:
|
|||||||
self.redis = get_redis_client(db)
|
self.redis = get_redis_client(db)
|
||||||
|
|
||||||
def subscribe(self, _next, error=None, complete=None):
|
def subscribe(self, _next, error=None, complete=None):
|
||||||
ps = self.redis.pubsub()
|
hub = _get_pubsub_hub(self.db)
|
||||||
ps.subscribe(self.ch)
|
return hub.add_subscription(self, _next, error, complete)
|
||||||
sub = Subscription(self, ps)
|
|
||||||
sub.keep_handle_msg(_next, error, complete)
|
|
||||||
return sub
|
|
||||||
|
|
||||||
def resubscribe(self, _next, error=None, complete=None):
|
def resubscribe(self, _next, error=None, complete=None):
|
||||||
self.redis = get_redis_client(self.db)
|
return self.subscribe(_next, error, complete)
|
||||||
self.subscribe(_next, error, complete)
|
|
||||||
|
|
||||||
def publish(self, data):
|
def publish(self, data):
|
||||||
data_json = json.dumps(data)
|
data_json = json.dumps(data)
|
||||||
@@ -42,85 +159,19 @@ class RedisPubSub:
|
|||||||
|
|
||||||
|
|
||||||
class Subscription:
|
class Subscription:
|
||||||
def __init__(self, pb: RedisPubSub, sub: PubSub):
|
def __init__(self, pb: RedisPubSub, hub: PubSubHub, ch: str, handler):
|
||||||
self.pb = pb
|
self.pb = pb
|
||||||
self.ch = pb.ch
|
self.ch = ch
|
||||||
self.sub = sub
|
self.hub = hub
|
||||||
|
self.handler = handler
|
||||||
self.unsubscribed = False
|
self.unsubscribed = False
|
||||||
|
|
||||||
def _handle_msg(self, _next, error, complete):
|
|
||||||
"""
|
|
||||||
handle arg is the pub published
|
|
||||||
:param _next: next msg handler
|
|
||||||
:param error: error msg handler
|
|
||||||
:param complete: complete msg handler
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
msgs = self.sub.listen()
|
|
||||||
|
|
||||||
if error is None:
|
|
||||||
error = lambda m, i: None
|
|
||||||
|
|
||||||
if complete is None:
|
|
||||||
complete = lambda: None
|
|
||||||
|
|
||||||
try:
|
|
||||||
for msg in msgs:
|
|
||||||
if msg["type"] != "message":
|
|
||||||
continue
|
|
||||||
item = None
|
|
||||||
try:
|
|
||||||
item_json = msg['data'].decode()
|
|
||||||
item = json.loads(item_json)
|
|
||||||
|
|
||||||
with safe_db_connection():
|
|
||||||
_next(item)
|
|
||||||
except Exception as e:
|
|
||||||
error(msg, item)
|
|
||||||
logger.error('Subscribe handler handle msg error: {}'.format(e))
|
|
||||||
except Exception as e:
|
|
||||||
if self.unsubscribed:
|
|
||||||
logger.debug('Subscription unsubscribed')
|
|
||||||
else:
|
|
||||||
logger.error('Consume msg error: {}'.format(e))
|
|
||||||
self.retry(_next, error, complete)
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
complete()
|
|
||||||
except Exception as e:
|
|
||||||
logger.error('Complete subscribe error: {}'.format(e))
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.unsubscribe()
|
|
||||||
except Exception as e:
|
|
||||||
logger.error("Redis observer close error: {}".format(e))
|
|
||||||
|
|
||||||
def keep_handle_msg(self, _next, error, complete):
|
|
||||||
t = threading.Thread(target=self._handle_msg, args=(_next, error, complete))
|
|
||||||
t.daemon = True
|
|
||||||
t.start()
|
|
||||||
return t
|
|
||||||
|
|
||||||
def unsubscribe(self):
|
def unsubscribe(self):
|
||||||
|
if self.unsubscribed:
|
||||||
|
return
|
||||||
self.unsubscribed = True
|
self.unsubscribed = True
|
||||||
logger.info(f"Unsubscribed from channel: {self.sub}")
|
logger.info(f"Unsubscribed from channel: {self.ch}")
|
||||||
try:
|
try:
|
||||||
self.sub.close()
|
self.hub.remove_subscription(self)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f'Unsubscribe msg error: {e}')
|
logger.warning(f'Unsubscribe msg error: {e}')
|
||||||
|
|
||||||
def retry(self, _next, error, complete):
|
|
||||||
logger.info('Retry subscribe channel: {}'.format(self.ch))
|
|
||||||
times = 0
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
self.unsubscribe()
|
|
||||||
self.pb.resubscribe(_next, error, complete)
|
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
logger.error('Retry #{} {} subscribe channel error: {}'.format(times, self.ch, e))
|
|
||||||
times += 1
|
|
||||||
time.sleep(times * 2)
|
|
||||||
|
|||||||
47
apps/common/views/template.py
Normal file
47
apps/common/views/template.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.template import Context
|
||||||
|
from django.template import Engine, TemplateSyntaxError
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
from django.utils._os import safe_join
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def safe_render_to_string(template_name, context=None, request=None, using=None):
|
||||||
|
with open(template_name, encoding="utf-8") as f:
|
||||||
|
template_code = f.read()
|
||||||
|
safe_engine = Engine(
|
||||||
|
debug=False,
|
||||||
|
libraries={}, # 禁用自定义 tag 库
|
||||||
|
builtins=[], # 不自动加载内置标签
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
template = safe_engine.from_string(template_code)
|
||||||
|
except TemplateSyntaxError as e:
|
||||||
|
logger.error(e)
|
||||||
|
return template_code
|
||||||
|
return template.render(Context(context or {}))
|
||||||
|
|
||||||
|
|
||||||
|
def _get_data_template_path(template_name: str):
|
||||||
|
# 保存到 data/template/<原路径>.html
|
||||||
|
# 例如 template_name users/_msg_x.html -> data/template/users/_msg_x.html
|
||||||
|
rel_path = template_name.replace('/', os.sep)
|
||||||
|
return safe_join(settings.DATA_DIR, 'template', rel_path)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_edit_template_path(template_name: str):
|
||||||
|
return _get_data_template_path(template_name) + '.edit'
|
||||||
|
|
||||||
|
|
||||||
|
def custom_render_to_string(template_name, context=None, request=None, using=None):
|
||||||
|
# 如果自定的义模板存在,则使用自定义模板,否则使用系统模板
|
||||||
|
custom_template = _get_data_template_path(template_name)
|
||||||
|
if os.path.exists(custom_template):
|
||||||
|
template = safe_render_to_string(custom_template, context=context, request=request, using=using)
|
||||||
|
else:
|
||||||
|
template = render_to_string(template_name, context=context, request=request, using=using)
|
||||||
|
return template
|
||||||
@@ -16,6 +16,7 @@ class BaseTranslateManager:
|
|||||||
'es': 'Spanish',
|
'es': 'Spanish',
|
||||||
'ru': 'Russian',
|
'ru': 'Russian',
|
||||||
'ko': 'Korean',
|
'ko': 'Korean',
|
||||||
|
'vi': 'Vietnamese',
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, dir_path, oai_trans_instance):
|
def __init__(self, dir_path, oai_trans_instance):
|
||||||
|
|||||||
85
apps/i18n/chen/vi.json
Normal file
85
apps/i18n/chen/vi.json
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
"ACLRejectError": "Lệnh này không được phép thực hiện",
|
||||||
|
"AffectedRows": "Trình duyệt cơ sở dữ liệu",
|
||||||
|
"AlreadyFirstPageError": "Đã là trang đầu tiên",
|
||||||
|
"AlreadyLastPageError": "Đã đến trang cuối cùng",
|
||||||
|
"Cancel": "Hủy bỏ",
|
||||||
|
"ChangeContextError": "Chuyển đổi ngữ cảnh thất bại",
|
||||||
|
"CommandReview": "Xác nhận lệnh",
|
||||||
|
"CommandReviewMessage": "Lệnh bạn nhập cần được xác nhận trước khi thực thi, có muốn gửi yêu cầu xác nhận không?",
|
||||||
|
"CommandReviewRejectBy": "Lệnh xác nhận bị %s từ chối",
|
||||||
|
"CommandReviewTimeoutError": "Thời gian xác nhận lệnh đã hết",
|
||||||
|
"CommandWarningDialogMessage": "Lệnh bạn thực hiện có nguy cơ, thông báo cảnh báo sẽ được gửi đến quản lý. Bạn có muốn tiếp tục không?< -SEP->Chạy (Ctrl + Enter)",
|
||||||
|
"Confirm": "Xác nhận",
|
||||||
|
"ConnectError": "Kết nối thất bại",
|
||||||
|
"ConnectSuccess": "Kết nối thành công",
|
||||||
|
"Connected": "Đã kết nối",
|
||||||
|
"Copy": "Sao chép",
|
||||||
|
"CopyFailed": "Sao chép thất bại",
|
||||||
|
"CopyNotAllowed": "Không được phép sao chép, hãy liên hệ với quản trị viên để mở quyền!",
|
||||||
|
"CopySucceeded": "Sao chép thành công",
|
||||||
|
"Current": "Hiện tại",
|
||||||
|
"DatabaseExplorer": "Người dùng",
|
||||||
|
"DatabaseProperties": "Thuộc tính nguồn dữ liệu",
|
||||||
|
"DownloadNotAllowed": "Không cho phép tải về, vui lòng liên hệ với quản lý để mở quyền!",
|
||||||
|
"DriverClass": "Điều khiển",
|
||||||
|
"DriverVersion": "Phiên bản lái",
|
||||||
|
"ErrorMessage": "Thông báo lỗi",
|
||||||
|
"ExecuteError": "Thực hiện thành công",
|
||||||
|
"ExecuteSuccess": "Thực hiện thành công",
|
||||||
|
"ExecutionCanceled": "Thực hiện đã bị hủy",
|
||||||
|
"ExportALL": "Xuất tất cả dữ liệu",
|
||||||
|
"ExportAll": "Xuất toàn bộ",
|
||||||
|
"ExportCurrent": "Xuất trang hiện tại",
|
||||||
|
"ExportData": "Xuất dữ liệu",
|
||||||
|
"FetchError": "Lấy dữ liệu thất bại",
|
||||||
|
"Format": "Định dạng",
|
||||||
|
"FormatHotKey": "Định dạng (Ctrl + L)",
|
||||||
|
"InitializeDatasource": "Khởi tạo nguồn dữ liệu",
|
||||||
|
"InitializeDatasourceFailed": "Khởi tạo nguồn dữ liệu thất bại",
|
||||||
|
"InitializingDatasourceMessage": "Đang khởi tạo nguồn dữ liệu, xin vui lòng chờ...",
|
||||||
|
"InsertStatement": "Câu lệnh chèn",
|
||||||
|
"JDBCURL": "JDBC URL",
|
||||||
|
"LogOutput": "Xuất nhật ký",
|
||||||
|
"Name": "Tên",
|
||||||
|
"NewQuery": "Tạo mới truy vấn",
|
||||||
|
"NoPermissionError": "Không có quyền thực hiện thao tác này",
|
||||||
|
"NumRow": "{num} dòng",
|
||||||
|
"Open": "Mở",
|
||||||
|
"OverMaxIdleTimeError": "Do phiên này quá thời gian rỗi vượt quá %d phút, đã bị đóng",
|
||||||
|
"OverMaxSessionTimeError": "Do vì cuộc trò chuyện này kéo dài hơn %d giờ, nó đã bị đóng. \nThuộc tính \nKết nối thành công \nPhiên đã kết thúc \nSao chép thất bại \nLàm mới \nSao chép thành công \nKết nối thất bại \nQuyền đã hết hạn, phiên sẽ hết hạn sau mười phút, vui lòng liên hệ với quản lý để gia hạn kịp thời \nKhông được phép dán, vui lòng liên hệ với quản lý để mở quyền! \nKhông có quyền thực hiện thao tác này \nJDBC URL \nChuyển đổi ngữ cảnh thất bại \nQuyền đã hết hạn \nChọn SQL",
|
||||||
|
"ParseError": "Phân tích thất bại",
|
||||||
|
"PasteNotAllowed": "Không cho phép dán, vui lòng liên hệ với quản trị viên để mở quyền!",
|
||||||
|
"PermissionAlreadyExpired": "Quyền đã hết hạn",
|
||||||
|
"PermissionExpiredDialogMessage": "- Quyền hạn đã hết hạn, phiên làm việc sẽ hết hạn sau mười phút, xin vui lòng liên hệ với quản lý để gia hạn.\n- Phiên làm việc đã kết thúc.\n- Không cho phép dán, xin vui lòng liên hệ với quản lý để mở quyền!\n- Thuộc tính.\n- Chuyển đổi ngữ cảnh thất bại.\n- Sao chép không thành công.\n- Kết nối thất bại.\n- Làm mới.\n- Chọn SQL.\n- Thực hiện thành công.\n- Kết nối thành công.\n- Sao chép thành công.\n- Quyền hạn đã hết hạn.\n- JDBC URL.\n- Không có quyền thực hiện thao tác này.",
|
||||||
|
"PermissionExpiredDialogTitle": "Số dòng bị ảnh hưởng",
|
||||||
|
"PermissionsExpiredOn": "Quyền liên kết với phiên này đã hết hạn vào %s",
|
||||||
|
"Properties": "Thuộc tính",
|
||||||
|
"Refresh": "Làm mới",
|
||||||
|
"Run": "Chạy",
|
||||||
|
"RunHotKey": "Quyền đã hết hạn",
|
||||||
|
"RunSelected": "Chạy đã chọn",
|
||||||
|
"Save": "Lưu",
|
||||||
|
"SaveSQL": "Lưu SQL",
|
||||||
|
"SaveSucceed": "Lưu thành công",
|
||||||
|
"Scope": "Phạm vi",
|
||||||
|
"SelectSQL": "Chọn SQL",
|
||||||
|
"SessionClosedBy": "Phiên đã bị %s đóng",
|
||||||
|
"SessionFinished": "Phiên làm việc đã kết thúc",
|
||||||
|
"SessionLockedError": "Phiên hiện tại đã bị khóa, không thể tiếp tục thực hiện lệnh",
|
||||||
|
"SessionLockedMessage": "Phiên này đã bị %s khóa, không thể tiếp tục thực hiện lệnh",
|
||||||
|
"SessionUnlockedMessage": "Phiên này đã được %s mở khóa, có thể tiếp tục thực hiện lệnh",
|
||||||
|
"ShowProperties": "Thuộc tính",
|
||||||
|
"StopHotKey": "Dừng (Ctrl + D)",
|
||||||
|
"Submit": "Gửi",
|
||||||
|
"Total": "Tổng cộng",
|
||||||
|
"Type": "Loại",
|
||||||
|
"UpdateStatement": "Câu lệnh cập nhật",
|
||||||
|
"User": "Thực hiện thất bại",
|
||||||
|
"UserCancelCommandReviewError": "Người dùng hủy lệnh duyệt lại",
|
||||||
|
"Version": "Phiên bản",
|
||||||
|
"ViewData": "Xem dữ liệu",
|
||||||
|
"WaitCommandReviewMessage": "Yêu cầu xem xét đã được gửi đi, xin vui lòng chờ kết quả xem xét.",
|
||||||
|
"Warning": "Cảnh báo",
|
||||||
|
"initializingDatasourceFailedMessage": "Kết nối thất bại, vui lòng kiểm tra cấu hình kết nối cơ sở dữ liệu có chính xác hay không."
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
12044
apps/i18n/core/vi/LC_MESSAGES/django.po
Normal file
12044
apps/i18n/core/vi/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
100
apps/i18n/core/vi/LC_MESSAGES/djangojs.po
Normal file
100
apps/i18n/core/vi/LC_MESSAGES/djangojs.po
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2025-02-24 14:25+0800\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"Language: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:267
|
||||||
|
msgid "Update is successful!"
|
||||||
|
msgstr "Cập nhật thành công"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:269
|
||||||
|
msgid "An unknown error occurred while updating.."
|
||||||
|
msgstr "Đã xảy ra lỗi không xác định khi cập nhật"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:342
|
||||||
|
msgid "Not found"
|
||||||
|
msgstr "Không tìm thấy"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:344
|
||||||
|
msgid "Server error"
|
||||||
|
msgstr "Lỗi máy chủ"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:346 static/js/jumpserver.js:384
|
||||||
|
#: static/js/jumpserver.js:386
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "Lỗi"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:352 static/js/jumpserver.js:393
|
||||||
|
msgid "Delete the success"
|
||||||
|
msgstr "Xóa thành công"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:359
|
||||||
|
msgid "Are you sure about deleting it?"
|
||||||
|
msgstr "Bạn có chắc chắn muốn xóa không?"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:363 static/js/jumpserver.js:404
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Hủy"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:365 static/js/jumpserver.js:406
|
||||||
|
msgid "Confirm"
|
||||||
|
msgstr "Xác nhận"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:384
|
||||||
|
msgid ""
|
||||||
|
"The organization contains undeleted information. Please try again after deleting"
|
||||||
|
msgstr "Tổ chức còn chứa thông tin chưa được xóa, vui lòng xóa rồi thử lại"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:386
|
||||||
|
msgid ""
|
||||||
|
"Do not perform this operation under this organization. Try again after switching to another organization"
|
||||||
|
msgstr "Đừng thực hiện thao tác này trong tổ chức hiện tại, hãy chuyển sang tổ chức khác rồi thử lại"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:400
|
||||||
|
msgid ""
|
||||||
|
"Please ensure that the following information in the organization has been deleted"
|
||||||
|
msgstr "Vui lòng đảm bảo rằng các thông tin sau trong tổ chức đã được xóa"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:401
|
||||||
|
msgid ""
|
||||||
|
"User list、User group、Asset list、Domain list、Admin user、System user、Labels、Asset permission"
|
||||||
|
msgstr "Danh sách người dùng, Nhóm người dùng, Danh sách tài sản, Danh sách miền, Người dùng đặc quyền, Người dùng hệ thống, Quản lý nhãn, Quy tắc cấp quyền tài sản"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:650
|
||||||
|
msgid "Unknown error occur"
|
||||||
|
msgstr "Xuất hiện lỗi không xác định"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:902
|
||||||
|
msgid "Password minimum length {N} bits"
|
||||||
|
msgstr "Mật khẩu phải có tối thiểu {N} ký tự"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:903
|
||||||
|
msgid "Must contain capital letters"
|
||||||
|
msgstr "Phải chứa chữ cái viết hoa"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:904
|
||||||
|
msgid "Must contain lowercase letters"
|
||||||
|
msgstr "Phải chứa chữ cái viết thường"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:905
|
||||||
|
msgid "Must contain numeric characters"
|
||||||
|
msgstr "Phải chứa ký tự số"
|
||||||
|
|
||||||
|
#: static/js/jumpserver.js:906
|
||||||
|
msgid "Must contain special characters"
|
||||||
|
msgstr "Phải chứa ký tự đặc biệt"
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,46 @@
|
|||||||
{
|
{
|
||||||
|
"\t%2d) Enter {{.GreenBoldColor}}%s{{.ColorEnd}} to %s.%s": "",
|
||||||
|
"%s approved": "",
|
||||||
|
"%s node has no assets": "",
|
||||||
|
"%s protocol client not installed.": "",
|
||||||
|
"%s rejected": "",
|
||||||
|
"/ + IP, Hostname, Comment": "",
|
||||||
|
"ACL reject": "",
|
||||||
|
"Account <%s> and asset <%s> protocol are inconsistent.": "",
|
||||||
"ActionPerm": "Action Permission",
|
"ActionPerm": "Action Permission",
|
||||||
|
"Address": "",
|
||||||
"AlreadyExistsPleaseRename": "File already exists, please rename it",
|
"AlreadyExistsPleaseRename": "File already exists, please rename it",
|
||||||
|
"Announcement: ": "",
|
||||||
|
"Authentication failed": "",
|
||||||
"AvailableShortcutKey": "Available Shortcut Key",
|
"AvailableShortcutKey": "Available Shortcut Key",
|
||||||
"Back": "Back",
|
"Back": "Back",
|
||||||
|
"Back: B/b": "",
|
||||||
"Cancel": "Cancel",
|
"Cancel": "Cancel",
|
||||||
|
"Cancel confirm": "",
|
||||||
|
"Cancel to login asset or max 3 retry": "",
|
||||||
"CancelFileUpload": "Cancel file upload",
|
"CancelFileUpload": "Cancel file upload",
|
||||||
"CaseSensitive": "Case sensitive",
|
"CaseSensitive": "Case sensitive",
|
||||||
"Clone Connect": "Clone Connect",
|
"Clone Connect": "Clone Connect",
|
||||||
"Close All Tabs": "Close All Tabs",
|
"Close All Tabs": "Close All Tabs",
|
||||||
"Close Current Tab": "Close Current Tab",
|
"Close Current Tab": "Close Current Tab",
|
||||||
|
"Command `%s` is forbidden": "",
|
||||||
|
"Comment": "",
|
||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"ConfirmBtn": "Confirm",
|
"ConfirmBtn": "Confirm",
|
||||||
"ConfirmDelete": "Are you sure you want to delete this file?",
|
"ConfirmDelete": "Are you sure you want to delete this file?",
|
||||||
"Connect": "Connect",
|
"Connect": "Connect",
|
||||||
|
"Connect idle more than %d minutes, disconnect": "",
|
||||||
|
"Connect with api server failed": "",
|
||||||
|
"Connecting to %s@%s": "",
|
||||||
|
"Connecting to Database %s": "",
|
||||||
|
"Connecting to Kubernetes %s": "",
|
||||||
|
"Connecting to Kubernetes %s container %s": "",
|
||||||
|
"Connection refused": "",
|
||||||
"CopyLink": "Copy Link Address and Code",
|
"CopyLink": "Copy Link Address and Code",
|
||||||
"CopyShareURLSuccess": "Copy Share URL Success",
|
"CopyShareURLSuccess": "Copy Share URL Success",
|
||||||
|
"Core API failed": "",
|
||||||
|
"Could copy website URL to notify reviewers: %s": "",
|
||||||
|
"Create k8s client err: %s": "",
|
||||||
"CreateFolder": "Create folder",
|
"CreateFolder": "Create folder",
|
||||||
"CreateLink": "Create link",
|
"CreateLink": "Create link",
|
||||||
"CreateSuccess": "Success",
|
"CreateSuccess": "Success",
|
||||||
@@ -27,10 +53,14 @@
|
|||||||
"DownloadProgress": "Download progress",
|
"DownloadProgress": "Download progress",
|
||||||
"DownloadSuccess": "Download success",
|
"DownloadSuccess": "Download success",
|
||||||
"Downloading": "Downloading",
|
"Downloading": "Downloading",
|
||||||
|
"Dynamic": "",
|
||||||
"EndFileTransfer": "File transfer end",
|
"EndFileTransfer": "File transfer end",
|
||||||
|
"Enter ID number directly login, multiple search use // + field, such as: //16": "",
|
||||||
"ExceedTransferSize": "exceed max transfer size",
|
"ExceedTransferSize": "exceed max transfer size",
|
||||||
"Expand": "Expand",
|
"Expand": "Expand",
|
||||||
"ExpiredTime": "Expiration time",
|
"ExpiredTime": "Expiration time",
|
||||||
|
"Face ACL is not supported yet. Please use the WebTerminal to connect the asset.": "",
|
||||||
|
"Face verification is not supported yet. Please use the WebTerminal to connect the asset.": "",
|
||||||
"FailedCreateConnection": "Failed to create connection",
|
"FailedCreateConnection": "Failed to create connection",
|
||||||
"FileAlreadyExists": "File already exists",
|
"FileAlreadyExists": "File already exists",
|
||||||
"FileListError": "Failed to get file list",
|
"FileListError": "Failed to get file list",
|
||||||
@@ -41,10 +71,15 @@
|
|||||||
"FileUploadInterrupted": "File upload interrupted",
|
"FileUploadInterrupted": "File upload interrupted",
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"General": "General",
|
"General": "General",
|
||||||
|
"Get auth password failed": "",
|
||||||
"GetFileManagerTokenTimeOut": "Get file manager token timeout",
|
"GetFileManagerTokenTimeOut": "Get file manager token timeout",
|
||||||
"GetShareUser": "Enter username",
|
"GetShareUser": "Enter username",
|
||||||
|
"HandleTask does not support protocol %s, please use web terminal to access": "",
|
||||||
|
"Hostname": "",
|
||||||
"Hotkeys": "Hotkeys",
|
"Hotkeys": "Hotkeys",
|
||||||
|
"ID": "",
|
||||||
"InputVerifyCode": "Input Verify Code",
|
"InputVerifyCode": "Input Verify Code",
|
||||||
|
"Invalid ID": "",
|
||||||
"JoinShare": "Join Session",
|
"JoinShare": "Join Session",
|
||||||
"JoinedWithSuccess": "Successfully joined",
|
"JoinedWithSuccess": "Successfully joined",
|
||||||
"KubernetesManagement": "Kubernetes management",
|
"KubernetesManagement": "Kubernetes management",
|
||||||
@@ -53,41 +88,71 @@
|
|||||||
"LeftArrow": "Left arrow",
|
"LeftArrow": "Left arrow",
|
||||||
"LinkAddr": "Link Address",
|
"LinkAddr": "Link Address",
|
||||||
"List": "List",
|
"List": "List",
|
||||||
|
"Manual": "",
|
||||||
"MatchWholeWords": "Match whole words",
|
"MatchWholeWords": "Match whole words",
|
||||||
"Minute": "Minute",
|
"Minute": "Minute",
|
||||||
"Minutes": "Minutes",
|
"Minutes": "Minutes",
|
||||||
|
"Must be auto login account for %s": "",
|
||||||
|
"Must be unique account for %s": "",
|
||||||
|
"Must be unique asset for %s": "",
|
||||||
"MustOneFile": "Only support to select one file",
|
"MustOneFile": "Only support to select one file",
|
||||||
"MustSelectOneFile": "Must select one file",
|
"MustSelectOneFile": "Must select one file",
|
||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
|
"Need ACL review, continue? (y/n): ": "",
|
||||||
|
"Need ticket confirm to execute command, already send email to the reviewers": "",
|
||||||
|
"Need ticket confirm to login, already send email to the reviewers": "",
|
||||||
"NewFolder": "New Folder",
|
"NewFolder": "New Folder",
|
||||||
|
"No Account found.": "No Account found.",
|
||||||
|
"No Assets": "No Assets",
|
||||||
|
"No Databases": "No Databases",
|
||||||
|
"No account found.": "No account found.",
|
||||||
|
"No found asset": "No found asset",
|
||||||
|
"No kubernetes": "No kubernetes",
|
||||||
|
"No protocol found.": "No protocol found.",
|
||||||
|
"No route to host": "No route to host",
|
||||||
"NoActiveTerminalTabFound": "No active terminal tab found",
|
"NoActiveTerminalTabFound": "No active terminal tab found",
|
||||||
"NoData": "No data",
|
"NoData": "No data",
|
||||||
"NoLink": "No Link",
|
"NoLink": "No Link",
|
||||||
"NoRunningTerminalFound": "No running terminal found",
|
"NoRunningTerminalFound": "No running terminal found",
|
||||||
|
"Node: [ ID.Name(Asset amount) ]": "Node: [ ID.Name(Asset amount) ]",
|
||||||
"OnlineUser": "Online User",
|
"OnlineUser": "Online User",
|
||||||
"OperationSuccessful": "Operation successful",
|
"OperationSuccessful": "Operation successful",
|
||||||
|
"Organization": "Organization",
|
||||||
"Owner": "Owner",
|
"Owner": "Owner",
|
||||||
|
"Page up: b\tPage down: n": "Page up: b\tPage down: n",
|
||||||
|
"Page: %d, Count: %d, Total Page: %d, Total Count: %d": "Page: %d, Count: %d, Total Page: %d, Total Count: %d",
|
||||||
"Paste": "Paste",
|
"Paste": "Paste",
|
||||||
"PauseSession": "Pause Session",
|
"PauseSession": "Pause Session",
|
||||||
|
"Permission has expired, disconnect": "Permission has expired, disconnect",
|
||||||
"PermissionDenied": "Permission denied",
|
"PermissionDenied": "Permission denied",
|
||||||
"PermissionExpired": "Permission expired",
|
"PermissionExpired": "Permission expired",
|
||||||
"PermissionValid": "Permission valid",
|
"PermissionValid": "Permission valid",
|
||||||
|
"Platform": "Platform",
|
||||||
|
"Please waiting for the reviewers to confirm command `%s`, cancel by CTRL+C or CTRL+D.": "",
|
||||||
|
"Please waiting for the reviewers to confirm, enter q to exit. ": "Please waiting for the reviewers to confirm, enter q to exit. ",
|
||||||
"PleaseInput": "Please input",
|
"PleaseInput": "Please input",
|
||||||
"PleaseInputVerifyCode": "Please input verify code",
|
"PleaseInputVerifyCode": "Please input verify code",
|
||||||
"PrimaryUser": "Primary user",
|
"PrimaryUser": "Primary user",
|
||||||
|
"Protocol": "Protocol",
|
||||||
"ReadOnly": "Read Only",
|
"ReadOnly": "Read Only",
|
||||||
"Reconnect": "Reconnect",
|
"Reconnect": "Reconnect",
|
||||||
"Refresh": "Refresh",
|
"Refresh": "Refresh",
|
||||||
|
"Refresh done": "",
|
||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
"RemoveShareUser": "You have been removed from the shared session.",
|
"RemoveShareUser": "You have been removed from the shared session.",
|
||||||
"RemoveUser": "Remove User",
|
"RemoveUser": "Remove User",
|
||||||
"Rename": "Rename",
|
"Rename": "Rename",
|
||||||
"ResumeSession": "Resume Session",
|
"ResumeSession": "Resume Session",
|
||||||
|
"Reuse SSH connections (%s@%s) [Number of connections: %d]": "",
|
||||||
"RightArrow": "Right arrow",
|
"RightArrow": "Right arrow",
|
||||||
"Search": "Search",
|
"Search": "Search",
|
||||||
|
"Search: %s": "",
|
||||||
|
"Select account exceed max retry times.": "",
|
||||||
|
"Select protocol exceed max retry times.": "",
|
||||||
"SelectAction": "Select",
|
"SelectAction": "Select",
|
||||||
"SelectTheme": "Select Theme",
|
"SelectTheme": "Select Theme",
|
||||||
"Self": "Self",
|
"Self": "Self",
|
||||||
|
"Session max time reached, disconnect": "",
|
||||||
"SessionDetail": "Session Detail",
|
"SessionDetail": "Session Detail",
|
||||||
"SessionShare": "Session Share",
|
"SessionShare": "Session Share",
|
||||||
"Settings": "Settings",
|
"Settings": "Settings",
|
||||||
@@ -96,18 +161,33 @@
|
|||||||
"ShareUser": "Share User",
|
"ShareUser": "Share User",
|
||||||
"ShareUserHelpText": "If left blank, everyone could join the session.",
|
"ShareUserHelpText": "If left blank, everyone could join the session.",
|
||||||
"Size": "Size",
|
"Size": "Size",
|
||||||
|
"Start domain gateway failed %s": "",
|
||||||
|
"Switch language successfully": "",
|
||||||
|
"Switched to %s": "",
|
||||||
"Sync": "Sync",
|
"Sync": "Sync",
|
||||||
"SyncUserPreferenceFailed": "Sync user preference failed",
|
"SyncUserPreferenceFailed": "Sync user preference failed",
|
||||||
"SyncUserPreferenceSuccess": "Sync user preference success",
|
"SyncUserPreferenceSuccess": "Sync user preference success",
|
||||||
|
"Terminal does not support protocol %s, please use web terminal to access": "",
|
||||||
"TerminalInstanceNotFound": "Terminal instance not found for current tab",
|
"TerminalInstanceNotFound": "Terminal instance not found for current tab",
|
||||||
"TerminalInstanceNotFoundForCurrentTab": "Terminal instance not found for current tab",
|
"TerminalInstanceNotFoundForCurrentTab": "Terminal instance not found for current tab",
|
||||||
|
"Terminated by admin %s": "",
|
||||||
|
"The command '%s' requires review. Continue or not [Y/n]?": "",
|
||||||
|
"The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?[Y/N]": "",
|
||||||
"TheCurrentTerminalInstanceWasNotFound": "The current terminal instance was not found",
|
"TheCurrentTerminalInstanceWasNotFound": "The current terminal instance was not found",
|
||||||
"Theme": "Theme",
|
"Theme": "Theme",
|
||||||
"ThemeColors": "Theme Colors",
|
"ThemeColors": "Theme Colors",
|
||||||
"ThemeConfig": "Theme",
|
"ThemeConfig": "Theme",
|
||||||
|
"Ticket Reviewers: %s": "",
|
||||||
|
"Tips: Enter asset[%s] account ID": "",
|
||||||
|
"Tips: Enter g+NodeID to display the host under the node, such as g1": "",
|
||||||
|
"Tips: Enter protocol ID": "",
|
||||||
|
"Tips: To set a default language, go to Personal Settings → Preferences on Web": "",
|
||||||
|
"Tips: switch language by ID (Current session only)": "",
|
||||||
"Transfer": "Transfer",
|
"Transfer": "Transfer",
|
||||||
"Type": "Type",
|
"Type": "Type",
|
||||||
"UnableToGenerateWebSocketURL": "Unable to generate WebSocket URL, missing parameters",
|
"UnableToGenerateWebSocketURL": "Unable to generate WebSocket URL, missing parameters",
|
||||||
|
"Unknown error code: %s, detail: %s": "",
|
||||||
|
"Unknown status": "",
|
||||||
"UpArrow": "Up arrow",
|
"UpArrow": "Up arrow",
|
||||||
"Upload": "Upload",
|
"Upload": "Upload",
|
||||||
"UploadEnd": "Upload completed, please wait for further processing",
|
"UploadEnd": "Upload completed, please wait for further processing",
|
||||||
@@ -117,11 +197,34 @@
|
|||||||
"UploadTips": "Drag file here or click to upload",
|
"UploadTips": "Drag file here or click to upload",
|
||||||
"UploadTitle": "File upload",
|
"UploadTitle": "File upload",
|
||||||
"User": "User",
|
"User": "User",
|
||||||
|
"Username": "",
|
||||||
"UsingRegularExpressions": "Using regular expressions",
|
"UsingRegularExpressions": "Using regular expressions",
|
||||||
"VerifyCode": "Verify Code",
|
"VerifyCode": "Verify Code",
|
||||||
"WaitFileTransfer": "Wait file transfer to finish",
|
"WaitFileTransfer": "Wait file transfer to finish",
|
||||||
"Warning": "Warning",
|
"Warning": "Warning",
|
||||||
"WebSocketClosed": "WebSocket closed",
|
"WebSocketClosed": "WebSocket closed",
|
||||||
"WebSocketConnectionIsClosedHelpText": "WebSocket connection is closed, please refresh the page or reconnect.",
|
"WebSocketConnectionIsClosedHelpText": "WebSocket connection is closed, please refresh the page or reconnect.",
|
||||||
"Writable": "Writable"
|
"Welcome to use JumpServer open source fortress system": "",
|
||||||
|
"Writable": "Writable",
|
||||||
|
"You don't have permission login %s": "",
|
||||||
|
"You get auth token failed": "",
|
||||||
|
"display the assets you have permission": "",
|
||||||
|
"display the databases that you have permission": "",
|
||||||
|
"display the hosts that you have permission": "",
|
||||||
|
"display the kubernetes that you have permission": "",
|
||||||
|
"display the node that you have permission": "",
|
||||||
|
"exit": "",
|
||||||
|
"get connect token err": "",
|
||||||
|
"have no permission to download file": "",
|
||||||
|
"have no permission to upload file": "",
|
||||||
|
"i/o timeout": "",
|
||||||
|
"language switch": "",
|
||||||
|
"network is unreachable": "",
|
||||||
|
"not found matched username %s": "",
|
||||||
|
"part IP, Hostname, Comment": "",
|
||||||
|
"print help": "",
|
||||||
|
"refresh your assets and nodes": "",
|
||||||
|
"select one asset to login": "",
|
||||||
|
"to search login if unique": "",
|
||||||
|
"to search, such as: /192.168": ""
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,45 @@
|
|||||||
{
|
{
|
||||||
|
"\t%2d) Enter {{.GreenBoldColor}}%s{{.ColorEnd}} to %s.%s": "%d) Introduzca {{.GreenBoldColor}}%s{{.ColorEnd}} para %s.%s",
|
||||||
|
"%s approved": "%s Aprobado en la revisión.",
|
||||||
|
"%s node has no assets": "El nodo %s no tiene activos",
|
||||||
|
"%s protocol client not installed.": "El cliente del protocolo %s no está instalado",
|
||||||
|
"%s rejected": "Revisión rechazada",
|
||||||
|
"ACL reject": "El acceso se ha denegado en esta ocasión debido a las limitaciones de la política de control de acceso",
|
||||||
|
"Account <%s> and asset <%s> protocol are inconsistent.": "El usuario del sistema <%s> y el activo <%s> presentan un desacuerdo en el protocolo",
|
||||||
"ActionPerm": "Permisos de acción",
|
"ActionPerm": "Permisos de acción",
|
||||||
|
"Address": "La dirección",
|
||||||
"AlreadyExistsPleaseRename": "El archivo ya existe, por favor renombrar",
|
"AlreadyExistsPleaseRename": "El archivo ya existe, por favor renombrar",
|
||||||
|
"Announcement: ": "Anuncio:",
|
||||||
|
"Authentication failed": "Autenticación fallida (nombre de usuario o contraseña incorrectos)",
|
||||||
"AvailableShortcutKey": "Atajos disponibles",
|
"AvailableShortcutKey": "Atajos disponibles",
|
||||||
"Back": "Regresar",
|
"Back": "Regresar",
|
||||||
|
"Back: B/b": "Regresar: B/b",
|
||||||
"Cancel": "Cancelar",
|
"Cancel": "Cancelar",
|
||||||
|
"Cancel confirm": "Cancelar revisión de inicio de sesión",
|
||||||
|
"Cancel to login asset or max 3 retry": "Cancelar la sesión del activo o alcanzar 3 intentos",
|
||||||
"CancelFileUpload": "Cancelar la subida del archivo",
|
"CancelFileUpload": "Cancelar la subida del archivo",
|
||||||
"CaseSensitive": "Distinguir mayúsculas de minúsculas",
|
"CaseSensitive": "Distinguir mayúsculas de minúsculas",
|
||||||
"Clone Connect": "Copiar ventana",
|
"Clone Connect": "Copiar ventana",
|
||||||
"Close All Tabs": "Cerrar todo",
|
"Close All Tabs": "Cerrar todo",
|
||||||
"Close Current Tab": "Cerrar actual \nColor del tema \nSin dirección \nPegar \nTema \nCerrar todo \nMinuto \nUnirse a compartir \nHas sido removido de la sesión compartida \nIntroduce el nombre de usuario \nPor favor selecciona \nBuscar \nConfirmar \nCrear enlace de compartición \nSubir archivo",
|
"Close Current Tab": "Cerrar actual \nColor del tema \nSin dirección \nPegar \nTema \nCerrar todo \nMinuto \nUnirse a compartir \nHas sido removido de la sesión compartida \nIntroduce el nombre de usuario \nPor favor selecciona \nBuscar \nConfirmar \nCrear enlace de compartición \nSubir archivo",
|
||||||
|
"Command `%s` is forbidden": "El comando `%s` está prohibido ...",
|
||||||
|
"Comment": "Nota",
|
||||||
"Confirm": "Confirmar",
|
"Confirm": "Confirmar",
|
||||||
"ConfirmBtn": "Confirmar",
|
"ConfirmBtn": "Confirmar",
|
||||||
"ConfirmDelete": "¿Está seguro de que desea eliminar este archivo?",
|
"ConfirmDelete": "¿Está seguro de que desea eliminar este archivo?",
|
||||||
"Connect": "Conectar",
|
"Connect": "Conectar",
|
||||||
|
"Connect idle more than %d minutes, disconnect": "Tiempo de inactividad excedido de %d minutos, desconectando",
|
||||||
|
"Connect with api server failed": "Fallo en la conexión con el servicio API",
|
||||||
|
"Connecting to %s@%s": "Comenzando a conectar a %s@%s",
|
||||||
|
"Connecting to Database %s": "Comenzando a conectar a la base de datos %s",
|
||||||
|
"Connecting to Kubernetes %s": "Comenzando a conectar con Kubernetes %s",
|
||||||
|
"Connecting to Kubernetes %s container %s": "Comenzando a conectar con el contenedor de Kubernetes %s en %s",
|
||||||
|
"Connection refused": "Red inalcanzable (conexión rechazada)",
|
||||||
"CopyLink": "Copiar enlace y código de verificación",
|
"CopyLink": "Copiar enlace y código de verificación",
|
||||||
"CopyShareURLSuccess": "Dirección de compartición copiada con éxito",
|
"CopyShareURLSuccess": "Dirección de compartición copiada con éxito",
|
||||||
|
"Core API failed": "Error en la API principal",
|
||||||
|
"Could copy website URL to notify reviewers: %s": "Dirección de auditoría copiables, notificar al auditor: %s",
|
||||||
|
"Create k8s client err: %s": "Error al crear cliente k8s: %s",
|
||||||
"CreateFolder": "Crear carpeta",
|
"CreateFolder": "Crear carpeta",
|
||||||
"CreateLink": "Crear enlace",
|
"CreateLink": "Crear enlace",
|
||||||
"CreateSuccess": "Creación exitosa",
|
"CreateSuccess": "Creación exitosa",
|
||||||
@@ -27,10 +52,14 @@
|
|||||||
"DownloadProgress": "Progreso de descarga",
|
"DownloadProgress": "Progreso de descarga",
|
||||||
"DownloadSuccess": "Descarga exitosa",
|
"DownloadSuccess": "Descarga exitosa",
|
||||||
"Downloading": "Descargando",
|
"Downloading": "Descargando",
|
||||||
|
"Dynamic": "Cuenta dinámica",
|
||||||
"EndFileTransfer": "Transferencia de archivos finalizada",
|
"EndFileTransfer": "Transferencia de archivos finalizada",
|
||||||
|
"Enter ID number directly login, multiple search use // + field, such as: //16": "Consejo: Ingrese el ID del activo para iniciar sesión directamente; para una búsqueda secundaria, use // + campo, por ejemplo: //192",
|
||||||
"ExceedTransferSize": "Superado el tamaño máximo de transferencia",
|
"ExceedTransferSize": "Superado el tamaño máximo de transferencia",
|
||||||
"Expand": "Expandir",
|
"Expand": "Expandir",
|
||||||
"ExpiredTime": "Fecha de validez",
|
"ExpiredTime": "Fecha de validez",
|
||||||
|
"Face ACL is not supported yet. Please use the WebTerminal to connect the asset.": "Este terminal no soporta las reglas de acceso facial, por favor utilice el terminal web para iniciar sesión",
|
||||||
|
"Face verification is not supported yet. Please use the WebTerminal to connect the asset.": "Esta terminal no soporta la autenticación por reconocimiento facial; por favor inicie sesión a través de la terminal web.",
|
||||||
"FailedCreateConnection": "Fallo al crear conexión",
|
"FailedCreateConnection": "Fallo al crear conexión",
|
||||||
"FileAlreadyExists": "El archivo ya existe",
|
"FileAlreadyExists": "El archivo ya existe",
|
||||||
"FileListError": "No se pudo obtener la información de la lista de archivos",
|
"FileListError": "No se pudo obtener la información de la lista de archivos",
|
||||||
@@ -41,10 +70,15 @@
|
|||||||
"FileUploadInterrupted": "La subida del archivo se ha interrumpido",
|
"FileUploadInterrupted": "La subida del archivo se ha interrumpido",
|
||||||
"Format": "Formato",
|
"Format": "Formato",
|
||||||
"General": "General",
|
"General": "General",
|
||||||
|
"Get auth password failed": "Fallo al obtener el token de autenticación",
|
||||||
"GetFileManagerTokenTimeOut": "Tiempo de espera para obtener el token de gestión de archivos",
|
"GetFileManagerTokenTimeOut": "Tiempo de espera para obtener el token de gestión de archivos",
|
||||||
"GetShareUser": "Introducir nombre de usuario",
|
"GetShareUser": "Introducir nombre de usuario",
|
||||||
|
"HandleTask does not support protocol %s, please use web terminal to access": "Este terminal no es compatible con el protocolo %s, utiliza la terminal web para iniciar sesión",
|
||||||
|
"Hostname": "Nombre del host",
|
||||||
"Hotkeys": "Atajos",
|
"Hotkeys": "Atajos",
|
||||||
|
"ID": "ID",
|
||||||
"InputVerifyCode": "Por favor, ingrese el código de verificación",
|
"InputVerifyCode": "Por favor, ingrese el código de verificación",
|
||||||
|
"Invalid ID": "ID inválido",
|
||||||
"JoinShare": "Unirse a la compartición",
|
"JoinShare": "Unirse a la compartición",
|
||||||
"JoinedWithSuccess": "Se ha unido con éxito",
|
"JoinedWithSuccess": "Se ha unido con éxito",
|
||||||
"KubernetesManagement": "Kubernetes gestión",
|
"KubernetesManagement": "Kubernetes gestión",
|
||||||
@@ -53,41 +87,69 @@
|
|||||||
"LeftArrow": "Flecha hacia atrás",
|
"LeftArrow": "Flecha hacia atrás",
|
||||||
"LinkAddr": "Dirección del enlace",
|
"LinkAddr": "Dirección del enlace",
|
||||||
"List": "Lista",
|
"List": "Lista",
|
||||||
|
"Manual": "Cuenta manual",
|
||||||
"MatchWholeWords": "Coincidencia exacta",
|
"MatchWholeWords": "Coincidencia exacta",
|
||||||
"Minute": "Minutos",
|
"Minute": "Minutos",
|
||||||
"Minutes": "Parte",
|
"Minutes": "Parte",
|
||||||
|
"Must be auto login account for %s": "Debe ser una cuenta de inicio de sesión automático %s",
|
||||||
|
"Must be unique account for %s": "Debe ser una cuenta única %s",
|
||||||
|
"Must be unique asset for %s": "debe ser un activo único %s",
|
||||||
"MustOneFile": "Solo se puede seleccionar un archivo",
|
"MustOneFile": "Solo se puede seleccionar un archivo",
|
||||||
"MustSelectOneFile": "Debe seleccionar un archivo",
|
"MustSelectOneFile": "Debe seleccionar un archivo",
|
||||||
"Name": "Nombre",
|
"Name": "Nombre",
|
||||||
|
"Need ACL review, continue? (y/n): ": "necesita auditoría, ¿continuar? (s/n):",
|
||||||
|
"Need ticket confirm to execute command, already send email to the reviewers": "Se necesita un comando de ticket para la revisión de la ejecución, se ha enviado un correo al revisor",
|
||||||
|
"Need ticket confirm to login, already send email to the reviewers": "Se requiere iniciar sesión mediante ticket para la revisión, correo enviado al auditor",
|
||||||
"NewFolder": "Nueva carpeta",
|
"NewFolder": "Nueva carpeta",
|
||||||
|
"No Account found.": "Cuenta no encontrada",
|
||||||
|
"No Assets": "No hay activos",
|
||||||
|
"No Databases": "No hay base de datos",
|
||||||
|
"No found asset": "No se encontró un activo coincidente %s",
|
||||||
|
"No kubernetes": "No hay Kubernetes",
|
||||||
|
"No protocol found.": "Sin protocolo",
|
||||||
|
"No route to host": "Conexión de red no disponible (Enrutador inalcanzable)",
|
||||||
"NoActiveTerminalTabFound": "No se encontró una pestaña de terminal activa",
|
"NoActiveTerminalTabFound": "No se encontró una pestaña de terminal activa",
|
||||||
"NoData": "Sin datos",
|
"NoData": "Sin datos",
|
||||||
"NoLink": "Sin dirección",
|
"NoLink": "Sin dirección",
|
||||||
"NoRunningTerminalFound": "No se encontró ningún terminal en ejecución",
|
"NoRunningTerminalFound": "No se encontró ningún terminal en ejecución",
|
||||||
|
"Node: [ ID.Name(Asset amount) ]": "Nodos: [ ID. Nombre (Cantidad de activos) ]",
|
||||||
"OnlineUser": "Usuarios en línea",
|
"OnlineUser": "Usuarios en línea",
|
||||||
"OperationSuccessful": "La acción se realizó con éxito",
|
"OperationSuccessful": "La acción se realizó con éxito",
|
||||||
|
"Organization": "Organización",
|
||||||
"Owner": "Administrador",
|
"Owner": "Administrador",
|
||||||
|
"Page up: b\tPage down: n": "Página anterior: b Página siguiente: n",
|
||||||
|
"Page: %d, Count: %d, Total Page: %d, Total Count: %d": "Número de página: %d, número de filas por página: %d, número total de páginas: %d, cantidad total: %d",
|
||||||
"Paste": "Pegar",
|
"Paste": "Pegar",
|
||||||
"PauseSession": "Pausar esta sesión",
|
"PauseSession": "Pausar esta sesión",
|
||||||
"PermissionDenied": "Sin permiso",
|
"PermissionDenied": "Sin permiso",
|
||||||
"PermissionExpired": "Los permisos han expirado",
|
"PermissionExpired": "Los permisos han expirado",
|
||||||
"PermissionValid": "Permisos válidos",
|
"PermissionValid": "Permisos válidos",
|
||||||
|
"Platform": "Plataforma",
|
||||||
|
"Please waiting for the reviewers to confirm command `%s`, cancel by CTRL+C or CTRL+D.": "Por favor, espere la revisión del revisor para el comando `%s`; cancele presionando CTRL+C o CTRL+D.",
|
||||||
|
"Please waiting for the reviewers to confirm, enter q to exit. ": "Esperando la revisión y confirmación del auditor, presione q y luego Enter para cancelar el inicio de sesión.",
|
||||||
"PleaseInput": "Por favor, ingrese.",
|
"PleaseInput": "Por favor, ingrese.",
|
||||||
"PleaseInputVerifyCode": "Por favor, ingresa el código de verificación",
|
"PleaseInputVerifyCode": "Por favor, ingresa el código de verificación",
|
||||||
"PrimaryUser": "Usuario principal",
|
"PrimaryUser": "Usuario principal",
|
||||||
|
"Protocol": "Protocolo",
|
||||||
"ReadOnly": "Solo lectura",
|
"ReadOnly": "Solo lectura",
|
||||||
"Reconnect": "Reconectar",
|
"Reconnect": "Reconectar",
|
||||||
"Refresh": "Refrescar",
|
"Refresh": "Refrescar",
|
||||||
|
"Refresh done": "Actualización completada",
|
||||||
"Remove": "Eliminar",
|
"Remove": "Eliminar",
|
||||||
"RemoveShareUser": "Has sido eliminado de la sesión compartida",
|
"RemoveShareUser": "Has sido eliminado de la sesión compartida",
|
||||||
"RemoveUser": "Eliminar usuario",
|
"RemoveUser": "Eliminar usuario",
|
||||||
"Rename": "Renombrar",
|
"Rename": "Renombrar",
|
||||||
"ResumeSession": "Restaurar esta sesión",
|
"ResumeSession": "Restaurar esta sesión",
|
||||||
|
"Reuse SSH connections (%s@%s) [Number of connections: %d]": "Reutilizando conexión SSH (%s@%s) [Cantidad de conexiones: %d]",
|
||||||
"RightArrow": "Flecha hacia adelante",
|
"RightArrow": "Flecha hacia adelante",
|
||||||
"Search": "Buscar",
|
"Search": "Buscar",
|
||||||
|
"Search: %s": "Buscar: %s",
|
||||||
|
"Select account exceed max retry times.": "Se ha superado el número máximo de intentos de selección de cuenta",
|
||||||
|
"Select protocol exceed max retry times.": "Se ha superado el número máximo de intentos para seleccionar el protocolo",
|
||||||
"SelectAction": "Por favor selecciona",
|
"SelectAction": "Por favor selecciona",
|
||||||
"SelectTheme": "Por favor, selecciona un tema",
|
"SelectTheme": "Por favor, selecciona un tema",
|
||||||
"Self": "Yo",
|
"Self": "Yo",
|
||||||
|
"Session max time reached, disconnect": "La sesión ha superado el tiempo máximo de conexión, desconectando",
|
||||||
"SessionDetail": "Detalles de la conversación.",
|
"SessionDetail": "Detalles de la conversación.",
|
||||||
"SessionShare": "Compartir conversación",
|
"SessionShare": "Compartir conversación",
|
||||||
"Settings": "Ajustes",
|
"Settings": "Ajustes",
|
||||||
@@ -96,18 +158,32 @@
|
|||||||
"ShareUser": "Compartir usuario",
|
"ShareUser": "Compartir usuario",
|
||||||
"ShareUserHelpText": "No se ha seleccionado un usuario, lo que permite la entrada de todos",
|
"ShareUserHelpText": "No se ha seleccionado un usuario, lo que permite la entrada de todos",
|
||||||
"Size": "Tamaño",
|
"Size": "Tamaño",
|
||||||
|
"Start domain gateway failed %s": "Fallo al iniciar el gateway de la base de datos %s",
|
||||||
|
"Switch language successfully": "Cambio de idioma exitoso",
|
||||||
|
"Switched to %s": "Se ha cambiado a %s",
|
||||||
"Sync": "Sincronizar",
|
"Sync": "Sincronizar",
|
||||||
"SyncUserPreferenceFailed": "Falló la sincronización de ajustes",
|
"SyncUserPreferenceFailed": "Falló la sincronización de ajustes",
|
||||||
"SyncUserPreferenceSuccess": "Sincronización de ajustes exitosa",
|
"SyncUserPreferenceSuccess": "Sincronización de ajustes exitosa",
|
||||||
|
"Terminal does not support protocol %s, please use web terminal to access": "Este terminal no soporta el protocolo %s, por favor inicie sesión a través del terminal web",
|
||||||
"TerminalInstanceNotFound": "No se encontró una instancia de terminal para la pestaña actual.",
|
"TerminalInstanceNotFound": "No se encontró una instancia de terminal para la pestaña actual.",
|
||||||
"TerminalInstanceNotFoundForCurrentTab": "La pestaña actual no encontró una instancia de terminal",
|
"TerminalInstanceNotFoundForCurrentTab": "La pestaña actual no encontró una instancia de terminal",
|
||||||
|
"The command '%s' requires review. Continue or not [Y/n]?": "El comando %s necesita ser revisado, ¿continuar? [Y/N]",
|
||||||
|
"The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?[Y/N]": "Su comando ejecutado presenta riesgos, se enviará una notificación de alerta al administrador. ¿Desea continuar? [S/N]",
|
||||||
"TheCurrentTerminalInstanceWasNotFound": "No se encontró la instancia de terminal actual",
|
"TheCurrentTerminalInstanceWasNotFound": "No se encontró la instancia de terminal actual",
|
||||||
"Theme": "Tema",
|
"Theme": "Tema",
|
||||||
"ThemeColors": "Color del tema",
|
"ThemeColors": "Color del tema",
|
||||||
"ThemeConfig": "Tema",
|
"ThemeConfig": "Tema",
|
||||||
|
"Ticket Reviewers: %s": "Revisor del ticket: %s",
|
||||||
|
"Tips: Enter asset[%s] account ID": "Sugerencia: Introduzca la ID de cuenta de los activos [%s]",
|
||||||
|
"Tips: Enter g+NodeID to display the host under the node, such as g1": "Sugerencia: ingrese g+ID del nodo para mostrar los hosts bajo el nodo, por ejemplo: g1",
|
||||||
|
"Tips: Enter protocol ID": "Sugerencia: Introduzca el ID del protocolo",
|
||||||
|
"Tips: To set a default language, go to Personal Settings → Preferences on Web": "Sugerencia: si deseas configurar el idioma predeterminado, dirígete a la web en \"Configuración personal → Preferencias\"",
|
||||||
|
"Tips: switch language by ID (Current session only)": "Sugerencia: ingrese el ID para cambiar el idioma",
|
||||||
"Transfer": "Transmisión",
|
"Transfer": "Transmisión",
|
||||||
"Type": "Tipo",
|
"Type": "Tipo",
|
||||||
"UnableToGenerateWebSocketURL": "No se puede generar la URL de WebSocket, faltan parámetros",
|
"UnableToGenerateWebSocketURL": "No se puede generar la URL de WebSocket, faltan parámetros",
|
||||||
|
"Unknown error code: %s, detail: %s": "Código de error desconocido: %s, detalles: %s",
|
||||||
|
"Unknown status": "Estado desconocido",
|
||||||
"UpArrow": "Flecha hacia arriba",
|
"UpArrow": "Flecha hacia arriba",
|
||||||
"Upload": "Subir",
|
"Upload": "Subir",
|
||||||
"UploadEnd": "La subida ha finalizado, por favor espera el procesamiento posterior",
|
"UploadEnd": "La subida ha finalizado, por favor espera el procesamiento posterior",
|
||||||
@@ -117,11 +193,35 @@
|
|||||||
"UploadTips": "Arrastra el archivo aquí, o haz clic para subir",
|
"UploadTips": "Arrastra el archivo aquí, o haz clic para subir",
|
||||||
"UploadTitle": "Subir archivo",
|
"UploadTitle": "Subir archivo",
|
||||||
"User": "Usuario",
|
"User": "Usuario",
|
||||||
|
"Username": "Nombre de usuario",
|
||||||
"UsingRegularExpressions": "Usar expresiones regulares",
|
"UsingRegularExpressions": "Usar expresiones regulares",
|
||||||
"VerifyCode": "Código de verificación.",
|
"VerifyCode": "Código de verificación.",
|
||||||
"WaitFileTransfer": "Esperando que finalice la transferencia de archivos",
|
"WaitFileTransfer": "Esperando que finalice la transferencia de archivos",
|
||||||
"Warning": "Advertencia",
|
"Warning": "Advertencia",
|
||||||
"WebSocketClosed": "WebSocket cerrado",
|
"WebSocketClosed": "WebSocket cerrado",
|
||||||
"WebSocketConnectionIsClosedHelpText": "La conexión WebSocket se ha cerrado, por favor actualiza la página o reconéctate.",
|
"WebSocketConnectionIsClosedHelpText": "La conexión WebSocket se ha cerrado, por favor actualiza la página o reconéctate.",
|
||||||
"Writable": "Se puede escribir"
|
"Welcome to use JumpServer open source fortress system": "Bienvenido al sistema de bastión de código abierto JumpServer",
|
||||||
|
"Writable": "Se puede escribir",
|
||||||
|
"You don't have permission login %s": "No tiene autorización para iniciar sesión en %s",
|
||||||
|
"You get auth token failed": "Ha fallado la obtención del token de autenticación",
|
||||||
|
"display the assets you have permission": "Mostrar los activos a los que tiene acceso",
|
||||||
|
"display the databases that you have permission": "Mostrar las bases de datos a las que tiene acceso",
|
||||||
|
"display the hosts that you have permission": "Mostrar los hosts a los que tiene acceso",
|
||||||
|
"display the kubernetes that you have permission": "Mostrar los Kubernetes a los que tiene acceso",
|
||||||
|
"display the node that you have permission": "Mostrar los nodos a los que tiene acceso",
|
||||||
|
"exit": "Salir",
|
||||||
|
"get connect token err": "Error al obtener el token de conexión",
|
||||||
|
"have no permission to download file": "Sin permiso para descargar archivos",
|
||||||
|
"have no permission to upload file": "Sin permiso para subir archivos",
|
||||||
|
"i/o timeout": "Conexión de red no disponible (Tiempo de conexión agotado)",
|
||||||
|
"language switch": "Cambio de idioma",
|
||||||
|
"network is unreachable": "Conexión de red fallida (red inalcanzable)",
|
||||||
|
"not found matched username %s": "No se encontró un nombre de usuario coincide %s.",
|
||||||
|
"part IP, Hostname, Comment": "Parte de IP, nombre de host, nota",
|
||||||
|
"part IP,, Hostname, Comment": "/ + IP, nombre del host, nota",
|
||||||
|
"print help": "Mostrar ayuda",
|
||||||
|
"refresh your assets and nodes": "Actualizando la información más reciente de máquinas y nodos",
|
||||||
|
"select one asset to login": "Selecciona uno de los activos para iniciar sesión",
|
||||||
|
"to search login if unique": "Buscar inicio de sesión (si es único)",
|
||||||
|
"to search, such as: /192.168": "Buscar, por ejemplo: /192.168"
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,45 @@
|
|||||||
{
|
{
|
||||||
|
"\t%2d) Enter {{.GreenBoldColor}}%s{{.ColorEnd}} to %s.%s": "%d) {{.GreenBoldColor}}%s{{.ColorEnd}} を入力して%s.%sを実行してください。",
|
||||||
|
"%s approved": "%s 承認されました",
|
||||||
|
"%s node has no assets": "%sノードに資産がありません",
|
||||||
|
"%s protocol client not installed.": "%s プロトコルのクライアントがインストールされていません。",
|
||||||
|
"%s rejected": "審査拒否",
|
||||||
|
"ACL reject": "今回のログインは拒否されました。理由はアクセス制御ポリシーによる制限です",
|
||||||
|
"Account <%s> and asset <%s> protocol are inconsistent.": "システムユーザー<%s>と資産<%s>の協定が一致しません",
|
||||||
"ActionPerm": "操作権限",
|
"ActionPerm": "操作権限",
|
||||||
|
"Address": "アドレス",
|
||||||
"AlreadyExistsPleaseRename": "ファイルは既に存在します。名前を変更してください",
|
"AlreadyExistsPleaseRename": "ファイルは既に存在します。名前を変更してください",
|
||||||
|
"Announcement: ": "お知らせ:",
|
||||||
|
"Authentication failed": "認証に失敗しました(ユーザー名またはパスワードが間違っています)。",
|
||||||
"AvailableShortcutKey": "使用可能なショートカット",
|
"AvailableShortcutKey": "使用可能なショートカット",
|
||||||
"Back": "戻る",
|
"Back": "戻る",
|
||||||
|
"Back: B/b": "戻る:B/b",
|
||||||
"Cancel": "キャンセル",
|
"Cancel": "キャンセル",
|
||||||
|
"Cancel confirm": "ログインの確認をキャンセル",
|
||||||
|
"Cancel to login asset or max 3 retry": "資産のログインをキャンセルするか、3回の再試行を行う。",
|
||||||
"CancelFileUpload": "ファイルアップロードをキャンセルする",
|
"CancelFileUpload": "ファイルアップロードをキャンセルする",
|
||||||
"CaseSensitive": "大文字と小文字を区別",
|
"CaseSensitive": "大文字と小文字を区別",
|
||||||
"Clone Connect": "ウィンドウをコピー",
|
"Clone Connect": "ウィンドウをコピー",
|
||||||
"Close All Tabs": "すべてを閉じる",
|
"Close All Tabs": "すべてを閉じる",
|
||||||
"Close Current Tab": "現在を閉じる",
|
"Close Current Tab": "現在を閉じる",
|
||||||
|
"Command `%s` is forbidden": "コマンド `%s` は禁止されています ...",
|
||||||
|
"Comment": "備考",
|
||||||
"Confirm": "確認",
|
"Confirm": "確認",
|
||||||
"ConfirmBtn": "確定",
|
"ConfirmBtn": "確定",
|
||||||
"ConfirmDelete": "このファイルを削除してもよろしいですか?",
|
"ConfirmDelete": "このファイルを削除してもよろしいですか?",
|
||||||
"Connect": "接続",
|
"Connect": "接続",
|
||||||
|
"Connect idle more than %d minutes, disconnect": "アイドル時間が%d分を超えたため、接続が切断されました",
|
||||||
|
"Connect with api server failed": "APIサービスに接続に失敗しました",
|
||||||
|
"Connecting to %s@%s": "%s@%s への接続を開始中",
|
||||||
|
"Connecting to Database %s": "データベース %s への接続を開始します。",
|
||||||
|
"Connecting to Kubernetes %s": "Kubernetes %s への接続を開始します",
|
||||||
|
"Connecting to Kubernetes %s container %s": "Kubernetes %s コンテナ %s に接続を開始します",
|
||||||
|
"Connection refused": "ネットワーク接続がありません(接続が拒否されました)",
|
||||||
"CopyLink": "リンクと認証コードのコピー",
|
"CopyLink": "リンクと認証コードのコピー",
|
||||||
"CopyShareURLSuccess": "レプリケーション共有住所成功",
|
"CopyShareURLSuccess": "レプリケーション共有住所成功",
|
||||||
|
"Core API failed": "Core APIにエラーが発生しました",
|
||||||
|
"Could copy website URL to notify reviewers: %s": "コピー可能な監査アドレス、監査人に通知:%s",
|
||||||
|
"Create k8s client err: %s": "k8s クライアントエラーの作成:%s",
|
||||||
"CreateFolder": "フォルダーを作成",
|
"CreateFolder": "フォルダーを作成",
|
||||||
"CreateLink": "リンクを作成する",
|
"CreateLink": "リンクを作成する",
|
||||||
"CreateSuccess": "作成に成功しました",
|
"CreateSuccess": "作成に成功しました",
|
||||||
@@ -27,10 +52,14 @@
|
|||||||
"DownloadProgress": "ダウンロード進捗",
|
"DownloadProgress": "ダウンロード進捗",
|
||||||
"DownloadSuccess": "ダウンロードに成功しました",
|
"DownloadSuccess": "ダウンロードに成功しました",
|
||||||
"Downloading": "ダウンロード中",
|
"Downloading": "ダウンロード中",
|
||||||
|
"Dynamic": "動的アカウント",
|
||||||
"EndFileTransfer": "ファイル転送終了",
|
"EndFileTransfer": "ファイル転送終了",
|
||||||
|
"Enter ID number directly login, multiple search use // + field, such as: //16": "ヒント:資産IDを入力して直接ログイン、二次検索には // + フィールドを使用します。例://192",
|
||||||
"ExceedTransferSize": "最大転送サイズを超えています",
|
"ExceedTransferSize": "最大転送サイズを超えています",
|
||||||
"Expand": "展開",
|
"Expand": "展開",
|
||||||
"ExpiredTime": "有効期限",
|
"ExpiredTime": "有効期限",
|
||||||
|
"Face ACL is not supported yet. Please use the WebTerminal to connect the asset.": "この端末は顔認証アクセスルールをサポートしていません。web端末でのログインを使用してください",
|
||||||
|
"Face verification is not supported yet. Please use the WebTerminal to connect the asset.": "この端末は顔認識認証をサポートしていません。ウェブ端末を使用してログインしてください。",
|
||||||
"FailedCreateConnection": "接続の作成に失敗しました",
|
"FailedCreateConnection": "接続の作成に失敗しました",
|
||||||
"FileAlreadyExists": "ファイルは既に存在します",
|
"FileAlreadyExists": "ファイルは既に存在します",
|
||||||
"FileListError": "ファイルリスト情報の取得に失敗しました",
|
"FileListError": "ファイルリスト情報の取得に失敗しました",
|
||||||
@@ -41,10 +70,15 @@
|
|||||||
"FileUploadInterrupted": "ファイルアップロードが中断されました",
|
"FileUploadInterrupted": "ファイルアップロードが中断されました",
|
||||||
"Format": "フォーマット",
|
"Format": "フォーマット",
|
||||||
"General": "汎用",
|
"General": "汎用",
|
||||||
|
"Get auth password failed": "認証トークンの取得に失敗しました",
|
||||||
"GetFileManagerTokenTimeOut": "ファイル管理トークンの取得がタイムアウトしました",
|
"GetFileManagerTokenTimeOut": "ファイル管理トークンの取得がタイムアウトしました",
|
||||||
"GetShareUser": "ユーザー名の入力",
|
"GetShareUser": "ユーザー名の入力",
|
||||||
|
"HandleTask does not support protocol %s, please use web terminal to access": "この端末は %s プロトコルをサポートしていません。Web端末でログインしてください",
|
||||||
|
"Hostname": "ホスト名",
|
||||||
"Hotkeys": "ショートカットキー",
|
"Hotkeys": "ショートカットキー",
|
||||||
|
"ID": "ID",
|
||||||
"InputVerifyCode": "認証コードを入力してください",
|
"InputVerifyCode": "認証コードを入力してください",
|
||||||
|
"Invalid ID": "無効なID",
|
||||||
"JoinShare": "共有セッションに参加",
|
"JoinShare": "共有セッションに参加",
|
||||||
"JoinedWithSuccess": "正常に参加しました",
|
"JoinedWithSuccess": "正常に参加しました",
|
||||||
"KubernetesManagement": "Kubernetes 管理",
|
"KubernetesManagement": "Kubernetes 管理",
|
||||||
@@ -53,41 +87,69 @@
|
|||||||
"LeftArrow": "戻る矢印",
|
"LeftArrow": "戻る矢印",
|
||||||
"LinkAddr": "リンクのアドレス",
|
"LinkAddr": "リンクのアドレス",
|
||||||
"List": "リスト",
|
"List": "リスト",
|
||||||
|
"Manual": "手動アカウント",
|
||||||
"MatchWholeWords": "完全一致",
|
"MatchWholeWords": "完全一致",
|
||||||
"Minute": "分",
|
"Minute": "分",
|
||||||
"Minutes": "分",
|
"Minutes": "分",
|
||||||
|
"Must be auto login account for %s": "自動ログインアカウントである必要があります %s",
|
||||||
|
"Must be unique account for %s": "唯一のアカウントである必要があります %s",
|
||||||
|
"Must be unique asset for %s": "は一意の資産でなければなりません %s",
|
||||||
"MustOneFile": "ファイルを1つだけ選択できます",
|
"MustOneFile": "ファイルを1つだけ選択できます",
|
||||||
"MustSelectOneFile": "ファイルを選択する必要があります",
|
"MustSelectOneFile": "ファイルを選択する必要があります",
|
||||||
"Name": "名前",
|
"Name": "名前",
|
||||||
|
"Need ACL review, continue? (y/n): ": "の审核が必要です。続けますか?(y/n):",
|
||||||
|
"Need ticket confirm to execute command, already send email to the reviewers": "実行の再確認には作業命令が必要です。審査者にメール通知が送信されました",
|
||||||
|
"Need ticket confirm to login, already send email to the reviewers": "チケットログインの再確認が必要で、監査人にメール通知が送信されました",
|
||||||
"NewFolder": "新しいフォルダー",
|
"NewFolder": "新しいフォルダー",
|
||||||
|
"No Account found.": "アカウントが見つかりません",
|
||||||
|
"No Assets": "資産がありません",
|
||||||
|
"No Databases": "データベースがありません",
|
||||||
|
"No found asset": "一致する資産が見つかりません %s",
|
||||||
|
"No kubernetes": "kubernetesがありません",
|
||||||
|
"No protocol found.": "プロトコルがありません。",
|
||||||
|
"No route to host": "ネットワーク不通(ルーティング不通)",
|
||||||
"NoActiveTerminalTabFound": "アクティブな端末タブが見つかりませんでした",
|
"NoActiveTerminalTabFound": "アクティブな端末タブが見つかりませんでした",
|
||||||
"NoData": "データがありません",
|
"NoData": "データがありません",
|
||||||
"NoLink": "住所なし",
|
"NoLink": "住所なし",
|
||||||
"NoRunningTerminalFound": "実行中のターミナルが見つかりませんでした",
|
"NoRunningTerminalFound": "実行中のターミナルが見つかりませんでした",
|
||||||
|
"Node: [ ID.Name(Asset amount) ]": "ノード:[ ID.名前(資産数) ]",
|
||||||
"OnlineUser": "オンラインユーザー",
|
"OnlineUser": "オンラインユーザー",
|
||||||
"OperationSuccessful": "操作成功",
|
"OperationSuccessful": "操作成功",
|
||||||
|
"Organization": "組織",
|
||||||
"Owner": "管理者",
|
"Owner": "管理者",
|
||||||
|
"Page up: b\tPage down: n": "前のページ:b 次のページ:n",
|
||||||
|
"Page: %d, Count: %d, Total Page: %d, Total Count: %d": "ページ番号:%d、1ページの行数:%d、総ページ数:%d、総数:%d",
|
||||||
"Paste": "貼り付け",
|
"Paste": "貼り付け",
|
||||||
"PauseSession": "セッションを一時停止",
|
"PauseSession": "セッションを一時停止",
|
||||||
"PermissionDenied": "権限がありません",
|
"PermissionDenied": "権限がありません",
|
||||||
"PermissionExpired": "許可が期限切れになりました",
|
"PermissionExpired": "許可が期限切れになりました",
|
||||||
"PermissionValid": "権限は有効です",
|
"PermissionValid": "権限は有効です",
|
||||||
|
"Platform": "プラットフォーム",
|
||||||
|
"Please waiting for the reviewers to confirm command `%s`, cancel by CTRL+C or CTRL+D.": "レビュアーがコマンド `%s` を確認するまでお待ちください。キャンセルするには CTRL+C または CTRL+D を押してください。",
|
||||||
|
"Please waiting for the reviewers to confirm, enter q to exit. ": "審査者の確認を待っています。ログインをキャンセルするには q を押してください。",
|
||||||
"PleaseInput": "入力してください",
|
"PleaseInput": "入力してください",
|
||||||
"PleaseInputVerifyCode": "验证码を入力してください",
|
"PleaseInputVerifyCode": "验证码を入力してください",
|
||||||
"PrimaryUser": "主要ユーザー",
|
"PrimaryUser": "主要ユーザー",
|
||||||
|
"Protocol": "プロトコル",
|
||||||
"ReadOnly": "読み取り専用",
|
"ReadOnly": "読み取り専用",
|
||||||
"Reconnect": "再接続",
|
"Reconnect": "再接続",
|
||||||
"Refresh": "リフレッシュ",
|
"Refresh": "リフレッシュ",
|
||||||
|
"Refresh done": "更新完了",
|
||||||
"Remove": "削除",
|
"Remove": "削除",
|
||||||
"RemoveShareUser": "あなたはすでに共有セッションから削除されました」という意味です",
|
"RemoveShareUser": "あなたはすでに共有セッションから削除されました」という意味です",
|
||||||
"RemoveUser": "ユーザーを削除",
|
"RemoveUser": "ユーザーを削除",
|
||||||
"Rename": "再命名",
|
"Rename": "再命名",
|
||||||
"ResumeSession": "セッションを再開",
|
"ResumeSession": "セッションを再開",
|
||||||
|
"Reuse SSH connections (%s@%s) [Number of connections: %d]": "SSH接続を再利用中(%s@%s)[接続数: %d]",
|
||||||
"RightArrow": "進む矢印",
|
"RightArrow": "進む矢印",
|
||||||
"Search": "検索",
|
"Search": "検索",
|
||||||
|
"Search: %s": "検索:%s",
|
||||||
|
"Select account exceed max retry times.": "アカウントの選択が最大リトライ回数を超えました。",
|
||||||
|
"Select protocol exceed max retry times.": "選択したプロトコルが最大リトライ回数を超えました",
|
||||||
"SelectAction": "選択してください",
|
"SelectAction": "選択してください",
|
||||||
"SelectTheme": "テーマを選択してください",
|
"SelectTheme": "テーマを選択してください",
|
||||||
"Self": "自分",
|
"Self": "自分",
|
||||||
|
"Session max time reached, disconnect": "セッションが最大接続時間を超え、接続が切断されました",
|
||||||
"SessionDetail": "会話の詳細",
|
"SessionDetail": "会話の詳細",
|
||||||
"SessionShare": "会話を共有",
|
"SessionShare": "会話を共有",
|
||||||
"Settings": "設定",
|
"Settings": "設定",
|
||||||
@@ -96,18 +158,32 @@
|
|||||||
"ShareUser": "共有ユーザー",
|
"ShareUser": "共有ユーザー",
|
||||||
"ShareUserHelpText": "ユーザーが選択されていません。つまり、すべての人が参加できます。",
|
"ShareUserHelpText": "ユーザーが選択されていません。つまり、すべての人が参加できます。",
|
||||||
"Size": "サイズ",
|
"Size": "サイズ",
|
||||||
|
"Start domain gateway failed %s": "データベースゲートウェイの起動に失敗しました %s \n最新のマシンとノード情報を刷新しています \nコマンド %s の再確認が必要です。続行しますか?[Y/N] \n検索: /192.168 \nネットワークが接続できません(ネットワークに到達できません) \nデータベースが存在しません \nあなたが権限を持つデータベースを表示します \n%s@%s に接続を開始しています \nあなたが権限を持つKubernetesを表示します \n更新が完了しました \nノード:[ ID.名称(資産数量) ] \n言語の切り替えに成功しました \nプロトコルの選択が最大再試行回数を超えました \nアイドル時間が%d分を超えたため、接続が切断されました \nヒント:g+ノードID を入力すると、そのノードの主機を表示します。例: g1",
|
||||||
|
"Switch language successfully": "言語の切り替えが成功しました",
|
||||||
|
"Switched to %s": "%sに切り替えました。",
|
||||||
"Sync": "同期",
|
"Sync": "同期",
|
||||||
"SyncUserPreferenceFailed": "ユーザー設定の同期に失敗しました",
|
"SyncUserPreferenceFailed": "ユーザー設定の同期に失敗しました",
|
||||||
"SyncUserPreferenceSuccess": "ユーザー設定の同期に成功しました",
|
"SyncUserPreferenceSuccess": "ユーザー設定の同期に成功しました",
|
||||||
|
"Terminal does not support protocol %s, please use web terminal to access": "この端末は %s プロトコルをサポートしていません。ウェブ端末を使用してログインしてください。",
|
||||||
"TerminalInstanceNotFound": "現在のタブのターミナルインスタンスが見つかりませんでした",
|
"TerminalInstanceNotFound": "現在のタブのターミナルインスタンスが見つかりませんでした",
|
||||||
"TerminalInstanceNotFoundForCurrentTab": "現在のタブに端末インスタンスが見つかりません",
|
"TerminalInstanceNotFoundForCurrentTab": "現在のタブに端末インスタンスが見つかりません",
|
||||||
|
"The command '%s' requires review. Continue or not [Y/n]?": "命令 %s は再確認が必要です。続けますか?[Y/N]",
|
||||||
|
"The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?[Y/N]": "あなたが実行した命令にはリスクがあります。警告通知が管理者に送信されます。続けますか?[Y/N]",
|
||||||
"TheCurrentTerminalInstanceWasNotFound": "現在のターミナルインスタンスが見つかりませんでした",
|
"TheCurrentTerminalInstanceWasNotFound": "現在のターミナルインスタンスが見つかりませんでした",
|
||||||
"Theme": "テーマ",
|
"Theme": "テーマ",
|
||||||
"ThemeColors": "テーマカラー",
|
"ThemeColors": "テーマカラー",
|
||||||
"ThemeConfig": "テーマ",
|
"ThemeConfig": "テーマ",
|
||||||
|
"Ticket Reviewers: %s": "チケットレビュアー:%s",
|
||||||
|
"Tips: Enter asset[%s] account ID": "提示:入力された資産[%s]のアカウントID←SEP→ページ番号:%d、1ページあたりの行数:%d、総ページ数:%d、総数量:%d←SEP→審査者の確認をお待ちしています。qを押してログインをキャンセルします。←SEP→ネットワーク通信異常(接続タイムアウト)←SEP→ネットワーク通信異常(ルーター接続不可)←SEP→APIサービスへの接続に失敗しました←SEP→ヘルプを表示←SEP→プラットフォーム←SEP→ファイルのダウンロード権限がありません←SEP→%s 承認されました",
|
||||||
|
"Tips: Enter g+NodeID to display the host under the node, such as g1": "ヒント:g+ノードIDを入力すると、そのノードに属するホストが表示されます。例:g1",
|
||||||
|
"Tips: Enter protocol ID": "ヒント:プロトコルIDを入力してください",
|
||||||
|
"Tips: To set a default language, go to Personal Settings → Preferences on Web": "ヒント:デフォルト言語を設定するには、Web端の「個人設定 → お好み設定」に移動してください",
|
||||||
|
"Tips: switch language by ID (Current session only)": "ヒント:IDを入力して言語を切り替え",
|
||||||
"Transfer": "伝送",
|
"Transfer": "伝送",
|
||||||
"Type": "タイプ",
|
"Type": "タイプ",
|
||||||
"UnableToGenerateWebSocketURL": "WebSocket URLを生成できません。パラメータが不足しています",
|
"UnableToGenerateWebSocketURL": "WebSocket URLを生成できません。パラメータが不足しています",
|
||||||
|
"Unknown error code: %s, detail: %s": "不明なエラーコード:%s、詳細:%s",
|
||||||
|
"Unknown status": "不明な状態",
|
||||||
"UpArrow": "上向き矢印",
|
"UpArrow": "上向き矢印",
|
||||||
"Upload": "アップロード",
|
"Upload": "アップロード",
|
||||||
"UploadEnd": "アップロードが完了しました。後の処理をお待ちください",
|
"UploadEnd": "アップロードが完了しました。後の処理をお待ちください",
|
||||||
@@ -117,11 +193,35 @@
|
|||||||
"UploadTips": "ファイルをここにドラッグするか、アップロードをクリックします",
|
"UploadTips": "ファイルをここにドラッグするか、アップロードをクリックします",
|
||||||
"UploadTitle": "ファイルのアップロード",
|
"UploadTitle": "ファイルのアップロード",
|
||||||
"User": "ユーザー",
|
"User": "ユーザー",
|
||||||
|
"Username": "ユーザー名",
|
||||||
"UsingRegularExpressions": "正規表現を使用",
|
"UsingRegularExpressions": "正規表現を使用",
|
||||||
"VerifyCode": "認証コード",
|
"VerifyCode": "認証コード",
|
||||||
"WaitFileTransfer": "ファイル転送終了待ち",
|
"WaitFileTransfer": "ファイル転送終了待ち",
|
||||||
"Warning": "警告",
|
"Warning": "警告",
|
||||||
"WebSocketClosed": "WebSocket 閉店",
|
"WebSocketClosed": "WebSocket 閉店",
|
||||||
"WebSocketConnectionIsClosedHelpText": "WebSocket接続が閉じられました。ページをリフレッシュするか、再接続してください。",
|
"WebSocketConnectionIsClosedHelpText": "WebSocket接続が閉じられました。ページをリフレッシュするか、再接続してください。",
|
||||||
"Writable": "作成"
|
"Welcome to use JumpServer open source fortress system": "JumpServerオープンソースバリケードシステムへようこそ",
|
||||||
|
"Writable": "作成",
|
||||||
|
"You don't have permission login %s": "あなたは%sにログインする権限がありません",
|
||||||
|
"You get auth token failed": "認証トークンの取得に失敗しました",
|
||||||
|
"display the assets you have permission": "あなたが権限を持つ資産を表示",
|
||||||
|
"display the databases that you have permission": "あなたが権限を持っているデータベースを表示します",
|
||||||
|
"display the hosts that you have permission": "あなたが権限を持つホストを表示します。",
|
||||||
|
"display the kubernetes that you have permission": "あなたが権限を持っているKubernetesを表示します",
|
||||||
|
"display the node that you have permission": "あなたが権限を持つノードを表示",
|
||||||
|
"exit": "終了",
|
||||||
|
"get connect token err": "接続トークンの取得に失敗しました",
|
||||||
|
"have no permission to download file": "ファイルをダウンロードする権限がありません",
|
||||||
|
"have no permission to upload file": "ファイルのアップロード権限がありません。",
|
||||||
|
"i/o timeout": "ネットワークが接続できません(タイムアウト)",
|
||||||
|
"language switch": "言語切替",
|
||||||
|
"network is unreachable": "ネットワーク不通(ネットワーク到達不可)",
|
||||||
|
"not found matched username %s": "一致するユーザー名 %s が見つかりませんでした。",
|
||||||
|
"part IP, Hostname, Comment": "一部のIP、ホスト名、備考",
|
||||||
|
"part IP,, Hostname, Comment": "/ + IP、ホスト名、備考",
|
||||||
|
"print help": "ヘルプを表示します",
|
||||||
|
"refresh your assets and nodes": "最新のマシンとノード情報を更新します",
|
||||||
|
"select one asset to login": "資産のいずれかを選択してログイン",
|
||||||
|
"to search login if unique": "ログイン検索(唯一の場合)",
|
||||||
|
"to search, such as: /192.168": "検索:/192.168"
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,45 @@
|
|||||||
{
|
{
|
||||||
|
"\t%2d) Enter {{.GreenBoldColor}}%s{{.ColorEnd}} to %s.%s": "%d) {{.GreenBoldColor}}%s{{.ColorEnd}}를 입력하여 %s.%s 진행",
|
||||||
|
"%s approved": "%s 검토 통과",
|
||||||
|
"%s node has no assets": "%s 노드에는 자산이 없습니다",
|
||||||
|
"%s protocol client not installed.": "%s 프로토콜의 클라이언트가 설치되어 있지 않음",
|
||||||
|
"%s rejected": "%s 심사 거부",
|
||||||
|
"ACL reject": "이번 로그인은 접근 제어 정책의 제한으로 거부되었습니다",
|
||||||
|
"Account <%s> and asset <%s> protocol are inconsistent.": "시스템 사용자<%s>와 자산<%s> 프로토콜 불일치",
|
||||||
"ActionPerm": "작업 권한",
|
"ActionPerm": "작업 권한",
|
||||||
|
"Address": "주소",
|
||||||
"AlreadyExistsPleaseRename": "파일이 이미 존재합니다, 이름을 변경해 주세요",
|
"AlreadyExistsPleaseRename": "파일이 이미 존재합니다, 이름을 변경해 주세요",
|
||||||
|
"Announcement: ": "공지사항:",
|
||||||
|
"Authentication failed": "인증 실패(사용자 이름 또는 비밀번호 오류)",
|
||||||
"AvailableShortcutKey": "사용 가능한 단축키",
|
"AvailableShortcutKey": "사용 가능한 단축키",
|
||||||
"Back": "돌아가기",
|
"Back": "돌아가기",
|
||||||
|
"Back: B/b": "반환: B/b",
|
||||||
"Cancel": "취소",
|
"Cancel": "취소",
|
||||||
|
"Cancel confirm": "로그인 검토를 취소합니다",
|
||||||
|
"Cancel to login asset or max 3 retry": "자산 로그인을 취소하거나 3회 재시도에 도달",
|
||||||
"CancelFileUpload": "파일 업로드 취소",
|
"CancelFileUpload": "파일 업로드 취소",
|
||||||
"CaseSensitive": "대소문자 구분",
|
"CaseSensitive": "대소문자 구분",
|
||||||
"Clone Connect": "복사 창",
|
"Clone Connect": "복사 창",
|
||||||
"Close All Tabs": "모두 닫기",
|
"Close All Tabs": "모두 닫기",
|
||||||
"Close Current Tab": "현재 닫기",
|
"Close Current Tab": "현재 닫기",
|
||||||
|
"Command `%s` is forbidden": "명령 `%s` 는 금지되었습니다 ...",
|
||||||
|
"Comment": "비고",
|
||||||
"Confirm": "확인",
|
"Confirm": "확인",
|
||||||
"ConfirmBtn": "확인",
|
"ConfirmBtn": "확인",
|
||||||
"ConfirmDelete": "이 파일을 삭제하시겠습니까?",
|
"ConfirmDelete": "이 파일을 삭제하시겠습니까?",
|
||||||
"Connect": "연결",
|
"Connect": "연결",
|
||||||
|
"Connect idle more than %d minutes, disconnect": "%d분 넘어 노는 시간, 연결 종료",
|
||||||
|
"Connect with api server failed": "API 서비스 연결 실패",
|
||||||
|
"Connecting to %s@%s": "%s@%s에 연결을 시작합니다",
|
||||||
|
"Connecting to Database %s": "데이터베이스 %s에 연결 중",
|
||||||
|
"Connecting to Kubernetes %s": "Kubernetes %s에 연결 시작",
|
||||||
|
"Connecting to Kubernetes %s container %s": "Kubernetes %s 컨테이너 %s에 연결 시작",
|
||||||
|
"Connection refused": "네트워크 연결 불가 (연결 거부)",
|
||||||
"CopyLink": "링크 및 인증 코드 복사",
|
"CopyLink": "링크 및 인증 코드 복사",
|
||||||
"CopyShareURLSuccess": "공유 주소 복사 성공",
|
"CopyShareURLSuccess": "공유 주소 복사 성공",
|
||||||
|
"Core API failed": "Core API에서 오류 발생",
|
||||||
|
"Could copy website URL to notify reviewers: %s": "복사 가능한 감사 주소, 감사인에게 통지: %s",
|
||||||
|
"Create k8s client err: %s": "k8s 클라이언트 오류 생성: %s",
|
||||||
"CreateFolder": "폴더 생성",
|
"CreateFolder": "폴더 생성",
|
||||||
"CreateLink": "링크 생성",
|
"CreateLink": "링크 생성",
|
||||||
"CreateSuccess": "생성이 성공적으로 완료되었습니다",
|
"CreateSuccess": "생성이 성공적으로 완료되었습니다",
|
||||||
@@ -27,10 +52,14 @@
|
|||||||
"DownloadProgress": "다운로드 진행 상황",
|
"DownloadProgress": "다운로드 진행 상황",
|
||||||
"DownloadSuccess": "다운로드 성공",
|
"DownloadSuccess": "다운로드 성공",
|
||||||
"Downloading": "다운로드 중",
|
"Downloading": "다운로드 중",
|
||||||
|
"Dynamic": "동적 계정",
|
||||||
"EndFileTransfer": "파일 전송 종료",
|
"EndFileTransfer": "파일 전송 종료",
|
||||||
|
"Enter ID number directly login, multiple search use // + field, such as: //16": "提示:자산 ID를 입력하여 직접 로그인하십시오. 2차 검색은 // + 필드를 사용하십시오. 예: //192",
|
||||||
"ExceedTransferSize": "최대 전송 크기를 초과했습니다",
|
"ExceedTransferSize": "최대 전송 크기를 초과했습니다",
|
||||||
"Expand": "펼치기",
|
"Expand": "펼치기",
|
||||||
"ExpiredTime": "유효 기간",
|
"ExpiredTime": "유효 기간",
|
||||||
|
"Face ACL is not supported yet. Please use the WebTerminal to connect the asset.": "이 단말기는 얼굴 인식 규칙을 지원하지 않으므로 웹 단말기로 로그인해 주십시오",
|
||||||
|
"Face verification is not supported yet. Please use the WebTerminal to connect the asset.": "해당 단말기는 얼굴 인식 인증을 지원하지 않습니다, 웹 단말기로 로그인해 주세요",
|
||||||
"FailedCreateConnection": "연결 생성 실패",
|
"FailedCreateConnection": "연결 생성 실패",
|
||||||
"FileAlreadyExists": "파일이 이미 존재합니다",
|
"FileAlreadyExists": "파일이 이미 존재합니다",
|
||||||
"FileListError": "파일 목록 정보 가져오기 실패",
|
"FileListError": "파일 목록 정보 가져오기 실패",
|
||||||
@@ -41,10 +70,15 @@
|
|||||||
"FileUploadInterrupted": "파일 업로드 중단",
|
"FileUploadInterrupted": "파일 업로드 중단",
|
||||||
"Format": "형식",
|
"Format": "형식",
|
||||||
"General": "일반",
|
"General": "일반",
|
||||||
|
"Get auth password failed": "인증 토큰을 가져오는 데 실패했습니다",
|
||||||
"GetFileManagerTokenTimeOut": "파일 관리 토큰을 얻는 데 시간 초과",
|
"GetFileManagerTokenTimeOut": "파일 관리 토큰을 얻는 데 시간 초과",
|
||||||
"GetShareUser": "사용자 이름 입력",
|
"GetShareUser": "사용자 이름 입력",
|
||||||
|
"HandleTask does not support protocol %s, please use web terminal to access": "해당 단말기는 %s 프로토콜을 지원하지 않습니다, 웹 단말기로 로그인해 주십시오",
|
||||||
|
"Hostname": "호스트 이름",
|
||||||
"Hotkeys": "단축키",
|
"Hotkeys": "단축키",
|
||||||
|
"ID": "아이디",
|
||||||
"InputVerifyCode": "인증 코드를 입력하세요",
|
"InputVerifyCode": "인증 코드를 입력하세요",
|
||||||
|
"Invalid ID": "유효하지 않은 ID",
|
||||||
"JoinShare": "공유에 가입",
|
"JoinShare": "공유에 가입",
|
||||||
"JoinedWithSuccess": "성공적으로 가입되었습니다",
|
"JoinedWithSuccess": "성공적으로 가입되었습니다",
|
||||||
"KubernetesManagement": "Kubernetes 관리",
|
"KubernetesManagement": "Kubernetes 관리",
|
||||||
@@ -53,41 +87,69 @@
|
|||||||
"LeftArrow": "뒤로 화살표",
|
"LeftArrow": "뒤로 화살표",
|
||||||
"LinkAddr": "링크 주소",
|
"LinkAddr": "링크 주소",
|
||||||
"List": "목록",
|
"List": "목록",
|
||||||
|
"Manual": "수동 계정",
|
||||||
"MatchWholeWords": "전체 단어 일치",
|
"MatchWholeWords": "전체 단어 일치",
|
||||||
"Minute": "분",
|
"Minute": "분",
|
||||||
"Minutes": "분",
|
"Minutes": "분",
|
||||||
|
"Must be auto login account for %s": "필수적으로 자동 로그인 계정 %s",
|
||||||
|
"Must be unique account for %s": "필수적으로 유일한 계정 %s",
|
||||||
|
"Must be unique asset for %s": "자산 %s는 반드시 고유해야 합니다",
|
||||||
"MustOneFile": "하나의 파일만 선택할 수 있습니다",
|
"MustOneFile": "하나의 파일만 선택할 수 있습니다",
|
||||||
"MustSelectOneFile": "파일 하나를 선택해야 합니다",
|
"MustSelectOneFile": "파일 하나를 선택해야 합니다",
|
||||||
"Name": "이름",
|
"Name": "이름",
|
||||||
|
"Need ACL review, continue? (y/n): ": "검토가 필요합니다, 계속하시겠습니까?(y/n):",
|
||||||
|
"Need ticket confirm to execute command, already send email to the reviewers": "검토를 수행하기 위해 작업 지시가 필요하며, 검토자에게 이메일 통지를 발송하였습니다",
|
||||||
|
"Need ticket confirm to login, already send email to the reviewers": "작업 요청 로그인 재검토가 필요합니다, 감사인에게 이메일이 발송되었습니다",
|
||||||
"NewFolder": "새 폴더 만들기",
|
"NewFolder": "새 폴더 만들기",
|
||||||
|
"No Account found.": "계정이 발견되지 않음",
|
||||||
|
"No Assets": "자산이 없습니다",
|
||||||
|
"No Databases": "데이터베이스 없음",
|
||||||
|
"No found asset": "일치하는 자산을 찾을 수 없습니다 %s",
|
||||||
|
"No kubernetes": "kubernetes가 없습니다",
|
||||||
|
"No protocol found.": "프로토콜 없음",
|
||||||
|
"No route to host": "네트워크가 연결되지 않음 (라우터 연결 실패)",
|
||||||
"NoActiveTerminalTabFound": "활성 터미널 탭을 찾을 수 없음",
|
"NoActiveTerminalTabFound": "활성 터미널 탭을 찾을 수 없음",
|
||||||
"NoData": "데이터 없음",
|
"NoData": "데이터 없음",
|
||||||
"NoLink": "주소 없음",
|
"NoLink": "주소 없음",
|
||||||
"NoRunningTerminalFound": "실행 중인 터미널을 찾을 수 없습니다",
|
"NoRunningTerminalFound": "실행 중인 터미널을 찾을 수 없습니다",
|
||||||
|
"Node: [ ID.Name(Asset amount) ]": "노드: [ ID.이름(자산 수량) ]",
|
||||||
"OnlineUser": "온라인 사용자",
|
"OnlineUser": "온라인 사용자",
|
||||||
"OperationSuccessful": "작업 성공",
|
"OperationSuccessful": "작업 성공",
|
||||||
|
"Organization": "조직이 검토가 필요합니다. 계속하시겠습니까? (y/n): 당신이 실행한 명령은 위험이 존재합니다. 경고 알림이 관리자에게 전송됩니다. 계속하시겠습니까? [Y/N] 팁: ID를 입력하여 언어를 전환하세요. 이전 페이지: b 다음 페이지: n 시스템 사용자 <%s>와 자산 <%s>의 프로토콜이 일치하지 않습니다. 세션이 최대 연결 시간을 초과하여 연결이 끊어졌습니다. %s에 로그인할 권한이 없습니다. 계정이 발견되지 않았습니다. 자산이 없습니다. 이번 로그인은 접근 제어 정책의 제한으로 인해 거부되었습니다. 작업 명령 실행 검토가 필요하며, 검토자에게 이메일이 발송되었습니다. 해당 단말기는 얼굴 인식 규칙을 지원하지 않으므로 웹 단말기를 통해 로그인해 주세요. 로그인 검토를 취소하시겠습니까? %s로 전환되었습니다.",
|
||||||
"Owner": "관리자",
|
"Owner": "관리자",
|
||||||
|
"Page up: b\tPage down: n": "이전 페이지: b 다음 페이지: n",
|
||||||
|
"Page: %d, Count: %d, Total Page: %d, Total Count: %d": "페이지 번호: %d, 매 페이지 행 수: %d, 총 페이지 수: %d, 총 수량: %d",
|
||||||
"Paste": "붙여넣기",
|
"Paste": "붙여넣기",
|
||||||
"PauseSession": "이번 대화 일시 중지",
|
"PauseSession": "이번 대화 일시 중지",
|
||||||
"PermissionDenied": "권한 없음",
|
"PermissionDenied": "권한 없음",
|
||||||
"PermissionExpired": "권한이 만료되었습니다",
|
"PermissionExpired": "권한이 만료되었습니다",
|
||||||
"PermissionValid": "권한 유효",
|
"PermissionValid": "권한 유효",
|
||||||
|
"Platform": "플랫폼",
|
||||||
|
"Please waiting for the reviewers to confirm command `%s`, cancel by CTRL+C or CTRL+D.": "검토자를 기다려 주십시오, 명령 `%s`의 검토를 위해 CTRL+C 또는 CTRL+D를 눌러 취소하십시오.",
|
||||||
|
"Please waiting for the reviewers to confirm, enter q to exit. ": "검토자가 확인할 때까지 기다립니다. q를 눌러 로그인을 취소합니다.",
|
||||||
"PleaseInput": "입력해 주세요.",
|
"PleaseInput": "입력해 주세요.",
|
||||||
"PleaseInputVerifyCode": "입력한 인증 코드",
|
"PleaseInputVerifyCode": "입력한 인증 코드",
|
||||||
"PrimaryUser": "주 사용자",
|
"PrimaryUser": "주 사용자",
|
||||||
|
"Protocol": "프로토콜",
|
||||||
"ReadOnly": "읽기 전용",
|
"ReadOnly": "읽기 전용",
|
||||||
"Reconnect": "재연결",
|
"Reconnect": "재연결",
|
||||||
"Refresh": "새로 고침",
|
"Refresh": "새로 고침",
|
||||||
|
"Refresh done": "새로 고침이 완료되었습니다",
|
||||||
"Remove": "제거",
|
"Remove": "제거",
|
||||||
"RemoveShareUser": "귀하가 공유 세션에서 제거되었습니다",
|
"RemoveShareUser": "귀하가 공유 세션에서 제거되었습니다",
|
||||||
"RemoveUser": "사용자 제거",
|
"RemoveUser": "사용자 제거",
|
||||||
"Rename": "이름 변경",
|
"Rename": "이름 변경",
|
||||||
"ResumeSession": "이 세션을 복원하시겠습니까?",
|
"ResumeSession": "이 세션을 복원하시겠습니까?",
|
||||||
|
"Reuse SSH connections (%s@%s) [Number of connections: %d]": "SSH 연결 재사용 ( %s@%s ) [연결 수: %d]",
|
||||||
"RightArrow": "앞으로 화살표",
|
"RightArrow": "앞으로 화살표",
|
||||||
"Search": "검색",
|
"Search": "검색",
|
||||||
|
"Search: %s": "검색: %s",
|
||||||
|
"Select account exceed max retry times.": "계정 선택이 최대 재시도 횟수를 초과했습니다",
|
||||||
|
"Select protocol exceed max retry times.": "프로토콜 선택이 최대 재시도 횟수를 초과했습니다",
|
||||||
"SelectAction": "선택하십시오",
|
"SelectAction": "선택하십시오",
|
||||||
"SelectTheme": "주제를 선택하세요",
|
"SelectTheme": "주제를 선택하세요",
|
||||||
"Self": "나",
|
"Self": "나",
|
||||||
|
"Session max time reached, disconnect": "세션이 최대 연결 시간을 초과하여 연결이 끊겼습니다",
|
||||||
"SessionDetail": "대화 상세 내용",
|
"SessionDetail": "대화 상세 내용",
|
||||||
"SessionShare": "세션 공유",
|
"SessionShare": "세션 공유",
|
||||||
"Settings": "설정",
|
"Settings": "설정",
|
||||||
@@ -96,18 +158,32 @@
|
|||||||
"ShareUser": "공유 사용자",
|
"ShareUser": "공유 사용자",
|
||||||
"ShareUserHelpText": "사용자가 선택되지 않았습니다, 모든 사람이 참여할 수 있습니다",
|
"ShareUserHelpText": "사용자가 선택되지 않았습니다, 모든 사람이 참여할 수 있습니다",
|
||||||
"Size": "크기",
|
"Size": "크기",
|
||||||
|
"Start domain gateway failed %s": "데이터베이스 게이트웨이 시작 실패 %s \n최신 머신 및 노드 정보 새로 고침 \n명령 %s를 재검토해야 합니다. 계속하시겠습니까? [Y/N] \n검색, 예: /192.168 \n네트워크 불통 (네트워크에 도달할 수 없음) \n데이터베이스 없음 \n당신이 권한을 가진 데이터베이스 표시 \n%s@%s에 연결을 시작합니다 \n당신이 권한을 가진 Kubernetes 표시 \n새로 고침 완료 \n노드: [ ID.이름(자산 수) ] \n언어 전환 성공 \n프로토콜 선택이 최대 재시도 횟수를 초과했습니다 \n유휴 시간이 %d분을 초과하여 연결이 끊겼습니다 \n提示: g+노드ID를 입력하여 노드 아래의 호스트를 표시합니다. 예: g1",
|
||||||
|
"Switch language successfully": "언어 전환이 성공적으로 완료되었습니다",
|
||||||
|
"Switched to %s": "%s로 전환되었습니다",
|
||||||
"Sync": "동기화",
|
"Sync": "동기화",
|
||||||
"SyncUserPreferenceFailed": "동기화 설정 실패",
|
"SyncUserPreferenceFailed": "동기화 설정 실패",
|
||||||
"SyncUserPreferenceSuccess": "동기화 설정 성공",
|
"SyncUserPreferenceSuccess": "동기화 설정 성공",
|
||||||
|
"Terminal does not support protocol %s, please use web terminal to access": "해당 단말은 %s 프로토콜을 지원하지 않습니다. 웹 단말로 로그인하십시오",
|
||||||
"TerminalInstanceNotFound": "현재 탭의 터미널 인스턴스를 찾을 수 없습니다.",
|
"TerminalInstanceNotFound": "현재 탭의 터미널 인스턴스를 찾을 수 없습니다.",
|
||||||
"TerminalInstanceNotFoundForCurrentTab": "현재 탭에서 터미널 인스턴스를 찾을 수 없음",
|
"TerminalInstanceNotFoundForCurrentTab": "현재 탭에서 터미널 인스턴스를 찾을 수 없음",
|
||||||
|
"The command '%s' requires review. Continue or not [Y/n]?": "명령 %s는 재검토가 필요합니다, 계속하시겠습니까?[Y/N]",
|
||||||
|
"The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?[Y/N]": "귀하가 실행한 명령은 위험이 따릅니다, 경고 알림이 관리자에게 전송됩니다. 계속하시겠습니까?[Y/N]",
|
||||||
"TheCurrentTerminalInstanceWasNotFound": "현재 터미널 인스턴스를 찾을 수 없습니다.",
|
"TheCurrentTerminalInstanceWasNotFound": "현재 터미널 인스턴스를 찾을 수 없습니다.",
|
||||||
"Theme": "주제",
|
"Theme": "주제",
|
||||||
"ThemeColors": "테마 색상",
|
"ThemeColors": "테마 색상",
|
||||||
"ThemeConfig": "주제",
|
"ThemeConfig": "주제",
|
||||||
|
"Ticket Reviewers: %s": "작업 검토자: %s",
|
||||||
|
"Tips: Enter asset[%s] account ID": "提示:자산 [%s]의 계정 ID",
|
||||||
|
"Tips: Enter g+NodeID to display the host under the node, such as g1": "提示: g+노드 ID 입력하여 노드 하위 호스트 표시, 예: g1",
|
||||||
|
"Tips: Enter protocol ID": "提示: 프로토콜 ID 입력",
|
||||||
|
"Tips: To set a default language, go to Personal Settings → Preferences on Web": "팁: 기본 언어 설정이 필요하시면 웹에서 「개인 설정 → 선호 설정」으로 가십시오",
|
||||||
|
"Tips: switch language by ID (Current session only)": "提示: ID 입력하여 언어 전환",
|
||||||
"Transfer": "전송",
|
"Transfer": "전송",
|
||||||
"Type": "유형",
|
"Type": "유형",
|
||||||
"UnableToGenerateWebSocketURL": "WebSocket URL을 생성할 수 없습니다, 파라미터가 부족합니다",
|
"UnableToGenerateWebSocketURL": "WebSocket URL을 생성할 수 없습니다, 파라미터가 부족합니다",
|
||||||
|
"Unknown error code: %s, detail: %s": "알 수 없는 오류 코드: %s, 자세한 내용: %s",
|
||||||
|
"Unknown status": "알 수 없는 상태",
|
||||||
"UpArrow": "위쪽 화살표",
|
"UpArrow": "위쪽 화살표",
|
||||||
"Upload": "업로드",
|
"Upload": "업로드",
|
||||||
"UploadEnd": "업로드가 완료되었습니다. 후속 처리를 기다려 주십시오.",
|
"UploadEnd": "업로드가 완료되었습니다. 후속 처리를 기다려 주십시오.",
|
||||||
@@ -117,11 +193,35 @@
|
|||||||
"UploadTips": "파일을 여기로 드래그하거나 업로드를 클릭하세요",
|
"UploadTips": "파일을 여기로 드래그하거나 업로드를 클릭하세요",
|
||||||
"UploadTitle": "파일 업로드",
|
"UploadTitle": "파일 업로드",
|
||||||
"User": "사용자",
|
"User": "사용자",
|
||||||
|
"Username": "사용자 이름",
|
||||||
"UsingRegularExpressions": "정규 표현식 사용",
|
"UsingRegularExpressions": "정규 표현식 사용",
|
||||||
"VerifyCode": "인증 코드",
|
"VerifyCode": "인증 코드",
|
||||||
"WaitFileTransfer": "파일 전송 완료 대기",
|
"WaitFileTransfer": "파일 전송 완료 대기",
|
||||||
"Warning": "경고",
|
"Warning": "경고",
|
||||||
"WebSocketClosed": "WebSocket이 닫혔습니다",
|
"WebSocketClosed": "WebSocket이 닫혔습니다",
|
||||||
"WebSocketConnectionIsClosedHelpText": "WebSocket 연결이 종료되었습니다, 페이지를 새로 고치거나 다시 연결하세요.",
|
"WebSocketConnectionIsClosedHelpText": "WebSocket 연결이 종료되었습니다, 페이지를 새로 고치거나 다시 연결하세요.",
|
||||||
"Writable": "작성 가능"
|
"Welcome to use JumpServer open source fortress system": "JumpServer 오픈 소스 방화벽 시스템에 오신 것을 환영합니다",
|
||||||
|
"Writable": "작성 가능",
|
||||||
|
"You don't have permission login %s": "%s에 로그인할 권한이 없습니다",
|
||||||
|
"You get auth token failed": "인증 토큰을 받는 데 실패했습니다",
|
||||||
|
"display the assets you have permission": "당신이 권한을 가진 자산을 표시",
|
||||||
|
"display the databases that you have permission": "당신이 권한을 가진 데이터베이스 표시",
|
||||||
|
"display the hosts that you have permission": "귀하가 권한이 있는 호스트를 표시합니다",
|
||||||
|
"display the kubernetes that you have permission": "당신이 권한을 가진 Kubernetes 표시",
|
||||||
|
"display the node that you have permission": "당신이 권한을 가진 노드를 표시",
|
||||||
|
"exit": "로그아웃",
|
||||||
|
"get connect token err": "연결 토큰을 가져오는 데 오류가 발생했습니다. <br> %s 노드에 자산이 없습니다. <br> 인증 토큰을 가져오지 못했습니다. <br> 주소는 <br> 고유한 자산이어야 합니다: %s <br> ID: <br> %d) {{.GreenBoldColor}}%s{{.ColorEnd}}를 입력하여 %s.%s을(를) 진행하세요. <br> 자산의 로그인 취소 또는 3회 재시도를 초과했습니다. <br> 티켓 검토자: %s <br> Core API에서 오류가 발생했습니다. <br> 힌트: 프로토콜 ID를 입력하세요. <br> Kubernetes가 없습니다. <br> 검토자가 명령 `%s`를 검토할 때까지 기다리세요. 종료하려면 CTRL+C 또는 CTRL+D를 누르십시오. <br> JumpServer 오픈소스 방화벽 시스템에 오신 것을 환영합니다. <br> 이 터미널은 얼굴 인식 인증을 지원하지 않으므로 웹 터미널을 통해 로그인하시기 바랍니다.",
|
||||||
|
"have no permission to download file": "파일 다운로드 권한 없음",
|
||||||
|
"have no permission to upload file": "파일 업로드 권한이 없음",
|
||||||
|
"i/o timeout": "네트워크가 연결되지 않음 (연결 시간 초과)",
|
||||||
|
"language switch": "언어 전환",
|
||||||
|
"network is unreachable": "네트워크 연결 불가(네트워크 도달 불가)",
|
||||||
|
"not found matched username %s": "일치하는 사용자 이름 %s를 찾을 수 없습니다.",
|
||||||
|
"part IP, Hostname, Comment": "부분 IP, 호스트 이름, 메모",
|
||||||
|
"part IP,, Hostname, Comment": "/ + IP, 호스트명, 비고",
|
||||||
|
"print help": "도움말 표시",
|
||||||
|
"refresh your assets and nodes": "최신 머신 및 노드 정보 새로 고침",
|
||||||
|
"select one asset to login": "하나의 자산을 선택하여 로그인합니다",
|
||||||
|
"to search login if unique": "로그인 검색(유일한 경우)",
|
||||||
|
"to search, such as: /192.168": "검색, 예: /192.168"
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,45 @@
|
|||||||
{
|
{
|
||||||
|
"\t%2d) Enter {{.GreenBoldColor}}%s{{.ColorEnd}} to %s.%s": "%d) Digite {{.GreenBoldColor}}%s{{.ColorEnd}} para %s.%s",
|
||||||
|
"%s approved": "%s Revisão aprovada.",
|
||||||
|
"%s node has no assets": "O nó %s não possui ativos",
|
||||||
|
"%s protocol client not installed.": "O cliente do protocolo %s não está instalado",
|
||||||
|
"%s rejected": "Rejeição da auditoria",
|
||||||
|
"ACL reject": "O login foi negado desta vez, devido a uma limitação da política de controle de acesso",
|
||||||
|
"Account <%s> and asset <%s> protocol are inconsistent.": "O usuário do sistema <%s> e o ativo <%s> têm um acordo inconsistente",
|
||||||
"ActionPerm": "Permissão de Ação",
|
"ActionPerm": "Permissão de Ação",
|
||||||
|
"Address": "O endereço",
|
||||||
"AlreadyExistsPleaseRename": "o arquivo já existe, por favor renomeie",
|
"AlreadyExistsPleaseRename": "o arquivo já existe, por favor renomeie",
|
||||||
|
"Announcement: ": "Anúncio:",
|
||||||
|
"Authentication failed": "Falha de autenticação (nome de usuário ou senha incorretos)",
|
||||||
"AvailableShortcutKey": "Atalhos disponíveis",
|
"AvailableShortcutKey": "Atalhos disponíveis",
|
||||||
"Back": "Voltar",
|
"Back": "Voltar",
|
||||||
|
"Back: B/b": "Retorno: B/b",
|
||||||
"Cancel": "Cancelar",
|
"Cancel": "Cancelar",
|
||||||
|
"Cancel confirm": "Cancelar revisão de login",
|
||||||
|
"Cancel to login asset or max 3 retry": "Cancela o login no ativo ou atinge 3 tentativas",
|
||||||
"CancelFileUpload": "Cancelar upload de arquivo",
|
"CancelFileUpload": "Cancelar upload de arquivo",
|
||||||
"CaseSensitive": "Diferenciar maiúsculas de minúsculas",
|
"CaseSensitive": "Diferenciar maiúsculas de minúsculas",
|
||||||
"Clone Connect": "Copiar janela",
|
"Clone Connect": "Copiar janela",
|
||||||
"Close All Tabs": "Fechar tudo",
|
"Close All Tabs": "Fechar tudo",
|
||||||
"Close Current Tab": "Fechar a atual",
|
"Close Current Tab": "Fechar a atual",
|
||||||
|
"Command `%s` is forbidden": "O comando `%s` está proibido ...",
|
||||||
|
"Comment": "Observações",
|
||||||
"Confirm": "Confirmar",
|
"Confirm": "Confirmar",
|
||||||
"ConfirmBtn": "Confirmar",
|
"ConfirmBtn": "Confirmar",
|
||||||
"ConfirmDelete": "Você tem certeza de que deseja excluir este arquivo?",
|
"ConfirmDelete": "Você tem certeza de que deseja excluir este arquivo?",
|
||||||
"Connect": "Conectar",
|
"Connect": "Conectar",
|
||||||
|
"Connect idle more than %d minutes, disconnect": "Tempo ocioso superior a %d minutos, conexão encerrada",
|
||||||
|
"Connect with api server failed": "Falha ao conectar ao serviço API",
|
||||||
|
"Connecting to %s@%s": "Iniciando conexão com %s@%s",
|
||||||
|
"Connecting to Database %s": "Iniciando a conexão com o banco de dados %s",
|
||||||
|
"Connecting to Kubernetes %s": "Iniciando conexão com Kubernetes %s",
|
||||||
|
"Connecting to Kubernetes %s container %s": "Iniciando conexão com o Kubernetes %s container %s",
|
||||||
|
"Connection refused": "Rede indisponível (conexão recusada)",
|
||||||
"CopyLink": "Copiar link e código",
|
"CopyLink": "Copiar link e código",
|
||||||
"CopyShareURLSuccess": "Cópia de endereço compartilhado bem sucedida",
|
"CopyShareURLSuccess": "Cópia de endereço compartilhado bem sucedida",
|
||||||
|
"Core API failed": "Ocorreu um erro na API Core",
|
||||||
|
"Could copy website URL to notify reviewers: %s": "Endereço de auditoria copiável, notificar auditor: %s",
|
||||||
|
"Create k8s client err: %s": "Erro ao criar cliente k8s: %s",
|
||||||
"CreateFolder": "criar pasta",
|
"CreateFolder": "criar pasta",
|
||||||
"CreateLink": "Criar link",
|
"CreateLink": "Criar link",
|
||||||
"CreateSuccess": "Criado com sucesso",
|
"CreateSuccess": "Criado com sucesso",
|
||||||
@@ -27,10 +52,14 @@
|
|||||||
"DownloadProgress": "Progresso do download",
|
"DownloadProgress": "Progresso do download",
|
||||||
"DownloadSuccess": "Download bem-sucedido",
|
"DownloadSuccess": "Download bem-sucedido",
|
||||||
"Downloading": "Baixando",
|
"Downloading": "Baixando",
|
||||||
|
"Dynamic": "Conta dinâmica",
|
||||||
"EndFileTransfer": "Transferência de arquivo concluída",
|
"EndFileTransfer": "Transferência de arquivo concluída",
|
||||||
|
"Enter ID number directly login, multiple search use // + field, such as: //16": "Dica: insira o ID do ativo para login direto, a pesquisa secundária utiliza // + campo, como: //192",
|
||||||
"ExceedTransferSize": "Excede o tamanho máximo de transferência",
|
"ExceedTransferSize": "Excede o tamanho máximo de transferência",
|
||||||
"Expand": "Expandir",
|
"Expand": "Expandir",
|
||||||
"ExpiredTime": "Prazo de validade",
|
"ExpiredTime": "Prazo de validade",
|
||||||
|
"Face ACL is not supported yet. Please use the WebTerminal to connect the asset.": "Este terminal não suporta regras de acesso por reconhecimento facial, por favor use o terminal web para fazer login",
|
||||||
|
"Face verification is not supported yet. Please use the WebTerminal to connect the asset.": "Este terminal não suporta autenticação por reconhecimento facial, por favor, utilize o terminal web para login.",
|
||||||
"FailedCreateConnection": "Falha ao criar conexão",
|
"FailedCreateConnection": "Falha ao criar conexão",
|
||||||
"FileAlreadyExists": "arquivo já existe",
|
"FileAlreadyExists": "arquivo já existe",
|
||||||
"FileListError": "Falha ao obter informações da lista de arquivos",
|
"FileListError": "Falha ao obter informações da lista de arquivos",
|
||||||
@@ -41,10 +70,15 @@
|
|||||||
"FileUploadInterrupted": "Upload de arquivo interrompido",
|
"FileUploadInterrupted": "Upload de arquivo interrompido",
|
||||||
"Format": "Formato",
|
"Format": "Formato",
|
||||||
"General": "Geral",
|
"General": "Geral",
|
||||||
|
"Get auth password failed": "Falha ao obter o token de autenticação",
|
||||||
"GetFileManagerTokenTimeOut": "Tempo limite na obtenção do Token de gerenciamento de arquivo",
|
"GetFileManagerTokenTimeOut": "Tempo limite na obtenção do Token de gerenciamento de arquivo",
|
||||||
"GetShareUser": "Digite o nome de usuário",
|
"GetShareUser": "Digite o nome de usuário",
|
||||||
|
"HandleTask does not support protocol %s, please use web terminal to access": "Este terminal não suporta o protocolo %s, por favor utilize o terminal web para logar",
|
||||||
|
"Hostname": "Nome do host",
|
||||||
"Hotkeys": "Atalhos",
|
"Hotkeys": "Atalhos",
|
||||||
|
"ID": "ID",
|
||||||
"InputVerifyCode": "Por favor, insira o código de verificação",
|
"InputVerifyCode": "Por favor, insira o código de verificação",
|
||||||
|
"Invalid ID": "ID inválido",
|
||||||
"JoinShare": "Junte-se ao compartilhamento",
|
"JoinShare": "Junte-se ao compartilhamento",
|
||||||
"JoinedWithSuccess": "Adicionado com sucesso",
|
"JoinedWithSuccess": "Adicionado com sucesso",
|
||||||
"KubernetesManagement": "Kubernetes gerenciar",
|
"KubernetesManagement": "Kubernetes gerenciar",
|
||||||
@@ -53,41 +87,69 @@
|
|||||||
"LeftArrow": "Seta para trás",
|
"LeftArrow": "Seta para trás",
|
||||||
"LinkAddr": "Endereço do link",
|
"LinkAddr": "Endereço do link",
|
||||||
"List": "Lista",
|
"List": "Lista",
|
||||||
|
"Manual": "Conta manual",
|
||||||
"MatchWholeWords": "Correspondência exata",
|
"MatchWholeWords": "Correspondência exata",
|
||||||
"Minute": "minutos",
|
"Minute": "minutos",
|
||||||
"Minutes": "minutos",
|
"Minutes": "minutos",
|
||||||
|
"Must be auto login account for %s": "Deve ser uma conta de login automático %s",
|
||||||
|
"Must be unique account for %s": "Deve ser uma conta única %s",
|
||||||
|
"Must be unique asset for %s": "deve ser um ativo único %s",
|
||||||
"MustOneFile": "Só pode escolher um arquivo",
|
"MustOneFile": "Só pode escolher um arquivo",
|
||||||
"MustSelectOneFile": "É necessário selecionar um arquivo",
|
"MustSelectOneFile": "É necessário selecionar um arquivo",
|
||||||
"Name": "Nome",
|
"Name": "Nome",
|
||||||
|
"Need ACL review, continue? (y/n): ": "precisa de auditoria, continuar? (s/n):",
|
||||||
|
"Need ticket confirm to execute command, already send email to the reviewers": "A execução da ordem de revisão requer um comando, um e-mail foi enviado ao revisor",
|
||||||
|
"Need ticket confirm to login, already send email to the reviewers": "Revisão de login de serviço necessário, auditor notificado por e-mail",
|
||||||
"NewFolder": "Criar nova pasta",
|
"NewFolder": "Criar nova pasta",
|
||||||
|
"No Account found.": "Nenhuma conta encontrada",
|
||||||
|
"No Assets": "Nenhum ativo",
|
||||||
|
"No Databases": "Sem banco de dados",
|
||||||
|
"No found asset": "Ativo correspondente não encontrado %s",
|
||||||
|
"No kubernetes": "Não há kubernetes",
|
||||||
|
"No protocol found.": "Nenhum protocolo",
|
||||||
|
"No route to host": "Rede indisponível (roteador inoperante)",
|
||||||
"NoActiveTerminalTabFound": "Não foi encontrada a guia do terminal ativo",
|
"NoActiveTerminalTabFound": "Não foi encontrada a guia do terminal ativo",
|
||||||
"NoData": "Sem dados",
|
"NoData": "Sem dados",
|
||||||
"NoLink": "Sem endereço",
|
"NoLink": "Sem endereço",
|
||||||
"NoRunningTerminalFound": "Terminal em execução não encontrado",
|
"NoRunningTerminalFound": "Terminal em execução não encontrado",
|
||||||
|
"Node: [ ID.Name(Asset amount) ]": "Nós: [ ID.Nome(Quantidade de ativos) ]",
|
||||||
"OnlineUser": "Usuários online",
|
"OnlineUser": "Usuários online",
|
||||||
"OperationSuccessful": "Ação bem-sucedida",
|
"OperationSuccessful": "Ação bem-sucedida",
|
||||||
|
"Organization": "Organização",
|
||||||
"Owner": "Administrador",
|
"Owner": "Administrador",
|
||||||
|
"Page up: b\tPage down: n": "Página anterior: b Próxima página: n",
|
||||||
|
"Page: %d, Count: %d, Total Page: %d, Total Count: %d": "Número da página: %d, linhas por página: %d, total de páginas: %d, quantidade total: %d",
|
||||||
"Paste": "Colar",
|
"Paste": "Colar",
|
||||||
"PauseSession": "Pausar esta sessão",
|
"PauseSession": "Pausar esta sessão",
|
||||||
"PermissionDenied": "Sem permissão",
|
"PermissionDenied": "Sem permissão",
|
||||||
"PermissionExpired": "Permissão expirada",
|
"PermissionExpired": "Permissão expirada",
|
||||||
"PermissionValid": "Permissão válida",
|
"PermissionValid": "Permissão válida",
|
||||||
|
"Platform": "Plataforma",
|
||||||
|
"Please waiting for the reviewers to confirm command `%s`, cancel by CTRL+C or CTRL+D.": "Aguarde a revisão do revisor do comando `%s`, cancele pressionando CTRL+C ou CTRL+D.",
|
||||||
|
"Please waiting for the reviewers to confirm, enter q to exit. ": "Aguardando a confirmação de revisão do avaliador, pressione q e enter para cancelar o login.",
|
||||||
"PleaseInput": "Por favor, insira.",
|
"PleaseInput": "Por favor, insira.",
|
||||||
"PleaseInputVerifyCode": "Por favor, insira o código de verificação",
|
"PleaseInputVerifyCode": "Por favor, insira o código de verificação",
|
||||||
"PrimaryUser": "Usuário principal",
|
"PrimaryUser": "Usuário principal",
|
||||||
|
"Protocol": "Protocolo",
|
||||||
"ReadOnly": "somente leitura",
|
"ReadOnly": "somente leitura",
|
||||||
"Reconnect": "Reconectar",
|
"Reconnect": "Reconectar",
|
||||||
"Refresh": "Atualizar",
|
"Refresh": "Atualizar",
|
||||||
|
"Refresh done": "Atualização concluída",
|
||||||
"Remove": "Remover",
|
"Remove": "Remover",
|
||||||
"RemoveShareUser": "Você foi removido da sessão compartilhada",
|
"RemoveShareUser": "Você foi removido da sessão compartilhada",
|
||||||
"RemoveUser": "Remover usuário",
|
"RemoveUser": "Remover usuário",
|
||||||
"Rename": "Renomear",
|
"Rename": "Renomear",
|
||||||
"ResumeSession": "Restaurar esta sessão",
|
"ResumeSession": "Restaurar esta sessão",
|
||||||
|
"Reuse SSH connections (%s@%s) [Number of connections: %d]": "Reutilizando conexão SSH (%s@%s) [Número de conexões: %d]",
|
||||||
"RightArrow": "Seta para frente",
|
"RightArrow": "Seta para frente",
|
||||||
"Search": "Pesquisar",
|
"Search": "Pesquisar",
|
||||||
|
"Search: %s": "Pesquisar: %s",
|
||||||
|
"Select account exceed max retry times.": "Número de contas selecionadas excede o número máximo de tentativas",
|
||||||
|
"Select protocol exceed max retry times.": "Número máximo de tentativas de protocolo excedido",
|
||||||
"SelectAction": "Por favor, selecione",
|
"SelectAction": "Por favor, selecione",
|
||||||
"SelectTheme": "Por favor, selecione um tema",
|
"SelectTheme": "Por favor, selecione um tema",
|
||||||
"Self": "Eu",
|
"Self": "Eu",
|
||||||
|
"Session max time reached, disconnect": "A sessão excedeu o tempo máximo de conexão, desconectando",
|
||||||
"SessionDetail": "Detalhes da conversa",
|
"SessionDetail": "Detalhes da conversa",
|
||||||
"SessionShare": "Compartilhamento de conversa",
|
"SessionShare": "Compartilhamento de conversa",
|
||||||
"Settings": "Configurações",
|
"Settings": "Configurações",
|
||||||
@@ -96,18 +158,32 @@
|
|||||||
"ShareUser": "usuários de compartilhamento",
|
"ShareUser": "usuários de compartilhamento",
|
||||||
"ShareUserHelpText": "Sem usuário selecionado, permitindo que todos se juntem",
|
"ShareUserHelpText": "Sem usuário selecionado, permitindo que todos se juntem",
|
||||||
"Size": "Tamanho",
|
"Size": "Tamanho",
|
||||||
|
"Start domain gateway failed %s": "Falha ao iniciar o gateway do banco de dados %s",
|
||||||
|
"Switch language successfully": "Mudança de idioma bem-sucedida",
|
||||||
|
"Switched to %s": "Alterado para %s",
|
||||||
"Sync": "Sincronizar",
|
"Sync": "Sincronizar",
|
||||||
"SyncUserPreferenceFailed": "Falha na configuração de sincronização",
|
"SyncUserPreferenceFailed": "Falha na configuração de sincronização",
|
||||||
"SyncUserPreferenceSuccess": "Configurações sincronizadas com sucesso",
|
"SyncUserPreferenceSuccess": "Configurações sincronizadas com sucesso",
|
||||||
|
"Terminal does not support protocol %s, please use web terminal to access": "Este terminal não suporta o protocolo %s, por favor, use o terminal web para login",
|
||||||
"TerminalInstanceNotFound": "Não foi encontrada uma instância de terminal para a aba atual",
|
"TerminalInstanceNotFound": "Não foi encontrada uma instância de terminal para a aba atual",
|
||||||
"TerminalInstanceNotFoundForCurrentTab": "A guia atual não encontrou a instância do terminal",
|
"TerminalInstanceNotFoundForCurrentTab": "A guia atual não encontrou a instância do terminal",
|
||||||
|
"The command '%s' requires review. Continue or not [Y/n]?": "O comando %s requer revisão, deseja continuar? [Y/N]",
|
||||||
|
"The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?[Y/N]": "O comando que você executou possui riscos, uma notificação de alerta será enviada ao administrador. Deseja continuar? [S/N]",
|
||||||
"TheCurrentTerminalInstanceWasNotFound": "Instância do terminal atual não encontrada",
|
"TheCurrentTerminalInstanceWasNotFound": "Instância do terminal atual não encontrada",
|
||||||
"Theme": "Tema",
|
"Theme": "Tema",
|
||||||
"ThemeColors": "Cor do tema",
|
"ThemeColors": "Cor do tema",
|
||||||
"ThemeConfig": "Tema",
|
"ThemeConfig": "Tema",
|
||||||
|
"Ticket Reviewers: %s": "Revisor do ticket: %s",
|
||||||
|
"Tips: Enter asset[%s] account ID": "Dica: Insira o ID da conta do ativo [%s]",
|
||||||
|
"Tips: Enter g+NodeID to display the host under the node, such as g1": "Dica: Digite g+ID do nó para exibir os hosts abaixo do nó, por exemplo: g1",
|
||||||
|
"Tips: Enter protocol ID": "Dica: insira o ID do protocolo",
|
||||||
|
"Tips: To set a default language, go to Personal Settings → Preferences on Web": "Dica: para definir a língua padrão, por favor, vá para a versão web em \"Configurações pessoais → Preferências\"",
|
||||||
|
"Tips: switch language by ID (Current session only)": "Dica: digite ID para mudar de idioma",
|
||||||
"Transfer": "Transmissão",
|
"Transfer": "Transmissão",
|
||||||
"Type": "Tipo",
|
"Type": "Tipo",
|
||||||
"UnableToGenerateWebSocketURL": "Não é possível gerar a URL do WebSocket, faltando parâmetros",
|
"UnableToGenerateWebSocketURL": "Não é possível gerar a URL do WebSocket, faltando parâmetros",
|
||||||
|
"Unknown error code: %s, detail: %s": "Código de erro desconhecido: %s, detalhes: %s",
|
||||||
|
"Unknown status": "Estado desconhecido",
|
||||||
"UpArrow": "Seta para cima",
|
"UpArrow": "Seta para cima",
|
||||||
"Upload": "Upload",
|
"Upload": "Upload",
|
||||||
"UploadEnd": "O upload foi concluído, aguarde o processamento subsequente",
|
"UploadEnd": "O upload foi concluído, aguarde o processamento subsequente",
|
||||||
@@ -117,11 +193,35 @@
|
|||||||
"UploadTips": "Arraste o arquivo para cá ou clique para fazer o upload",
|
"UploadTips": "Arraste o arquivo para cá ou clique para fazer o upload",
|
||||||
"UploadTitle": "Enviar arquivo",
|
"UploadTitle": "Enviar arquivo",
|
||||||
"User": "Usuário",
|
"User": "Usuário",
|
||||||
|
"Username": "Nome de usuário",
|
||||||
"UsingRegularExpressions": "Usar expressão regular",
|
"UsingRegularExpressions": "Usar expressão regular",
|
||||||
"VerifyCode": "código de verificação",
|
"VerifyCode": "código de verificação",
|
||||||
"WaitFileTransfer": "Aguarde o fim da transferência do arquivo",
|
"WaitFileTransfer": "Aguarde o fim da transferência do arquivo",
|
||||||
"Warning": "Aviso",
|
"Warning": "Aviso",
|
||||||
"WebSocketClosed": "WebSocket foi fechado",
|
"WebSocketClosed": "WebSocket foi fechado",
|
||||||
"WebSocketConnectionIsClosedHelpText": "Conexão do WebSocket fechada, por favor, atualize a página ou reconecte-se.",
|
"WebSocketConnectionIsClosedHelpText": "Conexão do WebSocket fechada, por favor, atualize a página ou reconecte-se.",
|
||||||
"Writable": "pode escrever"
|
"Welcome to use JumpServer open source fortress system": "Bem-vindo ao sistema de bastião de código aberto JumpServer",
|
||||||
|
"Writable": "pode escrever",
|
||||||
|
"You don't have permission login %s": "Você não tem permissão para acessar %s",
|
||||||
|
"You get auth token failed": "Falha ao obter o token de autenticação",
|
||||||
|
"display the assets you have permission": "Mostrar os ativos aos quais você tem permissão",
|
||||||
|
"display the databases that you have permission": "Mostrar os bancos de dados aos quais você tem acesso",
|
||||||
|
"display the hosts that you have permission": "Mostrar os hosts aos quais você tem acesso",
|
||||||
|
"display the kubernetes that you have permission": "Mostrar seus Kubernetes autorizados",
|
||||||
|
"display the node that you have permission": "Mostrar os nós aos quais você tem permissão",
|
||||||
|
"exit": "Sair",
|
||||||
|
"get connect token err": "Erro ao obter o token de conexão",
|
||||||
|
"have no permission to download file": "Sem permissão para baixar o arquivo",
|
||||||
|
"have no permission to upload file": "Sem permissão para enviar arquivos",
|
||||||
|
"i/o timeout": "Rede indisponível (tempo de conexão excedido)",
|
||||||
|
"language switch": "Trocar idioma",
|
||||||
|
"network is unreachable": "Rede indisponível (rede inatingível)",
|
||||||
|
"not found matched username %s": "Não foi encontrado um nome de usuário correspondente %s",
|
||||||
|
"part IP, Hostname, Comment": "Parte do IP, nome do host, observações",
|
||||||
|
"part IP,, Hostname, Comment": "/ + IP, nome do host, observações",
|
||||||
|
"print help": "Mostrar ajuda",
|
||||||
|
"refresh your assets and nodes": "Atualizando as informações mais recentes sobre máquinas e nós",
|
||||||
|
"select one asset to login": "Selecione um dos ativos para fazer o login",
|
||||||
|
"to search login if unique": "Buscar login (se único)",
|
||||||
|
"to search, such as: /192.168": "Buscar, por exemplo: /192.168"
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,47 @@
|
|||||||
{
|
{
|
||||||
"ActionPerm": "Права доступа",
|
"\t%2d) Enter {{.GreenBoldColor}}%s{{.ColorEnd}} to %s.%s": "\t%d) Введите {{.GreenBoldColor}}%s{{.ColorEnd}} чтобы %s.%s",
|
||||||
"AlreadyExistsPleaseRename": "Создать папку",
|
"%s approved": "%s одобрено",
|
||||||
|
"%s node has no assets": "В папке %s нет активов",
|
||||||
|
"%s protocol client not installed.": "Клиент протокола %s не установлен",
|
||||||
|
"%s rejected": "%s отклонено",
|
||||||
|
"ACL reject": "Вход запрещен: ограничение политики контроля доступа",
|
||||||
|
"Account <%s> and asset <%s> protocol are inconsistent.": "Протокол системного пользователя <%s> и актива <%s> не совпадают",
|
||||||
|
"ActionPerm": "Разрешения на действия",
|
||||||
|
"Address": "Адрес",
|
||||||
|
"AlreadyExistsPleaseRename": "Файл уже существует, пожалуйста, переименуйте его",
|
||||||
|
"Announcement: ": "Объявление:",
|
||||||
|
"Authentication failed": "Ошибка аутентификации: неверное имя пользователя или пароль",
|
||||||
"AvailableShortcutKey": "Доступные горячие клавиши",
|
"AvailableShortcutKey": "Доступные горячие клавиши",
|
||||||
"Back": "Вернуться",
|
"Back": "Назад",
|
||||||
|
"Back: B/b": "Назад: B/b",
|
||||||
"Cancel": "Отмена",
|
"Cancel": "Отмена",
|
||||||
|
"Cancel confirm": "Отмена подтверждения входа",
|
||||||
|
"Cancel to login asset or max 3 retry": "Вход на актив отменён или превышен лимит 3 попыток",
|
||||||
"CancelFileUpload": "Отменить передачу файла",
|
"CancelFileUpload": "Отменить передачу файла",
|
||||||
"CaseSensitive": "Учитывать регистрар",
|
"CaseSensitive": "Учитывать регистр",
|
||||||
"Clone Connect": "Клонировать окно",
|
"Clone Connect": "Клонировать окно",
|
||||||
"Close All Tabs": "Закрыть все вкладки",
|
"Close All Tabs": "Закрыть все вкладки",
|
||||||
"Close Current Tab": "Закрыть эту вкладку",
|
"Close Current Tab": "Закрыть эту вкладку",
|
||||||
|
"Command `%s` is forbidden": "Команда %s запрещена",
|
||||||
|
"Comment": "Примечание",
|
||||||
"Confirm": "Подтвердить",
|
"Confirm": "Подтвердить",
|
||||||
"ConfirmBtn": "Подтвердить",
|
"ConfirmBtn": "Подтвердить",
|
||||||
"ConfirmDelete": "Вы уверены, что хотите удалить этот файл?",
|
"ConfirmDelete": "Вы действительно хотите удалить этот файл?",
|
||||||
"Connect": "Подключение",
|
"Connect": "Подключение",
|
||||||
"CopyLink": "Скопировать ссылку и код подтверждения",
|
"Connect idle more than %d minutes, disconnect": "Превышено время простоя (%d минут). Соединение разорвано",
|
||||||
|
"Connect with api server failed": "Не удалось подключиться к API-серверу",
|
||||||
|
"Connecting to %s@%s": "Подключение к %s@%s…",
|
||||||
|
"Connecting to Database %s": "Подключение к базе данных %s...",
|
||||||
|
"Connecting to Kubernetes %s": "Подключение к Kubernetes %s...",
|
||||||
|
"Connecting to Kubernetes %s container %s": "Подключение к Kubernetes %s, контейнер %s…",
|
||||||
|
"Connection refused": "Нет соединения (соединение отклонено)",
|
||||||
|
"CopyLink": "Копировать ссылку и код",
|
||||||
"CopyShareURLSuccess": "URL общего доступа успешно скопирован",
|
"CopyShareURLSuccess": "URL общего доступа успешно скопирован",
|
||||||
"CreateFolder": "Пользователи для分享",
|
"Core API failed": "Ошибка Core API",
|
||||||
"CreateLink": "Создать ссылку",
|
"Could copy website URL to notify reviewers: %s": "Можно скопировать URL для проверки и уведомить проверяющего: %s",
|
||||||
|
"Create k8s client err: %s": "Ошибка создания клиента k8s: %s",
|
||||||
|
"CreateFolder": "Создать папку",
|
||||||
|
"CreateLink": "Создать ссылку для общего доступа",
|
||||||
"CreateSuccess": "Успешно создано",
|
"CreateSuccess": "Успешно создано",
|
||||||
"CurrentUser": "Текущий пользователь",
|
"CurrentUser": "Текущий пользователь",
|
||||||
"Custom Setting": "Пользовательские настройки",
|
"Custom Setting": "Пользовательские настройки",
|
||||||
@@ -24,104 +49,179 @@
|
|||||||
"Delete": "Удалить",
|
"Delete": "Удалить",
|
||||||
"DownArrow": "Стрелка вниз",
|
"DownArrow": "Стрелка вниз",
|
||||||
"Download": "Скачать",
|
"Download": "Скачать",
|
||||||
"DownloadProgress": "Прогресс загрузки",
|
"DownloadProgress": "Прогресс скачивания",
|
||||||
"DownloadSuccess": "Успешное скачивание",
|
"DownloadSuccess": "Успешное скачивание",
|
||||||
"Downloading": "Ведётся загрузка",
|
"Downloading": "Скачивается",
|
||||||
|
"Dynamic": "Своя учетная запись",
|
||||||
"EndFileTransfer": "Передача файла завершена",
|
"EndFileTransfer": "Передача файла завершена",
|
||||||
|
"Enter ID number directly login, multiple search use // + field, such as: //16": "Подсказка: введите ID ресурса для прямого входа, для расширенного поиска используйте // + значение, например: //192",
|
||||||
"ExceedTransferSize": "Превышен максимальный размер передачи",
|
"ExceedTransferSize": "Превышен максимальный размер передачи",
|
||||||
"Expand": "Развернуть",
|
"Expand": "Развернуть",
|
||||||
"ExpiredTime": "Срок действия",
|
"ExpiredTime": "Срок действия",
|
||||||
"FailedCreateConnection": "Ошибка создания соединения",
|
"Face ACL is not supported yet. Please use the WebTerminal to connect the asset.": "Этот терминал пока не поддерживает правила доступа по лицу, пожалуйста, войдите через веб-терминал",
|
||||||
"FileAlreadyExists": "Только для чтения",
|
"Face verification is not supported yet. Please use the WebTerminal to connect the asset.": "Этот терминал не поддерживает аутентификацию по лицу, пожалуйста, войдите через веб-терминал",
|
||||||
"FileListError": "Не удалось получить информацию о списке файлов",
|
"FailedCreateConnection": "Не удалось создать соединение",
|
||||||
|
"FileAlreadyExists": "Файл уже существует",
|
||||||
|
"FileListError": "Не удалось получить список файлов",
|
||||||
"FileManagement": "Управление файлами",
|
"FileManagement": "Управление файлами",
|
||||||
"FileManagementExpired": "Текущая сессия управления файлами истекла.",
|
"FileManagementExpired": "Текущая сессия управления файлами истекла.",
|
||||||
"FileManagerTokenTimeout": "Получить токен файлового менеджера, время ожидания истекло",
|
"FileManagerTokenTimeout": "Тайм-аут при получении токена файлового менеджера",
|
||||||
"FileTransferInterrupted": "Передача файлов прервана",
|
"FileTransferInterrupted": "Передача файлов прервана",
|
||||||
"FileUploadInterrupted": "Передача файла прервана",
|
"FileUploadInterrupted": "Загрузка файла прервана",
|
||||||
"Format": "Формат",
|
"Format": "Формат",
|
||||||
"General": "Универсальный",
|
"General": "Основной",
|
||||||
"GetFileManagerTokenTimeOut": "Таймаут получения токена для управления файлами",
|
"Get auth password failed": "Не удалось получить пароль аутентификации",
|
||||||
|
"GetFileManagerTokenTimeOut": "Тайм-аут при получении токена управления файлами",
|
||||||
"GetShareUser": "Введите имя пользователя",
|
"GetShareUser": "Введите имя пользователя",
|
||||||
|
"HandleTask does not support protocol %s, please use web terminal to access": "Протокол %s не поддерживается этим терминалом. Используйте веб-терминал",
|
||||||
|
"Hostname": "Имя хоста",
|
||||||
"Hotkeys": "Горячие клавиши",
|
"Hotkeys": "Горячие клавиши",
|
||||||
|
"ID": "ID",
|
||||||
"InputVerifyCode": "Введите код подтверждения",
|
"InputVerifyCode": "Введите код подтверждения",
|
||||||
"JoinShare": "Присоединиться к общей сессии",
|
"Invalid ID": "Неверный ID",
|
||||||
|
"JoinShare": "Присоединился к общей сессии",
|
||||||
"JoinedWithSuccess": "Успешно присоединился",
|
"JoinedWithSuccess": "Успешно присоединился",
|
||||||
"KubernetesManagement": "Управление Kubernetes",
|
"KubernetesManagement": "Управление Kubernetes",
|
||||||
"LastModified": "Последнее время изменения",
|
"LastModified": "Последнее время изменения",
|
||||||
"LeaveShare": "Покинуть общую сессию",
|
"LeaveShare": "Покинул общую сессию",
|
||||||
"LeftArrow": "Стрелка влево",
|
"LeftArrow": "Стрелка влево",
|
||||||
"LinkAddr": "Адрес ссылки",
|
"LinkAddr": "Адрес ссылки",
|
||||||
"List": "Список",
|
"List": "Список",
|
||||||
"MatchWholeWords": "Полное совпадение",
|
"Manual": "Ручной ввод",
|
||||||
"Minute": "Минуты",
|
"MatchWholeWords": "Точное совпадение",
|
||||||
"Minutes": "Файл уже существует, пожалуйста, переименуйте",
|
"Minute": "Минута",
|
||||||
|
"Minutes": "Минут",
|
||||||
|
"Must be auto login account for %s": "УЗ %s должна быть учётной записью с автоматическим входом",
|
||||||
|
"Must be unique account for %s": "УЗ %s должна быть уникальной",
|
||||||
|
"Must be unique asset for %s": "Актив %s должен быть уникальным",
|
||||||
"MustOneFile": "Можно выбрать только один файл",
|
"MustOneFile": "Можно выбрать только один файл",
|
||||||
"MustSelectOneFile": "Необходимо выбрать файл",
|
"MustSelectOneFile": "Необходимо выбрать файл",
|
||||||
"Name": "Название",
|
"Name": "Имя",
|
||||||
|
"Need ACL review, continue? (y/n): ": "Требуется проверка правил доступа. Продолжить? (y/n):",
|
||||||
|
"Need ticket confirm to execute command, already send email to the reviewers": "Выполнение команды требует проверки по заявке. Проверяющему отправлено письмо",
|
||||||
|
"Need ticket confirm to login, already send email to the reviewers": "Требуется вход в систему через заявку, уведомление отправлено утверждающему",
|
||||||
"NewFolder": "Создать папку",
|
"NewFolder": "Создать папку",
|
||||||
|
"No Account found.": "Учетная запись не найдена",
|
||||||
|
"No Assets": "Нет активов",
|
||||||
|
"No Databases": "База данных отсутствует",
|
||||||
|
"No found asset": "Совпадений для актива %s не найдено",
|
||||||
|
"No kubernetes": "Kubernetes не найден",
|
||||||
|
"No protocol found.": "Нет протокола",
|
||||||
|
"No route to host": "Нет соединения (маршрут недоступен)",
|
||||||
"NoActiveTerminalTabFound": "Активная вкладка терминала не найдена",
|
"NoActiveTerminalTabFound": "Активная вкладка терминала не найдена",
|
||||||
"NoData": "Нет данных",
|
"NoData": "Нет данных",
|
||||||
"NoLink": "Без адреса",
|
"NoLink": "Без адреса",
|
||||||
"NoRunningTerminalFound": "Не найдено работающего терминала",
|
"NoRunningTerminalFound": "Активный терминал не найден",
|
||||||
"OnlineUser": "Онлайн пользователи",
|
"Node: [ ID.Name(Asset amount) ]": "Папка: [ID.Название(кол-во активов)]",
|
||||||
|
"OnlineUser": "Пользователи онлайн",
|
||||||
"OperationSuccessful": "Операция выполнена успешно",
|
"OperationSuccessful": "Операция выполнена успешно",
|
||||||
"Owner": "Администратор",
|
"Organization": "Организация",
|
||||||
|
"Owner": "Владелец",
|
||||||
|
"Page up: b\tPage down: n": "Предыдущая страница: b Следующая страница: n",
|
||||||
|
"Page: %d, Count: %d, Total Page: %d, Total Count: %d": "Страница: %d, строк на странице: %d, всего страниц: %d, всего записей: %d",
|
||||||
"Paste": "Вставить",
|
"Paste": "Вставить",
|
||||||
"PauseSession": "Приостановить сессию",
|
"PauseSession": "Приостановить сессию",
|
||||||
"PermissionDenied": "Нет разрешения",
|
"PermissionDenied": "Доступ запрещен",
|
||||||
"PermissionExpired": "Разрешение истекло",
|
"PermissionExpired": "Разрешение истекло",
|
||||||
"PermissionValid": "Доступ разрешен",
|
"PermissionValid": "Доступ разрешен",
|
||||||
|
"Platform": "Платформа",
|
||||||
|
"Please waiting for the reviewers to confirm command `%s`, cancel by CTRL+C or CTRL+D.": "Пожалуйста, дождитесь проверки команды %s утверждающим. Для отмены нажмите CTRL+C или CTRL+D.",
|
||||||
|
"Please waiting for the reviewers to confirm, enter q to exit. ": "Ждём подтверждения проверяющего. q + Enter — отмена входа.",
|
||||||
"PleaseInput": "Пожалуйста, введите",
|
"PleaseInput": "Пожалуйста, введите",
|
||||||
"PleaseInputVerifyCode": "Введите код безопасности",
|
"PleaseInputVerifyCode": "Пожалуйста, введите код подтверждения",
|
||||||
"PrimaryUser": "Главный пользователь",
|
"PrimaryUser": "Основной пользователь",
|
||||||
"ReadOnly": "Минуты",
|
"Protocol": "Протокол",
|
||||||
|
"ReadOnly": "Только просмотр",
|
||||||
"Reconnect": "Переподключение",
|
"Reconnect": "Переподключение",
|
||||||
"Refresh": "Обновить",
|
"Refresh": "Обновить",
|
||||||
|
"Refresh done": "Обновлено",
|
||||||
"Remove": "Удалить",
|
"Remove": "Удалить",
|
||||||
"RemoveShareUser": "Вас удалили из общей сессии",
|
"RemoveShareUser": "Вас удалили из общей сессии",
|
||||||
"RemoveUser": "Удалить пользователя",
|
"RemoveUser": "Удалить пользователя",
|
||||||
"Rename": "Переименовать",
|
"Rename": "Переименовать",
|
||||||
"ResumeSession": "Возобновить сессию",
|
"ResumeSession": "Возобновить сессию",
|
||||||
|
"Reuse SSH connections (%s@%s) [Number of connections: %d]": "Повторное использование SSH соединения (%s@%s) [Количество соединений: %d]",
|
||||||
"RightArrow": "Стрелка вправо",
|
"RightArrow": "Стрелка вправо",
|
||||||
"Search": "Поиск",
|
"Search": "Поиск",
|
||||||
|
"Search: %s": "Поиск: %s",
|
||||||
|
"Select account exceed max retry times.": "Превышено максимальное число попыток выбора УЗ",
|
||||||
|
"Select protocol exceed max retry times.": "Превышено максимальное количество попыток выбора протокола",
|
||||||
"SelectAction": "Выберите действие",
|
"SelectAction": "Выберите действие",
|
||||||
"SelectTheme": "Выберите тему",
|
"SelectTheme": "Выберите тему",
|
||||||
"Self": "Я",
|
"Self": "Я",
|
||||||
"SessionDetail": "Детали разговора",
|
"Session max time reached, disconnect": "Превышено максимальное время сессии. Соединение разорвано",
|
||||||
|
"SessionDetail": "Детали сессии",
|
||||||
"SessionShare": "Поделиться сессией",
|
"SessionShare": "Поделиться сессией",
|
||||||
"Settings": "Настройки",
|
"Settings": "Настройки",
|
||||||
"Share": "Поделиться",
|
"Share": "Поделиться",
|
||||||
"ShareLink": "Поделиться ссылкой",
|
"ShareLink": "Поделиться ссылкой",
|
||||||
"ShareUser": "Поделиться пользователем",
|
"ShareUser": "Поделиться с",
|
||||||
"ShareUserHelpText": "Пустое поле означает, что присоединиться может каждый желающий.",
|
"ShareUserHelpText": "Пустое поле означает, что присоединиться может каждый желающий.",
|
||||||
"Size": "Размер",
|
"Size": "Размер",
|
||||||
|
"Start domain gateway failed %s": "Не удалось запустить шлюз базы данных %s",
|
||||||
|
"Switch language successfully": "Смена языка успешно выполнена",
|
||||||
|
"Switched to %s": "Переключено на %s",
|
||||||
"Sync": "Синхронизация",
|
"Sync": "Синхронизация",
|
||||||
"SyncUserPreferenceFailed": "Ошибка синхронизации настроек",
|
"SyncUserPreferenceFailed": "Ошибка синхронизации настроек",
|
||||||
"SyncUserPreferenceSuccess": "Настройки успешно синхронизированы",
|
"SyncUserPreferenceSuccess": "Настройки успешно синхронизированы",
|
||||||
"TerminalInstanceNotFound": "Не найден экземпляр терминала для текущей вкладки",
|
"Terminal does not support protocol %s, please use web terminal to access": "Этот терминал не поддерживает протокол %s, пожалуйста, войдите через веб-терминал",
|
||||||
"TerminalInstanceNotFoundForCurrentTab": "Текущая вкладка не найдена экземпляр терминала",
|
"TerminalInstanceNotFound": "Экземпляр терминала не найден",
|
||||||
"TheCurrentTerminalInstanceWasNotFound": "Текущий экземпляр терминала не найден.",
|
"TerminalInstanceNotFoundForCurrentTab": "Экземпляр терминала не найден в текущей вкладке",
|
||||||
|
"The command '%s' requires review. Continue or not [Y/n]?": "Команда %s требует проверки. Продолжить? [Y/N]",
|
||||||
|
"The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?[Y/N]": "Выполняемая вами команда несёт риск, уведомление будет отправлено администратору. Продолжить? [Y/N]",
|
||||||
|
"TheCurrentTerminalInstanceWasNotFound": "Текущий экземпляр терминала не найден",
|
||||||
"Theme": "Тема",
|
"Theme": "Тема",
|
||||||
"ThemeColors": "Цвета темы",
|
"ThemeColors": "Цвета темы",
|
||||||
"ThemeConfig": "Настройки темы",
|
"ThemeConfig": "Настройки темы",
|
||||||
|
"Ticket Reviewers: %s": "Утверждающий заявки: %s",
|
||||||
|
"Tips: Enter asset[%s] account ID": "Подсказка: Введите ID учетной записи актива [%s]",
|
||||||
|
"Tips: Enter g+NodeID to display the host under the node, such as g1": "Подсказка: введите g+ID папки, чтобы показать хосты внутри, например: g1",
|
||||||
|
"Tips: Enter protocol ID": "Подсказка: введите ID протокола",
|
||||||
|
"Tips: To set a default language, go to Personal Settings → Preferences on Web": "Подсказка: если хотите установить язык по умолчанию, перейдите в веб-версию в «Личные настройки → Предпочтения»",
|
||||||
|
"Tips: switch language by ID (Current session only)": "Подсказка: введите ID, чтобы переключить язык (только для этой сессии)",
|
||||||
"Transfer": "Передача",
|
"Transfer": "Передача",
|
||||||
"Type": "Тип",
|
"Type": "Тип",
|
||||||
"UnableToGenerateWebSocketURL": "Не удалось сгенерировать WebSocket URL, отсутствуют параметры",
|
"UnableToGenerateWebSocketURL": "Не удалось создать URL WebSocket — отсутствуют параметры",
|
||||||
|
"Unknown error code: %s, detail: %s": "Неизвестный код ошибки: %s, подробности: %s",
|
||||||
|
"Unknown status": "Неизвестное состояние",
|
||||||
"UpArrow": "Кнопка вверх",
|
"UpArrow": "Кнопка вверх",
|
||||||
"Upload": "Загрузить",
|
"Upload": "Загрузить",
|
||||||
"UploadEnd": "Загрузка завершена, пожалуйста, подождите дальнейшей обработки",
|
"UploadEnd": "Загрузка завершена, пожалуйста, подождите дальнейшей обработки",
|
||||||
"UploadProgress": "Прогресс передачи",
|
"UploadProgress": "Прогресс загрузки",
|
||||||
"UploadStart": "Загрузка началась",
|
"UploadStart": "Загрузка началась",
|
||||||
"UploadSuccess": "Загрузка успешно завершена",
|
"UploadSuccess": "Загрузка успешно завершена",
|
||||||
"UploadTips": "Перетащите файл сюда или нажмите для загрузки",
|
"UploadTips": "Перетащите файл сюда или нажмите для загрузки",
|
||||||
"UploadTitle": "Загрузить файл",
|
"UploadTitle": "Загрузить файл",
|
||||||
"User": "Пользователь",
|
"User": "Пользователь",
|
||||||
|
"Username": "Имя пользователя",
|
||||||
"UsingRegularExpressions": "Использовать регулярные выражения",
|
"UsingRegularExpressions": "Использовать регулярные выражения",
|
||||||
"VerifyCode": "Код подтверждения",
|
"VerifyCode": "Код подтверждения",
|
||||||
"WaitFileTransfer": "Ожидание завершения передачи файла",
|
"WaitFileTransfer": "Ожидание завершения передачи файла",
|
||||||
"Warning": "Предупреждение",
|
"Warning": "Предупреждение",
|
||||||
"WebSocketClosed": "WebSocket закрыт",
|
"WebSocketClosed": "WebSocket закрыт",
|
||||||
"WebSocketConnectionIsClosedHelpText": "WebSocket соединение закрыто, пожалуйста, обновите страницу или переподключитесь.",
|
"WebSocketConnectionIsClosedHelpText": "WebSocket соединение закрыто, пожалуйста, обновите страницу или переподключитесь.",
|
||||||
"Writable": "Создать ссылку для分享"
|
"Welcome to use JumpServer open source fortress system": "Добро пожаловать в JumpServer",
|
||||||
|
"Writable": "Просмотр и управление",
|
||||||
|
"You don't have permission login %s": "У вас нет прав на вход в %s",
|
||||||
|
"You get auth token failed": "Не удалось получить токен аутентификации",
|
||||||
|
"display the assets you have permission": "посмотреть активы, к которым у вас есть доступ",
|
||||||
|
"display the databases that you have permission": "посмотреть базы данных, к которым у вас есть доступ",
|
||||||
|
"display the hosts that you have permission": "посмотреть хосты, к которым у вас есть доступ",
|
||||||
|
"display the kubernetes that you have permission": "посмотреть доступные вам Kubernetes",
|
||||||
|
"display the node that you have permission": "посмотреть папки, к которым у вас есть доступ",
|
||||||
|
"exit": "выйти",
|
||||||
|
"get connect token err": "Ошибка получения токена подключения",
|
||||||
|
"have no permission to download file": "Нет прав на скачивание файлов",
|
||||||
|
"have no permission to upload file": "Нет прав на загрузку файлов",
|
||||||
|
"i/o timeout": "Нет соединения (тайм-аут соединения)",
|
||||||
|
"language switch": "сменить язык",
|
||||||
|
"network is unreachable": "Нет соединения (сеть недоступна)",
|
||||||
|
"not found matched username %s": "совпадений для УЗ %s не найдено",
|
||||||
|
"part IP, Hostname, Comment": "часть IP, имя хоста или примечание",
|
||||||
|
"part IP,, Hostname, Comment": "/ + IP, имя хоста или примечание",
|
||||||
|
"print help": "посмотреть помощь",
|
||||||
|
"refresh your assets and nodes": "обновить информацию об активах и папках",
|
||||||
|
"select one asset to login": "выберите один из активов для входа",
|
||||||
|
"to search login if unique": "найти подключение (если результат уникальный)",
|
||||||
|
"to search, such as: /192.168": "выполнить поиск, например: /192.168"
|
||||||
}
|
}
|
||||||
227
apps/i18n/koko/vi.json
Normal file
227
apps/i18n/koko/vi.json
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
{
|
||||||
|
"\t%2d) Enter {{.GreenBoldColor}}%s{{.ColorEnd}} to %s.%s": "%d) Nhập {{.GreenBoldColor}}%s{{.ColorEnd}} để thực hiện %s.%s",
|
||||||
|
"%s approved": "%s đã được phê duyệt.",
|
||||||
|
"%s node has no assets": "Tài nguyên trên nút %s không tồn tại",
|
||||||
|
"%s protocol client not installed.": "%s协议 của khách hàng chưa được cài đặt",
|
||||||
|
"%s rejected": "Phê duyệt bị từ chối",
|
||||||
|
"ACL reject": "Đăng nhập lần này đã bị từ chối vì hạn chế của chính sách kiểm soát truy cập",
|
||||||
|
"Account <%s> and asset <%s> protocol are inconsistent.": "Người dùng hệ thống<%s> và tài sản<%s> không nhất quán",
|
||||||
|
"ActionPerm": "Quyền hành động",
|
||||||
|
"Address": "Địa chỉ",
|
||||||
|
"AlreadyExistsPleaseRename": "Tệp đã tồn tại, vui lòng đổi tên",
|
||||||
|
"Announcement: ": "Thông báo:",
|
||||||
|
"Authentication failed": "Xác thực thất bại (tên người dùng hoặc mật khẩu không chính xác)",
|
||||||
|
"AvailableShortcutKey": "Phím tắt có sẵn",
|
||||||
|
"Back": "Quay lại",
|
||||||
|
"Back: B/b": "Quay lại: B/b",
|
||||||
|
"Cancel": "Hủy bỏ",
|
||||||
|
"Cancel confirm": "Hủy phê duyệt đăng nhập",
|
||||||
|
"Cancel to login asset or max 3 retry": "Hủy đăng nhập vào tài nguyên hoặc đã đạt 3 lần thử lại",
|
||||||
|
"CancelFileUpload": "Hủy tải file lên",
|
||||||
|
"CaseSensitive": "Phân biệt chữ hoa chữ thường",
|
||||||
|
"Clone Connect": "Sao chép cửa sổ",
|
||||||
|
"Close All Tabs": "Đóng tất cả",
|
||||||
|
"Close Current Tab": "Đóng hiện tại",
|
||||||
|
"Command `%s` is forbidden": "Lệnh `%s` bị cấm ...",
|
||||||
|
"Comment": "Ghi chú",
|
||||||
|
"Confirm": "Xác nhận",
|
||||||
|
"ConfirmBtn": "Đồng ý",
|
||||||
|
"ConfirmDelete": "Bạn có chắc chắn muốn xóa tệp này không?",
|
||||||
|
"Connect": "Kết nối",
|
||||||
|
"Connect idle more than %d minutes, disconnect": "thời gian rảnh rỗi vượt quá %d phút, ngắt kết nối",
|
||||||
|
"Connect with api server failed": "Kết nối dịch vụ API thất bại",
|
||||||
|
"Connecting to %s@%s": "bắt đầu kết nối đến %s@%s",
|
||||||
|
"Connecting to Database %s": "Bắt đầu kết nối với cơ sở dữ liệu %s",
|
||||||
|
"Connecting to Kubernetes %s": "Bắt đầu kết nối với Kubernetes %s",
|
||||||
|
"Connecting to Kubernetes %s container %s": "Bắt đầu kết nối với Kubernetes %s Container %s",
|
||||||
|
"Connection refused": "Mạng không kết nối (kết nối bị từ chối)",
|
||||||
|
"CopyLink": "Sao chép liên kết và mã xác thực.",
|
||||||
|
"CopyShareURLSuccess": "Sao chép địa chỉ chia sẻ thành công",
|
||||||
|
"Core API failed": "Lỗi xảy ra tại Core API",
|
||||||
|
"Could copy website URL to notify reviewers: %s": "Địa chỉ kiểm tra có thể sao chép, thông báo cho người kiểm tra: %s",
|
||||||
|
"Create k8s client err: %s": "Tạo lỗi khách hàng k8s: %s",
|
||||||
|
"CreateFolder": "Tạo thư mục",
|
||||||
|
"CreateLink": "Tạo liên kết",
|
||||||
|
"CreateSuccess": "Tạo thành công",
|
||||||
|
"CurrentUser": "Người dùng hiện tại",
|
||||||
|
"Custom Setting": "Cài đặt tùy chỉnh",
|
||||||
|
"DangerWarning": "Đây là một hành động nguy hiểm",
|
||||||
|
"Delete": "Xóa",
|
||||||
|
"DownArrow": "Mũi tên hướng xuống",
|
||||||
|
"Download": "Tải xuống",
|
||||||
|
"DownloadProgress": "Tiến độ tải xuống",
|
||||||
|
"DownloadSuccess": "Tải xuống thành công",
|
||||||
|
"Downloading": "Đang tải xuống",
|
||||||
|
"Dynamic": "Tài khoản động",
|
||||||
|
"EndFileTransfer": "Chuyển file hoàn tất",
|
||||||
|
"Enter ID number directly login, multiple search use // + field, such as: //16": "Gợi ý: Nhập ID tài sản để đăng nhập trực tiếp, tìm kiếm cấp hai sử dụng // + lĩnh vực, ví dụ: //192",
|
||||||
|
"ExceedTransferSize": "Vượt quá kích thước truyền tải tối đa",
|
||||||
|
"Expand": "Mở rộng",
|
||||||
|
"ExpiredTime": "Thời gian hiệu lực",
|
||||||
|
"Face ACL is not supported yet. Please use the WebTerminal to connect the asset.": "Thiết bị này không hỗ trợ quy tắc truy cập bằng khuôn mặt, vui lòng đăng nhập bằng thiết bị web",
|
||||||
|
"Face verification is not supported yet. Please use the WebTerminal to connect the asset.": "Thiết bị đầu cuối này không hỗ trợ xác thực nhận diện khuôn mặt, vui lòng đăng nhập bằng thiết bị đầu cuối web.",
|
||||||
|
"FailedCreateConnection": "Tạo kết nối thất bại",
|
||||||
|
"FileAlreadyExists": "Tệp đã tồn tại",
|
||||||
|
"FileListError": "Lấy thông tin danh sách tệp thất bại",
|
||||||
|
"FileManagement": "Quản lý tập tin",
|
||||||
|
"FileManagementExpired": "Phiên quản lý tệp hiện tại đã hết hạn.",
|
||||||
|
"FileManagerTokenTimeout": "Lấy Token quản lý tập tin hết thời gian",
|
||||||
|
"FileTransferInterrupted": "Chuyển tệp bị gián đoạn",
|
||||||
|
"FileUploadInterrupted": "Tải tệp bị ngắt quãng",
|
||||||
|
"Format": "Định dạng",
|
||||||
|
"General": "Chung",
|
||||||
|
"Get auth password failed": "Bạn đã không thể lấy mã xác thực",
|
||||||
|
"GetFileManagerTokenTimeOut": "Lấy Token quản lý tập tin hết thời gian",
|
||||||
|
"GetShareUser": "Nhập tên người dùng",
|
||||||
|
"HandleTask does not support protocol %s, please use web terminal to access": "Thiết bị này không hỗ trợ giao thức %s, vui lòng đăng nhập bằng thiết bị web",
|
||||||
|
"Hostname": "Tên máy chủ",
|
||||||
|
"Hotkeys": "Phím tắt",
|
||||||
|
"ID": "ID",
|
||||||
|
"InputVerifyCode": "Xin vui lòng nhập mã xác minh",
|
||||||
|
"Invalid ID": "ID không hợp lệ",
|
||||||
|
"JoinShare": "Tham gia chia sẻ",
|
||||||
|
"JoinedWithSuccess": "Đã tham gia thành công",
|
||||||
|
"KubernetesManagement": "Quản lý Kubernetes",
|
||||||
|
"LastModified": "Thời gian chỉnh sửa cuối cùng",
|
||||||
|
"LeaveShare": "Rời khỏi chia sẻ",
|
||||||
|
"LeftArrow": "Mũi tên quay lại",
|
||||||
|
"LinkAddr": "Địa chỉ liên kết",
|
||||||
|
"List": "Danh sách",
|
||||||
|
"Manual": "Tài khoản thủ công",
|
||||||
|
"MatchWholeWords": "Khớp chính xác",
|
||||||
|
"Minute": "Phút",
|
||||||
|
"Minutes": "Phút",
|
||||||
|
"Must be auto login account for %s": "Tài khoản phải là tài khoản đăng nhập tự động %s",
|
||||||
|
"Must be unique account for %s": "Tài khoản phải là duy nhất %s",
|
||||||
|
"Must be unique asset for %s": "Phải là tài nguyên duy nhất %s",
|
||||||
|
"MustOneFile": "Chỉ có thể chọn một tệp",
|
||||||
|
"MustSelectOneFile": "Phải chọn một tệp",
|
||||||
|
"Name": "Tên",
|
||||||
|
"Need ACL review, continue? (y/n): ": "cần phê duyệt, tiếp tục? (y/n):",
|
||||||
|
"Need ticket confirm to execute command, already send email to the reviewers": "Cần lệnh công việc để thực hiện phê duyệt, đã gửi email thông báo cho người phê duyệt",
|
||||||
|
"Need ticket confirm to login, already send email to the reviewers": "Cần đăng nhập công việc để kiểm tra và đã gửi email thông báo cho người kiểm tra",
|
||||||
|
"NewFolder": "Thư mục mới",
|
||||||
|
"No Account found.": "Không tìm thấy tài khoản",
|
||||||
|
"No Assets": "Không có tài sản",
|
||||||
|
"No Databases": "không có cơ sở dữ liệu",
|
||||||
|
"No found asset": "Không tìm thấy tài sản phù hợp %s",
|
||||||
|
"No kubernetes": "Không có Kubernetes",
|
||||||
|
"No protocol found.": "Không có giao thức",
|
||||||
|
"No route to host": "Mạng không ổn định (đường truyền không thông)",
|
||||||
|
"NoActiveTerminalTabFound": "Không tìm thấy tab terminal hoạt động",
|
||||||
|
"NoData": "Không có dữ liệu",
|
||||||
|
"NoLink": "Không có địa chỉ",
|
||||||
|
"NoRunningTerminalFound": "Không tìm thấy terminal đang chạy",
|
||||||
|
"Node: [ ID.Name(Asset amount) ]": "nút: [ ID.Tên (số lượng tài sản) ]",
|
||||||
|
"OnlineUser": "Người dùng trực tuyến",
|
||||||
|
"OperationSuccessful": "Thao tác thành công",
|
||||||
|
"Organization": "Tổ chức",
|
||||||
|
"Owner": "Quản lý",
|
||||||
|
"Page up: b\tPage down: n": "Trang trước: b Trang tiếp theo: n",
|
||||||
|
"Page: %d, Count: %d, Total Page: %d, Total Count: %d": "Số trang: %d, số dòng mỗi trang: %d, tổng số trang: %d, tổng số lượng: %d",
|
||||||
|
"Paste": "Dán vào",
|
||||||
|
"PauseSession": "Tạm dừng phiên này",
|
||||||
|
"PermissionDenied": "Không có quyền",
|
||||||
|
"PermissionExpired": "Quyền đã hết hạn",
|
||||||
|
"PermissionValid": "Quyền vẫn còn hiệu lực",
|
||||||
|
"Platform": "Nền tảng",
|
||||||
|
"Please waiting for the reviewers to confirm command `%s`, cancel by CTRL+C or CTRL+D.": "Vui lòng chờ người xem xét xem xét lệnh `%s`, hủy bằng CTRL+C hoặc CTRL+D.",
|
||||||
|
"Please waiting for the reviewers to confirm, enter q to exit. ": "Đang chờ người kiểm tra xác nhận, nhấn q và Enter để hủy đăng nhập.",
|
||||||
|
"PleaseInput": "Vui lòng nhập",
|
||||||
|
"PleaseInputVerifyCode": "Vui lòng nhập mã xác thực",
|
||||||
|
"PrimaryUser": "Người dùng chính",
|
||||||
|
"Protocol": "Giao thức",
|
||||||
|
"ReadOnly": "Chỉ đọc",
|
||||||
|
"Reconnect": "Kết nối lại",
|
||||||
|
"Refresh": "Làm mới",
|
||||||
|
"Refresh done": "làm mới hoàn tất",
|
||||||
|
"Remove": "Gỡ bỏ",
|
||||||
|
"RemoveShareUser": "Bạn đã bị gỡ khỏi phiên chia sẻ.",
|
||||||
|
"RemoveUser": "Gỡ bỏ người dùng",
|
||||||
|
"Rename": "Đổi tên",
|
||||||
|
"ResumeSession": "Khôi phục phiên này",
|
||||||
|
"Reuse SSH connections (%s@%s) [Number of connections: %d]": "Tái sử dụng kết nối SSH (%s@%s) [Số lượng kết nối: %d]",
|
||||||
|
"RightArrow": "Mũi tên tiến lên",
|
||||||
|
"Search": "Tìm kiếm",
|
||||||
|
"Search: %s": "Tìm kiếm: %s",
|
||||||
|
"Select account exceed max retry times.": "Số tài khoản đã vượt quá số lần thử tối đa",
|
||||||
|
"Select protocol exceed max retry times.": "chọn giao thức vượt quá số lần thử tối đa.",
|
||||||
|
"SelectAction": "Vui lòng chọn",
|
||||||
|
"SelectTheme": "- Chọn chủ đề\n- Định dạng\n- Bạn có chắc chắn muốn xóa tệp này không?\n- Truyền tệp bị gián đoạn\n- Chia sẻ phiên\n- Phải chọn một tệp\n- Tải xuống thành công\n- Chưa chọn người dùng, tức là cho phép tất cả mọi người tham gia\n- Cài đặt đồng bộ thành công\n- Người dùng chia sẻ\n- Tệp đã tồn tại\n- Bạn đã bị gỡ bỏ khỏi phiên chia sẻ\n- Đồng bộ\n- Người dùng chính\n- Mũi tên quay lại",
|
||||||
|
"Self": "Tôi",
|
||||||
|
"Session max time reached, disconnect": "Phiên đã vượt quá thời gian kết nối tối đa, ngắt kết nối",
|
||||||
|
"SessionDetail": "Chi tiết phiên hoạt động.",
|
||||||
|
"SessionShare": "Chia sẻ phiên",
|
||||||
|
"Settings": "Cài đặt",
|
||||||
|
"Share": "Chia sẻ",
|
||||||
|
"ShareLink": "Chia sẻ liên kết",
|
||||||
|
"ShareUser": "Chia sẻ người dùng",
|
||||||
|
"ShareUserHelpText": "Chưa chọn người dùng, tức là cho phép mọi người tham gia",
|
||||||
|
"Size": "Kích thước",
|
||||||
|
"Start domain gateway failed %s": "Khởi động cổng cơ sở dữ liệu thất bại %s \nCập nhật thông tin máy móc và nút mới nhất \nLệnh %s cần được xem xét, bạn có muốn tiếp tục không? [Y/N] \nTìm kiếm, ví dụ: /192.168 \nMạng không thông (mạng không thể truy cập) \nKhông có cơ sở dữ liệu \nHiển thị các cơ sở dữ liệu mà bạn có quyền truy cập \nBắt đầu kết nối đến %s@%s \nHiển thị các Kubernetes mà bạn có quyền truy cập \nCập nhật hoàn tất \nNút: [ ID.Tên(Số lượng tài sản) ] \nChuyển đổi ngôn ngữ thành công \nChọn giao thức vượt quá số lần thử tối đa \nThời gian nhàn rỗi vượt quá %d phút, ngắt kết nối \nLời khuyên: Nhập g+nút ID để hiển thị các máy chủ dưới nút, ví dụ: g1",
|
||||||
|
"Switch language successfully": "chuyển ngôn ngữ thành công",
|
||||||
|
"Switched to %s": "Đã chuyển sang %s",
|
||||||
|
"Sync": "Đồng bộ",
|
||||||
|
"SyncUserPreferenceFailed": "Đồng bộ cài đặt thất bại",
|
||||||
|
"SyncUserPreferenceSuccess": "Cài đặt đồng bộ thành công",
|
||||||
|
"Terminal does not support protocol %s, please use web terminal to access": "Thiết bị này không hỗ trợ %sprotocol, vui lòng đăng nhập bằng thiết bị web",
|
||||||
|
"TerminalInstanceNotFound": "Không tìm thấy phiên bản terminal của tab hiện tại",
|
||||||
|
"TerminalInstanceNotFoundForCurrentTab": "Không tìm thấy phiên bản terminal trong tab hiện tại",
|
||||||
|
"The command '%s' requires review. Continue or not [Y/n]?": "lệnh %s cần được xem xét, có tiếp tục không? [Y/N]",
|
||||||
|
"The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?[Y/N]": "Lệnh bạn thực hiện có nguy cơ, thông báo cảnh báo sẽ được gửi đến quản lý. Có muốn tiếp tục không? [Y/N]",
|
||||||
|
"TheCurrentTerminalInstanceWasNotFound": "Không tìm thấy phiên bản terminal hiện tại",
|
||||||
|
"Theme": "Chủ đề",
|
||||||
|
"ThemeColors": "Màu sắc chủ đề",
|
||||||
|
"ThemeConfig": "Chủ đề",
|
||||||
|
"Ticket Reviewers: %s": "Người xem xét công việc: %s",
|
||||||
|
"Tips: Enter asset[%s] account ID": "Gợi ý: Nhập ID tài khoản của tài sản [%s]",
|
||||||
|
"Tips: Enter g+NodeID to display the host under the node, such as g1": "Ghi chú: Nhập g+ID nút để hiển thị máy chủ dưới nút, ví dụ: g1",
|
||||||
|
"Tips: Enter protocol ID": "Gợi ý: Nhập ID giao thức",
|
||||||
|
"Tips: To set a default language, go to Personal Settings → Preferences on Web": "Gợi ý: Để thiết lập ngôn ngữ mặc định, vui lòng truy cập vào trang Web \"Cài đặt cá nhân → Tùy chọn\"",
|
||||||
|
"Tips: switch language by ID (Current session only)": "Gợi ý: Nhập ID để chuyển đổi ngôn ngữ",
|
||||||
|
"Transfer": "Truyền tải",
|
||||||
|
"Type": "Loại",
|
||||||
|
"UnableToGenerateWebSocketURL": "Không thể tạo URL WebSocket, thiếu tham số",
|
||||||
|
"Unknown error code: %s, detail: %s": "Mã lỗi không xác định: %s, chi tiết: %s",
|
||||||
|
"Unknown status": "Trạng thái không xác định",
|
||||||
|
"UpArrow": "Mũi tên lên",
|
||||||
|
"Upload": "Tải lên",
|
||||||
|
"UploadEnd": "Tải lên đã hoàn tất, vui lòng chờ xử lý tiếp theo",
|
||||||
|
"UploadProgress": "Tiến độ tải lên",
|
||||||
|
"UploadStart": "Bắt đầu tải lên",
|
||||||
|
"UploadSuccess": "Tải lên thành công",
|
||||||
|
"UploadTips": "Kéo file đến đây, hoặc nhấp vào tải lên",
|
||||||
|
"UploadTitle": "Tải lên tệp",
|
||||||
|
"User": "Người dùng",
|
||||||
|
"Username": "Tên người dùng",
|
||||||
|
"UsingRegularExpressions": "Sử dụng biểu thức chính quy",
|
||||||
|
"VerifyCode": "Mã xác thực",
|
||||||
|
"WaitFileTransfer": "Chờ đợi kết thúc truyền tệp",
|
||||||
|
"Warning": "Cảnh báo",
|
||||||
|
"WebSocketClosed": "WebSocket đã đóng",
|
||||||
|
"WebSocketConnectionIsClosedHelpText": "Kết nối WebSocket đã bị đóng, vui lòng làm mới trang hoặc kết nối lại.",
|
||||||
|
"Welcome to use JumpServer open source fortress system": "Chào mừng bạn đến với hệ thống JumpServer mã nguồn mở",
|
||||||
|
"Writable": "Có thể ghi",
|
||||||
|
"You don't have permission login %s": "Bạn không có quyền đăng nhập vào %s",
|
||||||
|
"You get auth token failed": "Bạn đã không lấy được mã thông báo xác thực",
|
||||||
|
"display the assets you have permission": "Hiển thị tài sản mà bạn có quyền truy cập",
|
||||||
|
"display the databases that you have permission": "hiển thị cơ sở dữ liệu mà bạn có quyền truy cập",
|
||||||
|
"display the hosts that you have permission": "Hiển thị các máy chủ mà bạn có quyền",
|
||||||
|
"display the kubernetes that you have permission": "hiển thị các Kubernetes mà bạn có quyền truy cập",
|
||||||
|
"display the node that you have permission": "Hiển thị các nút mà bạn có quyền truy cập",
|
||||||
|
"exit": "Thoát",
|
||||||
|
"get connect token err": "Lỗi lấy mã kết nối",
|
||||||
|
"have no permission to download file": "Không có quyền tải xuống tệp",
|
||||||
|
"have no permission to upload file": "Không có quyền tải lên tệp",
|
||||||
|
"i/o timeout": "Mạng không ổn định (thời gian kết nối đã hết)",
|
||||||
|
"language switch": "Chuyển đổi ngôn ngữ",
|
||||||
|
"network is unreachable": "mạng không thông (mạng không thể tiếp cận)",
|
||||||
|
"not found matched username %s": "Không tìm thấy tên người dùng khớp %s",
|
||||||
|
"part IP, Hostname, Comment": "Một phần IP, tên máy chủ, ghi chú",
|
||||||
|
"part IP,, Hostname, Comment": "/ + IP, tên máy chủ, ghi chú",
|
||||||
|
"print help": "Hiển thị trợ giúp",
|
||||||
|
"refresh your assets and nodes": "làm mới thông tin máy và nút mới nhất",
|
||||||
|
"select one asset to login": "Chọn một tài sản để đăng nhập",
|
||||||
|
"to search login if unique": "Tìm kiếm đăng nhập (nếu duy nhất)",
|
||||||
|
"to search, such as: /192.168": "tìm kiếm, ví dụ: /192.168"
|
||||||
|
}
|
||||||
@@ -1,20 +1,45 @@
|
|||||||
{
|
{
|
||||||
|
"\t%2d) Enter {{.GreenBoldColor}}%s{{.ColorEnd}} to %s.%s": "\t%d) 输入 {{.GreenBoldColor}}%s{{.ColorEnd}} 进行%s.%s",
|
||||||
|
"%s approved": "%s 审核通过",
|
||||||
|
"%s node has no assets": "%s节点没有资产",
|
||||||
|
"%s protocol client not installed.": "%s 协议的客户端未安装",
|
||||||
|
"%s rejected": "%s 审核拒绝",
|
||||||
|
"ACL reject": "本次登录已拒绝,原因是访问控制策略的限制",
|
||||||
|
"Account <%s> and asset <%s> protocol are inconsistent.": "系统用户<%s>和资产<%s>协议不一致",
|
||||||
"ActionPerm": "操作权限",
|
"ActionPerm": "操作权限",
|
||||||
|
"Address": "地址",
|
||||||
"AlreadyExistsPleaseRename": "文件已存在,请重命名",
|
"AlreadyExistsPleaseRename": "文件已存在,请重命名",
|
||||||
|
"Announcement: ": "公告:",
|
||||||
|
"Authentication failed": "认证失败(用户名或密码错误)",
|
||||||
"AvailableShortcutKey": "可用快捷键",
|
"AvailableShortcutKey": "可用快捷键",
|
||||||
"Back": "返回",
|
"Back": "返回",
|
||||||
|
"Back: B/b": "返回:B/b",
|
||||||
"Cancel": "取消",
|
"Cancel": "取消",
|
||||||
|
"Cancel confirm": "取消登录复核",
|
||||||
|
"Cancel to login asset or max 3 retry": "取消登录资产或达到3次重试",
|
||||||
"CancelFileUpload": "取消文件上传",
|
"CancelFileUpload": "取消文件上传",
|
||||||
"CaseSensitive": "区分大小写",
|
"CaseSensitive": "区分大小写",
|
||||||
"Clone Connect": "复制窗口",
|
"Clone Connect": "复制窗口",
|
||||||
"Close All Tabs": "关闭所有",
|
"Close All Tabs": "关闭所有",
|
||||||
"Close Current Tab": "关闭当前",
|
"Close Current Tab": "关闭当前",
|
||||||
|
"Command `%s` is forbidden": "命令 `%s` 是被禁止的 ...",
|
||||||
|
"Comment": "备注",
|
||||||
"Confirm": "确认",
|
"Confirm": "确认",
|
||||||
"ConfirmBtn": "确定",
|
"ConfirmBtn": "确定",
|
||||||
"ConfirmDelete": "您确定要删除该文件吗?",
|
"ConfirmDelete": "您确定要删除该文件吗?",
|
||||||
"Connect": "连接",
|
"Connect": "连接",
|
||||||
|
"Connect idle more than %d minutes, disconnect": "空闲时间超过%d分钟,断开连接",
|
||||||
|
"Connect with api server failed": "连接API服务失败",
|
||||||
|
"Connecting to %s@%s": "开始连接到 %s@%s",
|
||||||
|
"Connecting to Database %s": "开始连接数据库 %s",
|
||||||
|
"Connecting to Kubernetes %s": "开始连接Kubernetes %s",
|
||||||
|
"Connecting to Kubernetes %s container %s": "开始连接Kubernetes %s 容器 %s",
|
||||||
|
"Connection refused": "网络不通(连接拒绝)",
|
||||||
"CopyLink": "复制链接及验证码",
|
"CopyLink": "复制链接及验证码",
|
||||||
"CopyShareURLSuccess": "复制分享地址成功",
|
"CopyShareURLSuccess": "复制分享地址成功",
|
||||||
|
"Core API failed": "Core API 发生错误",
|
||||||
|
"Could copy website URL to notify reviewers: %s": "可复制审核地址,通知审核人:%s",
|
||||||
|
"Create k8s client err: %s": "创建 k8s 客户端错误:%s",
|
||||||
"CreateFolder": "创建文件夹",
|
"CreateFolder": "创建文件夹",
|
||||||
"CreateLink": "创建链接",
|
"CreateLink": "创建链接",
|
||||||
"CreateSuccess": "创建成功",
|
"CreateSuccess": "创建成功",
|
||||||
@@ -27,10 +52,14 @@
|
|||||||
"DownloadProgress": "下载进度",
|
"DownloadProgress": "下载进度",
|
||||||
"DownloadSuccess": "下载成功",
|
"DownloadSuccess": "下载成功",
|
||||||
"Downloading": "正在下载",
|
"Downloading": "正在下载",
|
||||||
|
"Dynamic": "动态账号",
|
||||||
"EndFileTransfer": "文件传输结束",
|
"EndFileTransfer": "文件传输结束",
|
||||||
|
"Enter ID number directly login, multiple search use // + field, such as: //16": "提示:输入资产ID直接登录,二级搜索使用 // + 字段,如://192",
|
||||||
"ExceedTransferSize": "超过最大传输大小",
|
"ExceedTransferSize": "超过最大传输大小",
|
||||||
"Expand": "展开",
|
"Expand": "展开",
|
||||||
"ExpiredTime": "有效期限",
|
"ExpiredTime": "有效期限",
|
||||||
|
"Face ACL is not supported yet. Please use the WebTerminal to connect the asset.": "该终端不支持人脸访问规则,请使用web终端登录",
|
||||||
|
"Face verification is not supported yet. Please use the WebTerminal to connect the asset.": "该终端不支持人脸识别认证,请使用web终端登录",
|
||||||
"FailedCreateConnection": "创建连接失败",
|
"FailedCreateConnection": "创建连接失败",
|
||||||
"FileAlreadyExists": "文件已存在",
|
"FileAlreadyExists": "文件已存在",
|
||||||
"FileListError": "获取文件列表信息失败",
|
"FileListError": "获取文件列表信息失败",
|
||||||
@@ -41,10 +70,15 @@
|
|||||||
"FileUploadInterrupted": "文件上传中断",
|
"FileUploadInterrupted": "文件上传中断",
|
||||||
"Format": "格式",
|
"Format": "格式",
|
||||||
"General": "通用",
|
"General": "通用",
|
||||||
|
"Get auth password failed": "你获取认证令牌失败",
|
||||||
"GetFileManagerTokenTimeOut": "获取文件管理 Token 超时",
|
"GetFileManagerTokenTimeOut": "获取文件管理 Token 超时",
|
||||||
"GetShareUser": "输入用户名",
|
"GetShareUser": "输入用户名",
|
||||||
|
"HandleTask does not support protocol %s, please use web terminal to access": "该终端不支持 %s 协议,请使用web终端登录",
|
||||||
|
"Hostname": "主机名",
|
||||||
"Hotkeys": "快捷键",
|
"Hotkeys": "快捷键",
|
||||||
|
"ID": "ID",
|
||||||
"InputVerifyCode": "请输入验证码",
|
"InputVerifyCode": "请输入验证码",
|
||||||
|
"Invalid ID": "无效 ID",
|
||||||
"JoinShare": "加入共享",
|
"JoinShare": "加入共享",
|
||||||
"JoinedWithSuccess": "已成功加入",
|
"JoinedWithSuccess": "已成功加入",
|
||||||
"KubernetesManagement": "Kubernetes 管理",
|
"KubernetesManagement": "Kubernetes 管理",
|
||||||
@@ -53,41 +87,69 @@
|
|||||||
"LeftArrow": "后退箭头",
|
"LeftArrow": "后退箭头",
|
||||||
"LinkAddr": "链接地址",
|
"LinkAddr": "链接地址",
|
||||||
"List": "列表",
|
"List": "列表",
|
||||||
|
"Manual": "手动账号",
|
||||||
"MatchWholeWords": "全字匹配",
|
"MatchWholeWords": "全字匹配",
|
||||||
"Minute": "分钟",
|
"Minute": "分钟",
|
||||||
"Minutes": "分",
|
"Minutes": "分",
|
||||||
|
"Must be auto login account for %s": "必须是自动登录账号 %s",
|
||||||
|
"Must be unique account for %s": "必须是唯一的账号 %s",
|
||||||
|
"Must be unique asset for %s": "必须是唯一的资产 %s",
|
||||||
"MustOneFile": "只能选择一个文件",
|
"MustOneFile": "只能选择一个文件",
|
||||||
"MustSelectOneFile": "必须选择一个文件",
|
"MustSelectOneFile": "必须选择一个文件",
|
||||||
"Name": "名称",
|
"Name": "名称",
|
||||||
|
"Need ACL review, continue? (y/n): ": "需要审核,继续?(y/n): ",
|
||||||
|
"Need ticket confirm to execute command, already send email to the reviewers": "需要工单命令执行复核,已发邮件通知审核人",
|
||||||
|
"Need ticket confirm to login, already send email to the reviewers": "需要工单登录复核,已发邮件通知审核人",
|
||||||
"NewFolder": "新建文件夹",
|
"NewFolder": "新建文件夹",
|
||||||
|
"No Account found.": "未发现账号",
|
||||||
|
"No Assets": "没有资产",
|
||||||
|
"No Databases": "无数据库",
|
||||||
|
"No found asset": "未发现匹配的资产 %s",
|
||||||
|
"No kubernetes": "没有kubernetes",
|
||||||
|
"No protocol found.": "无协议",
|
||||||
|
"No route to host": "网络不通(路由不通)",
|
||||||
"NoActiveTerminalTabFound": "未找到活动终端标签页",
|
"NoActiveTerminalTabFound": "未找到活动终端标签页",
|
||||||
"NoData": "无数据",
|
"NoData": "无数据",
|
||||||
"NoLink": "无地址",
|
"NoLink": "无地址",
|
||||||
"NoRunningTerminalFound": "未找到正在运行的终端",
|
"NoRunningTerminalFound": "未找到正在运行的终端",
|
||||||
|
"Node: [ ID.Name(Asset amount) ]": "节点:[ ID.名称(资产数量) ]",
|
||||||
"OnlineUser": "在线用户",
|
"OnlineUser": "在线用户",
|
||||||
"OperationSuccessful": "操作成功",
|
"OperationSuccessful": "操作成功",
|
||||||
|
"Organization": "组织",
|
||||||
"Owner": "管理者",
|
"Owner": "管理者",
|
||||||
|
"Page up: b\tPage down: n": "上一页:b 下一页:n",
|
||||||
|
"Page: %d, Count: %d, Total Page: %d, Total Count: %d": "页码:%d,每页行数:%d,总页数:%d,总数量:%d",
|
||||||
"Paste": "粘贴",
|
"Paste": "粘贴",
|
||||||
"PauseSession": "暂停此会话",
|
"PauseSession": "暂停此会话",
|
||||||
"PermissionDenied": "没有权限",
|
"PermissionDenied": "没有权限",
|
||||||
"PermissionExpired": "权限已过期",
|
"PermissionExpired": "权限已过期",
|
||||||
"PermissionValid": "权限有效",
|
"PermissionValid": "权限有效",
|
||||||
|
"Platform": "平台",
|
||||||
|
"Please waiting for the reviewers to confirm command `%s`, cancel by CTRL+C or CTRL+D.": "请等待审核人复核命令 `%s`,取消按 CTRL+C 或 CTRL+D。",
|
||||||
|
"Please waiting for the reviewers to confirm, enter q to exit. ": "等待审核人复核确认,按 q 回车取消登录。",
|
||||||
"PleaseInput": "请输入",
|
"PleaseInput": "请输入",
|
||||||
"PleaseInputVerifyCode": "请输入验证码",
|
"PleaseInputVerifyCode": "请输入验证码",
|
||||||
"PrimaryUser": "主用户",
|
"PrimaryUser": "主用户",
|
||||||
|
"Protocol": "协议",
|
||||||
"ReadOnly": "只读",
|
"ReadOnly": "只读",
|
||||||
"Reconnect": "重新连接",
|
"Reconnect": "重新连接",
|
||||||
"Refresh": "刷新",
|
"Refresh": "刷新",
|
||||||
|
"Refresh done": "刷新完成",
|
||||||
"Remove": "移除",
|
"Remove": "移除",
|
||||||
"RemoveShareUser": "你已经被移除共享会话",
|
"RemoveShareUser": "你已经被移除共享会话",
|
||||||
"RemoveUser": "移除用户",
|
"RemoveUser": "移除用户",
|
||||||
"Rename": "重命名",
|
"Rename": "重命名",
|
||||||
"ResumeSession": "恢复此会话",
|
"ResumeSession": "恢复此会话",
|
||||||
|
"Reuse SSH connections (%s@%s) [Number of connections: %d]": "复用SSH连接(%s@%s)[连接数量: %d]",
|
||||||
"RightArrow": "前进箭头",
|
"RightArrow": "前进箭头",
|
||||||
"Search": "搜索",
|
"Search": "搜索",
|
||||||
|
"Search: %s": "搜索:%s",
|
||||||
|
"Select account exceed max retry times.": "选择账号超过最大重试次数",
|
||||||
|
"Select protocol exceed max retry times.": "选择协议超过最大重试次数",
|
||||||
"SelectAction": "请选择",
|
"SelectAction": "请选择",
|
||||||
"SelectTheme": "请选择主题",
|
"SelectTheme": "请选择主题",
|
||||||
"Self": "我",
|
"Self": "我",
|
||||||
|
"Session max time reached, disconnect": "会话超过最大连接时间,断开连接",
|
||||||
"SessionDetail": "会话详情",
|
"SessionDetail": "会话详情",
|
||||||
"SessionShare": "会话分享",
|
"SessionShare": "会话分享",
|
||||||
"Settings": "设置",
|
"Settings": "设置",
|
||||||
@@ -96,18 +158,32 @@
|
|||||||
"ShareUser": "分享用户",
|
"ShareUser": "分享用户",
|
||||||
"ShareUserHelpText": "未选择用户,即允许所有人加入",
|
"ShareUserHelpText": "未选择用户,即允许所有人加入",
|
||||||
"Size": "大小",
|
"Size": "大小",
|
||||||
|
"Start domain gateway failed %s": "启动数据库网关失败%s",
|
||||||
|
"Switch language successfully": "切换语言成功",
|
||||||
|
"Switched to %s": "已切换至%s",
|
||||||
"Sync": "同步",
|
"Sync": "同步",
|
||||||
"SyncUserPreferenceFailed": "同步设置失败",
|
"SyncUserPreferenceFailed": "同步设置失败",
|
||||||
"SyncUserPreferenceSuccess": "同步设置成功",
|
"SyncUserPreferenceSuccess": "同步设置成功",
|
||||||
|
"Terminal does not support protocol %s, please use web terminal to access": "该终端不支持 %s 协议,请使用web终端登录",
|
||||||
"TerminalInstanceNotFound": "未找到当前选项卡的终端实例",
|
"TerminalInstanceNotFound": "未找到当前选项卡的终端实例",
|
||||||
"TerminalInstanceNotFoundForCurrentTab": "当前标签页未找到终端实例",
|
"TerminalInstanceNotFoundForCurrentTab": "当前标签页未找到终端实例",
|
||||||
|
"The command '%s' requires review. Continue or not [Y/n]?": "命令 %s 需要复核,是否继续?[Y/N]",
|
||||||
|
"The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?[Y/N]": "您执行的命令存在风险,告警通知将发送给管理员。是否继续?[Y/N]",
|
||||||
"TheCurrentTerminalInstanceWasNotFound": "当前终端实例未找到",
|
"TheCurrentTerminalInstanceWasNotFound": "当前终端实例未找到",
|
||||||
"Theme": "主题",
|
"Theme": "主题",
|
||||||
"ThemeColors": "主题颜色",
|
"ThemeColors": "主题颜色",
|
||||||
"ThemeConfig": "主题",
|
"ThemeConfig": "主题",
|
||||||
|
"Ticket Reviewers: %s": "工单审核人:%s ",
|
||||||
|
"Tips: Enter asset[%s] account ID": "提示:输入资产[%s]的账号ID",
|
||||||
|
"Tips: Enter g+NodeID to display the host under the node, such as g1": "提示:输入 g+节点ID 显示节点下主机,如: g1",
|
||||||
|
"Tips: Enter protocol ID": "提示:输入协议ID",
|
||||||
|
"Tips: To set a default language, go to Personal Settings → Preferences on Web": "提示:如需设置默认语言,请前往 Web 端「个人设置 → 偏好设置」",
|
||||||
|
"Tips: switch language by ID (Current session only)": "提示:输入ID切换语言",
|
||||||
"Transfer": "传输",
|
"Transfer": "传输",
|
||||||
"Type": "类型",
|
"Type": "类型",
|
||||||
"UnableToGenerateWebSocketURL": "无法生成 WebSocket URL, 缺少参数",
|
"UnableToGenerateWebSocketURL": "无法生成 WebSocket URL, 缺少参数",
|
||||||
|
"Unknown error code: %s, detail: %s": "未知错误代码:%s,详情:%s",
|
||||||
|
"Unknown status": "未知状态",
|
||||||
"UpArrow": "向上箭头",
|
"UpArrow": "向上箭头",
|
||||||
"Upload": "上传",
|
"Upload": "上传",
|
||||||
"UploadEnd": "上传已完成,请等待后续处理",
|
"UploadEnd": "上传已完成,请等待后续处理",
|
||||||
@@ -117,11 +193,35 @@
|
|||||||
"UploadTips": "将文件拖到此处,或点击上传",
|
"UploadTips": "将文件拖到此处,或点击上传",
|
||||||
"UploadTitle": "上传文件",
|
"UploadTitle": "上传文件",
|
||||||
"User": "用户",
|
"User": "用户",
|
||||||
|
"Username": "用户名",
|
||||||
"UsingRegularExpressions": "使用正则表达式",
|
"UsingRegularExpressions": "使用正则表达式",
|
||||||
"VerifyCode": "验证码",
|
"VerifyCode": "验证码",
|
||||||
"WaitFileTransfer": "等待文件传输结束",
|
"WaitFileTransfer": "等待文件传输结束",
|
||||||
"Warning": "警告",
|
"Warning": "警告",
|
||||||
"WebSocketClosed": "WebSocket 已关闭",
|
"WebSocketClosed": "WebSocket 已关闭",
|
||||||
"WebSocketConnectionIsClosedHelpText": "WebSocket 连接已关闭,请刷新页面或重新连接。",
|
"WebSocketConnectionIsClosedHelpText": "WebSocket 连接已关闭,请刷新页面或重新连接。",
|
||||||
"Writable": "可写"
|
"Welcome to use JumpServer open source fortress system": "欢迎使用JumpServer开源堡垒机系统",
|
||||||
|
"Writable": "可写",
|
||||||
|
"You don't have permission login %s": "你无权限登陆%s",
|
||||||
|
"You get auth token failed": "你获取认证令牌失败",
|
||||||
|
"display the assets you have permission": "显示您有权限的资产",
|
||||||
|
"display the databases that you have permission": "显示您有权限的数据库",
|
||||||
|
"display the hosts that you have permission": "显示您有权限的主机",
|
||||||
|
"display the kubernetes that you have permission": "显示您有权限的Kubernetes",
|
||||||
|
"display the node that you have permission": "显示您有权限的节点",
|
||||||
|
"exit": "退出",
|
||||||
|
"get connect token err": "获取 connect token 错误",
|
||||||
|
"have no permission to download file": "无权限下载文件",
|
||||||
|
"have no permission to upload file": "无权限上传文件",
|
||||||
|
"i/o timeout": "网络不通(连接超时)",
|
||||||
|
"language switch": "语言切换",
|
||||||
|
"network is unreachable": "网络不通(网络不可达)",
|
||||||
|
"not found matched username %s": "未发现匹配的用户名 %s",
|
||||||
|
"part IP, Hostname, Comment": "部分IP,主机名,备注",
|
||||||
|
"part IP,, Hostname, Comment": "/ + IP,主机名,备注",
|
||||||
|
"print help": "显示帮助",
|
||||||
|
"refresh your assets and nodes": "刷新最新的机器和节点信息",
|
||||||
|
"select one asset to login": "选择其中一个资产登录",
|
||||||
|
"to search login if unique": "搜索登录(如果唯一)",
|
||||||
|
"to search, such as: /192.168": "搜索,如:/192.168"
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,45 @@
|
|||||||
{
|
{
|
||||||
|
"\t%2d) Enter {{.GreenBoldColor}}%s{{.ColorEnd}} to %s.%s": "%d) 輸入 {{.GreenBoldColor}}%s{{.ColorEnd}} 進行%s.%s",
|
||||||
|
"%s approved": "%s 審核通過",
|
||||||
|
"%s node has no assets": "%s節點沒有資產",
|
||||||
|
"%s protocol client not installed.": "%s 協議的客戶端未安裝",
|
||||||
|
"%s rejected": "%s 審核拒絕",
|
||||||
|
"ACL reject": "本次登錄已拒絕,原因是訪問控制策略的限制",
|
||||||
|
"Account <%s> and asset <%s> protocol are inconsistent.": "系統用戶<%s>和資產<%s>協議不一致",
|
||||||
"ActionPerm": "操作權限",
|
"ActionPerm": "操作權限",
|
||||||
|
"Address": "地址",
|
||||||
"AlreadyExistsPleaseRename": "檔案已存在,請重新命名",
|
"AlreadyExistsPleaseRename": "檔案已存在,請重新命名",
|
||||||
|
"Announcement: ": "公告:",
|
||||||
|
"Authentication failed": "認證失敗(用戶名或密碼錯誤)",
|
||||||
"AvailableShortcutKey": "可用快捷鍵",
|
"AvailableShortcutKey": "可用快捷鍵",
|
||||||
"Back": "返回",
|
"Back": "返回",
|
||||||
|
"Back: B/b": "返回:B/b",
|
||||||
"Cancel": "取消",
|
"Cancel": "取消",
|
||||||
|
"Cancel confirm": "取消登錄復核",
|
||||||
|
"Cancel to login asset or max 3 retry": "取消登錄資產或達到3次重試",
|
||||||
"CancelFileUpload": "取消文件上傳",
|
"CancelFileUpload": "取消文件上傳",
|
||||||
"CaseSensitive": "區分大小寫",
|
"CaseSensitive": "區分大小寫",
|
||||||
"Clone Connect": "複製視窗",
|
"Clone Connect": "複製視窗",
|
||||||
"Close All Tabs": "關閉全部",
|
"Close All Tabs": "關閉全部",
|
||||||
"Close Current Tab": "關閉當前",
|
"Close Current Tab": "關閉當前",
|
||||||
|
"Command `%s` is forbidden": "命令 `%s` 是被禁止的 ...",
|
||||||
|
"Comment": "備註",
|
||||||
"Confirm": "確認",
|
"Confirm": "確認",
|
||||||
"ConfirmBtn": "確定",
|
"ConfirmBtn": "確定",
|
||||||
"ConfirmDelete": "您確定要刪除該文件嗎?",
|
"ConfirmDelete": "您確定要刪除該文件嗎?",
|
||||||
"Connect": "連接",
|
"Connect": "連接",
|
||||||
|
"Connect idle more than %d minutes, disconnect": "空閒時間超過%d分鐘,斷開連接",
|
||||||
|
"Connect with api server failed": "連接API服務失敗",
|
||||||
|
"Connecting to %s@%s": "開始連接到 %s@%s",
|
||||||
|
"Connecting to Database %s": "開始連接數據庫 %s",
|
||||||
|
"Connecting to Kubernetes %s": "開始連接Kubernetes %s",
|
||||||
|
"Connecting to Kubernetes %s container %s": "開始連接Kubernetes %s 容器 %s",
|
||||||
|
"Connection refused": "網絡不通(連接拒絕)",
|
||||||
"CopyLink": "複製連結及驗證碼",
|
"CopyLink": "複製連結及驗證碼",
|
||||||
"CopyShareURLSuccess": "複製分享地址成功",
|
"CopyShareURLSuccess": "複製分享地址成功",
|
||||||
|
"Core API failed": "Core API 發生錯誤",
|
||||||
|
"Could copy website URL to notify reviewers: %s": "可複製審核地址,通知審核人:%s",
|
||||||
|
"Create k8s client err: %s": "創建 k8s 客戶端錯誤:%s",
|
||||||
"CreateFolder": "創建資料夾",
|
"CreateFolder": "創建資料夾",
|
||||||
"CreateLink": "創建連結",
|
"CreateLink": "創建連結",
|
||||||
"CreateSuccess": "創建成功",
|
"CreateSuccess": "創建成功",
|
||||||
@@ -27,10 +52,14 @@
|
|||||||
"DownloadProgress": "下載進度",
|
"DownloadProgress": "下載進度",
|
||||||
"DownloadSuccess": "下載成功",
|
"DownloadSuccess": "下載成功",
|
||||||
"Downloading": "正在下載",
|
"Downloading": "正在下載",
|
||||||
|
"Dynamic": "動態帳號",
|
||||||
"EndFileTransfer": "文件傳輸結束",
|
"EndFileTransfer": "文件傳輸結束",
|
||||||
|
"Enter ID number directly login, multiple search use // + field, such as: //16": "提示:輸入資產ID直接登錄,二級搜索使用 // + 欄位,如://192",
|
||||||
"ExceedTransferSize": "超過最大傳輸大小",
|
"ExceedTransferSize": "超過最大傳輸大小",
|
||||||
"Expand": "展開",
|
"Expand": "展開",
|
||||||
"ExpiredTime": "有效期限",
|
"ExpiredTime": "有效期限",
|
||||||
|
"Face ACL is not supported yet. Please use the WebTerminal to connect the asset.": "該終端不支持人臉訪問規則,請使用web終端登錄",
|
||||||
|
"Face verification is not supported yet. Please use the WebTerminal to connect the asset.": "該終端不支持人臉識別認證,請使用web終端登錄。",
|
||||||
"FailedCreateConnection": "創建連接失敗",
|
"FailedCreateConnection": "創建連接失敗",
|
||||||
"FileAlreadyExists": "檔案已存在",
|
"FileAlreadyExists": "檔案已存在",
|
||||||
"FileListError": "獲取文件列表資訊失敗",
|
"FileListError": "獲取文件列表資訊失敗",
|
||||||
@@ -41,10 +70,15 @@
|
|||||||
"FileUploadInterrupted": "文件上傳中斷",
|
"FileUploadInterrupted": "文件上傳中斷",
|
||||||
"Format": "格式",
|
"Format": "格式",
|
||||||
"General": "通用傳輸",
|
"General": "通用傳輸",
|
||||||
|
"Get auth password failed": "你獲取認證令牌失敗",
|
||||||
"GetFileManagerTokenTimeOut": "獲取文件管理 Token 超時",
|
"GetFileManagerTokenTimeOut": "獲取文件管理 Token 超時",
|
||||||
"GetShareUser": "輸入使用者名稱",
|
"GetShareUser": "輸入使用者名稱",
|
||||||
|
"HandleTask does not support protocol %s, please use web terminal to access": "該終端不支持 %s 協議,請使用web終端登錄",
|
||||||
|
"Hostname": "主機名",
|
||||||
"Hotkeys": "快速鍵",
|
"Hotkeys": "快速鍵",
|
||||||
|
"ID": "ID",
|
||||||
"InputVerifyCode": "請輸入驗證碼",
|
"InputVerifyCode": "請輸入驗證碼",
|
||||||
|
"Invalid ID": "無效 ID",
|
||||||
"JoinShare": "加入共享",
|
"JoinShare": "加入共享",
|
||||||
"JoinedWithSuccess": "已成功加入",
|
"JoinedWithSuccess": "已成功加入",
|
||||||
"KubernetesManagement": "Kubernetes 管理",
|
"KubernetesManagement": "Kubernetes 管理",
|
||||||
@@ -53,41 +87,69 @@
|
|||||||
"LeftArrow": "後退箭頭",
|
"LeftArrow": "後退箭頭",
|
||||||
"LinkAddr": "連結地址",
|
"LinkAddr": "連結地址",
|
||||||
"List": "列表",
|
"List": "列表",
|
||||||
|
"Manual": "手動帳號",
|
||||||
"MatchWholeWords": "全字匹配",
|
"MatchWholeWords": "全字匹配",
|
||||||
"Minute": "分鐘",
|
"Minute": "分鐘",
|
||||||
"Minutes": "分",
|
"Minutes": "分",
|
||||||
|
"Must be auto login account for %s": "必須是自動登錄帳號 %s",
|
||||||
|
"Must be unique account for %s": "必須是唯一的帳號 %s",
|
||||||
|
"Must be unique asset for %s": "必須是唯一的資產 %s",
|
||||||
"MustOneFile": "只能選擇一個文件",
|
"MustOneFile": "只能選擇一個文件",
|
||||||
"MustSelectOneFile": "必須選擇一個文件",
|
"MustSelectOneFile": "必須選擇一個文件",
|
||||||
"Name": "名稱",
|
"Name": "名稱",
|
||||||
|
"Need ACL review, continue? (y/n): ": "需要審核,繼續?(y/n):",
|
||||||
|
"Need ticket confirm to execute command, already send email to the reviewers": "需要工單命令執行復核,已發郵件通知審核人",
|
||||||
|
"Need ticket confirm to login, already send email to the reviewers": "需要工單登錄復核,已發郵件通知審核人",
|
||||||
"NewFolder": "新建文件夾",
|
"NewFolder": "新建文件夾",
|
||||||
|
"No Account found.": "未發現賬號",
|
||||||
|
"No Assets": "沒有資產",
|
||||||
|
"No Databases": "無數據庫",
|
||||||
|
"No found asset": "未發現匹配的資產 %s",
|
||||||
|
"No kubernetes": "沒有kubernetes",
|
||||||
|
"No protocol found.": "無協議",
|
||||||
|
"No route to host": "網絡不通(路由不通)",
|
||||||
"NoActiveTerminalTabFound": "未找到活動終端標籤頁",
|
"NoActiveTerminalTabFound": "未找到活動終端標籤頁",
|
||||||
"NoData": "無資料",
|
"NoData": "無資料",
|
||||||
"NoLink": "無地址",
|
"NoLink": "無地址",
|
||||||
"NoRunningTerminalFound": "未找到正在運行的終端",
|
"NoRunningTerminalFound": "未找到正在運行的終端",
|
||||||
|
"Node: [ ID.Name(Asset amount) ]": "節點:[ ID.名稱(資產數量) ]",
|
||||||
"OnlineUser": "在線用戶",
|
"OnlineUser": "在線用戶",
|
||||||
"OperationSuccessful": "操作成功",
|
"OperationSuccessful": "操作成功",
|
||||||
|
"Organization": "組織",
|
||||||
"Owner": "管理者",
|
"Owner": "管理者",
|
||||||
|
"Page up: b\tPage down: n": "上一頁:b 下一頁:n",
|
||||||
|
"Page: %d, Count: %d, Total Page: %d, Total Count: %d": "頁碼:%d,每頁行數:%d,總頁數:%d,總數量:%d",
|
||||||
"Paste": "貼上",
|
"Paste": "貼上",
|
||||||
"PauseSession": "暫停此會話",
|
"PauseSession": "暫停此會話",
|
||||||
"PermissionDenied": "沒有權限",
|
"PermissionDenied": "沒有權限",
|
||||||
"PermissionExpired": "權限已過期",
|
"PermissionExpired": "權限已過期",
|
||||||
"PermissionValid": "權限有效",
|
"PermissionValid": "權限有效",
|
||||||
|
"Platform": "平台",
|
||||||
|
"Please waiting for the reviewers to confirm command `%s`, cancel by CTRL+C or CTRL+D.": "請等待審核人復核命令 `%s`,取消請按 CTRL+C 或 CTRL+D。",
|
||||||
|
"Please waiting for the reviewers to confirm, enter q to exit. ": "等待審核人複核確認,按 q 回車取消登錄。",
|
||||||
"PleaseInput": "請輸入",
|
"PleaseInput": "請輸入",
|
||||||
"PleaseInputVerifyCode": "請輸入驗證碼",
|
"PleaseInputVerifyCode": "請輸入驗證碼",
|
||||||
"PrimaryUser": "主用戶",
|
"PrimaryUser": "主用戶",
|
||||||
|
"Protocol": "協議",
|
||||||
"ReadOnly": "只讀",
|
"ReadOnly": "只讀",
|
||||||
"Reconnect": "重新連線",
|
"Reconnect": "重新連線",
|
||||||
"Refresh": "刷新",
|
"Refresh": "刷新",
|
||||||
|
"Refresh done": "刷新完成",
|
||||||
"Remove": "移除",
|
"Remove": "移除",
|
||||||
"RemoveShareUser": "你已經被移除共享會話",
|
"RemoveShareUser": "你已經被移除共享會話",
|
||||||
"RemoveUser": "移除用戶",
|
"RemoveUser": "移除用戶",
|
||||||
"Rename": "重命名",
|
"Rename": "重命名",
|
||||||
"ResumeSession": "恢復此會話",
|
"ResumeSession": "恢復此會話",
|
||||||
|
"Reuse SSH connections (%s@%s) [Number of connections: %d]": "複用SSH連接(%s@%s)[連接數量: %d]",
|
||||||
"RightArrow": "前進箭頭",
|
"RightArrow": "前進箭頭",
|
||||||
"Search": "搜尋",
|
"Search": "搜尋",
|
||||||
|
"Search: %s": "搜索:%s",
|
||||||
|
"Select account exceed max retry times.": "選擇賬號超過最大重試次數",
|
||||||
|
"Select protocol exceed max retry times.": "選擇協議超過最大重試次數",
|
||||||
"SelectAction": "請選擇",
|
"SelectAction": "請選擇",
|
||||||
"SelectTheme": "請選擇主題",
|
"SelectTheme": "請選擇主題",
|
||||||
"Self": "我",
|
"Self": "我",
|
||||||
|
"Session max time reached, disconnect": "會話超過最大連接時間,斷開連接",
|
||||||
"SessionDetail": "會話詳情",
|
"SessionDetail": "會話詳情",
|
||||||
"SessionShare": "會話分享",
|
"SessionShare": "會話分享",
|
||||||
"Settings": "設置",
|
"Settings": "設置",
|
||||||
@@ -96,18 +158,32 @@
|
|||||||
"ShareUser": "分享用戶",
|
"ShareUser": "分享用戶",
|
||||||
"ShareUserHelpText": "未選擇用戶,即允許所有人加入",
|
"ShareUserHelpText": "未選擇用戶,即允許所有人加入",
|
||||||
"Size": "大小",
|
"Size": "大小",
|
||||||
|
"Start domain gateway failed %s": "啟動資料庫網關失敗%s \n刷新最新的機器和節點資訊 \n命令 %s 需要複核,是否繼續?[Y/N] \n搜索,如:/192.168 \n網絡不通(網絡不可達) \n無資料庫 \n顯示您有權限的資料庫 \n開始連接到 %s@%s \n顯示您有權限的 Kubernetes \n刷新完成 \n節點:[ ID.名稱(資產數量) ] \n切換語言成功 \n選擇協議超過最大重試次數 \n空閒時間超過%d分鐘,斷開連接 \n提示:輸入 g+節點ID 顯示節點下主機,如: g1",
|
||||||
|
"Switch language successfully": "切換語言成功",
|
||||||
|
"Switched to %s": "已切換至%s",
|
||||||
"Sync": "同步",
|
"Sync": "同步",
|
||||||
"SyncUserPreferenceFailed": "同步設定失敗",
|
"SyncUserPreferenceFailed": "同步設定失敗",
|
||||||
"SyncUserPreferenceSuccess": "同步設定成功",
|
"SyncUserPreferenceSuccess": "同步設定成功",
|
||||||
|
"Terminal does not support protocol %s, please use web terminal to access": "該終端不支持 %s 協議,請使用web終端登錄",
|
||||||
"TerminalInstanceNotFound": "未找到當前選項卡的終端實例",
|
"TerminalInstanceNotFound": "未找到當前選項卡的終端實例",
|
||||||
"TerminalInstanceNotFoundForCurrentTab": "當前標籤頁未找到終端實例",
|
"TerminalInstanceNotFoundForCurrentTab": "當前標籤頁未找到終端實例",
|
||||||
|
"The command '%s' requires review. Continue or not [Y/n]?": "命令 %s 需要復核,是否繼續?[Y/N]",
|
||||||
|
"The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?[Y/N]": "您執行的命令存在風險,告警通知將發送給管理員。是否繼續?[Y/N]",
|
||||||
"TheCurrentTerminalInstanceWasNotFound": "當前終端實例未找到",
|
"TheCurrentTerminalInstanceWasNotFound": "當前終端實例未找到",
|
||||||
"Theme": "主題",
|
"Theme": "主題",
|
||||||
"ThemeColors": "主題顏色",
|
"ThemeColors": "主題顏色",
|
||||||
"ThemeConfig": "主題",
|
"ThemeConfig": "主題",
|
||||||
|
"Ticket Reviewers: %s": "工單審核人:%s",
|
||||||
|
"Tips: Enter asset[%s] account ID": "提示:輸入資產[%s]的帳號ID",
|
||||||
|
"Tips: Enter g+NodeID to display the host under the node, such as g1": "提示:輸入 g+節點ID 顯示節點下主機,如: g1",
|
||||||
|
"Tips: Enter protocol ID": "提示:輸入協議ID",
|
||||||
|
"Tips: To set a default language, go to Personal Settings → Preferences on Web": "提示:如需設置默認語言,請前往 Web 端「個人設置 → 偏好設置」",
|
||||||
|
"Tips: switch language by ID (Current session only)": "提示:輸入ID切換語言",
|
||||||
"Transfer": "傳輸",
|
"Transfer": "傳輸",
|
||||||
"Type": "類型",
|
"Type": "類型",
|
||||||
"UnableToGenerateWebSocketURL": "無法生成 WebSocket URL,缺少參數",
|
"UnableToGenerateWebSocketURL": "無法生成 WebSocket URL,缺少參數",
|
||||||
|
"Unknown error code: %s, detail: %s": "未知錯誤代碼:%s,詳情:%s",
|
||||||
|
"Unknown status": "未知狀態",
|
||||||
"UpArrow": "向上箭頭",
|
"UpArrow": "向上箭頭",
|
||||||
"Upload": "上傳",
|
"Upload": "上傳",
|
||||||
"UploadEnd": "上傳已完成,請等待後續處理",
|
"UploadEnd": "上傳已完成,請等待後續處理",
|
||||||
@@ -117,11 +193,35 @@
|
|||||||
"UploadTips": "將文件拖到此處,或點擊上傳",
|
"UploadTips": "將文件拖到此處,或點擊上傳",
|
||||||
"UploadTitle": "上傳文件",
|
"UploadTitle": "上傳文件",
|
||||||
"User": "用戶",
|
"User": "用戶",
|
||||||
|
"Username": "用戶名",
|
||||||
"UsingRegularExpressions": "使用正則表達式",
|
"UsingRegularExpressions": "使用正則表達式",
|
||||||
"VerifyCode": "驗證碼",
|
"VerifyCode": "驗證碼",
|
||||||
"WaitFileTransfer": "等待文件傳輸結束",
|
"WaitFileTransfer": "等待文件傳輸結束",
|
||||||
"Warning": "警告",
|
"Warning": "警告",
|
||||||
"WebSocketClosed": "WebSocket 已關閉",
|
"WebSocketClosed": "WebSocket 已關閉",
|
||||||
"WebSocketConnectionIsClosedHelpText": "WebSocket 連接已關閉,請刷新頁面或重新連接。",
|
"WebSocketConnectionIsClosedHelpText": "WebSocket 連接已關閉,請刷新頁面或重新連接。",
|
||||||
"Writable": "可寫"
|
"Welcome to use JumpServer open source fortress system": "歡迎使用JumpServer開源堡壘機系統",
|
||||||
|
"Writable": "可寫",
|
||||||
|
"You don't have permission login %s": "你無權登錄%s",
|
||||||
|
"You get auth token failed": "您獲取認證令牌失敗",
|
||||||
|
"display the assets you have permission": "顯示您有權限的資產",
|
||||||
|
"display the databases that you have permission": "顯示您有權限的數據庫",
|
||||||
|
"display the hosts that you have permission": "顯示您有權限的主機",
|
||||||
|
"display the kubernetes that you have permission": "顯示您有權限的Kubernetes",
|
||||||
|
"display the node that you have permission": "顯示您有權限的節點",
|
||||||
|
"exit": "退出",
|
||||||
|
"get connect token err": "獲取連接令牌錯誤",
|
||||||
|
"have no permission to download file": "無權限下載文件",
|
||||||
|
"have no permission to upload file": "無權限上傳文件",
|
||||||
|
"i/o timeout": "網絡不通(連接超時)",
|
||||||
|
"language switch": "語言切換",
|
||||||
|
"network is unreachable": "網絡不通(網絡不可達)",
|
||||||
|
"not found matched username %s": "未發現匹配的用戶名 %s",
|
||||||
|
"part IP, Hostname, Comment": "部分IP,主機名,備註",
|
||||||
|
"part IP,, Hostname, Comment": "/ + IP,主機名,備註",
|
||||||
|
"print help": "顯示幫助",
|
||||||
|
"refresh your assets and nodes": "刷新最新的機器和節點信息",
|
||||||
|
"select one asset to login": "選擇其中一個資產登錄",
|
||||||
|
"to search login if unique": "搜索登錄(如果唯一)",
|
||||||
|
"to search, such as: /192.168": "搜尋,如:/192.168"
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,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 name] [AppletHost: publishing machine name] [仅发布机: publishing machine name] [AppletHostOnly: 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",
|
||||||
@@ -448,6 +448,10 @@
|
|||||||
"DangerCommand": "Dangerous command",
|
"DangerCommand": "Dangerous command",
|
||||||
"DangerousCommandNum": "Total dangerous commands",
|
"DangerousCommandNum": "Total dangerous commands",
|
||||||
"Dashboard": "Dashboard",
|
"Dashboard": "Dashboard",
|
||||||
|
"DataMasking": "DataMasking",
|
||||||
|
"DataMaskingFieldsPatternHelpTip": "Supports multiple field names separated by commas, and supports wildcard *\n For example:\nSingle field name: password — only masks the\"password\" field\nMultiple field names: password,secret — masks both\"password\" and\"secret\" fields\nWildcard : password — masks fields whose names start with\"password\"\nWildcard *: .*password — masks fields whose names end with\"password\"\n",
|
||||||
|
"DataMaskingRuleHelpHelpMsg": "When connecting to database assets, you can anonymize query results based on this rule.",
|
||||||
|
"DataMaskingRuleHelpHelpText": "When connecting to database assets, you can anonymize query results based on this rule.",
|
||||||
"Database": "Database",
|
"Database": "Database",
|
||||||
"DatabaseCreate": "Create asset - database",
|
"DatabaseCreate": "Create asset - database",
|
||||||
"DatabasePort": "Database protocol port",
|
"DatabasePort": "Database protocol port",
|
||||||
@@ -573,9 +577,9 @@
|
|||||||
"EsUrl": "Cannot include special char `#`; eg: http://es_user:es_password@es_host:es_port",
|
"EsUrl": "Cannot include special char `#`; eg: http://es_user:es_password@es_host:es_port",
|
||||||
"Every": "Every",
|
"Every": "Every",
|
||||||
"Exclude": "Does not include",
|
"Exclude": "Does not include",
|
||||||
|
"ExcludeAccount": "Exclude accounts",
|
||||||
"ExcludeAsset": "Skipped assets",
|
"ExcludeAsset": "Skipped assets",
|
||||||
"ExcludeSymbol": "Exclude char",
|
"ExcludeSymbol": "Exclude char",
|
||||||
"ExcludeAccount": "Exclude accounts",
|
|
||||||
"ExecCloudSyncErrorMsg": "The cloud account configuration is incomplete, please update and try again.",
|
"ExecCloudSyncErrorMsg": "The cloud account configuration is incomplete, please update and try again.",
|
||||||
"Execute": "Execute",
|
"Execute": "Execute",
|
||||||
"ExecuteAfterSaving": "Execute after saving",
|
"ExecuteAfterSaving": "Execute after saving",
|
||||||
@@ -865,6 +869,7 @@
|
|||||||
"MoveAssetToNode": "Move assets to node",
|
"MoveAssetToNode": "Move assets to node",
|
||||||
"MoveToAsset": "Move to asset",
|
"MoveToAsset": "Move to asset",
|
||||||
"MsgSubscribe": "Subscription",
|
"MsgSubscribe": "Subscription",
|
||||||
|
"MsgTemplate": "Msg Template",
|
||||||
"MyAssets": "My assets",
|
"MyAssets": "My assets",
|
||||||
"MyTickets": "Submitted",
|
"MyTickets": "Submitted",
|
||||||
"NUMBER_REQUIRED": "Must contain numbers",
|
"NUMBER_REQUIRED": "Must contain numbers",
|
||||||
@@ -1035,6 +1040,7 @@
|
|||||||
"PrivilegedOnly": "Privileged only",
|
"PrivilegedOnly": "Privileged only",
|
||||||
"PrivilegedTemplate": "Privileged",
|
"PrivilegedTemplate": "Privileged",
|
||||||
"Processing": "Processing",
|
"Processing": "Processing",
|
||||||
|
"ProcessingMessage": "Processing, please wait...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"ProfileSetting": "Profile info",
|
"ProfileSetting": "Profile info",
|
||||||
"Project": "Project name",
|
"Project": "Project name",
|
||||||
@@ -1148,6 +1154,7 @@
|
|||||||
"ResetSSHKeySuccessMsg": "Email task submitted, user will receive a url to reset shortly",
|
"ResetSSHKeySuccessMsg": "Email task submitted, user will receive a url to reset shortly",
|
||||||
"ResetSSHKeyWarningMsg": "Are you sure you want to send a reset ssh key email to the user?",
|
"ResetSSHKeyWarningMsg": "Are you sure you want to send a reset ssh key email to the user?",
|
||||||
"ResetSecret": "Secret can be changed",
|
"ResetSecret": "Secret can be changed",
|
||||||
|
"ResetSuccessfully": "Reset successfully",
|
||||||
"ResolveSelected": "Resolve selected",
|
"ResolveSelected": "Resolve selected",
|
||||||
"Resource": "Resources",
|
"Resource": "Resources",
|
||||||
"ResourceType": "Resource type",
|
"ResourceType": "Resource type",
|
||||||
@@ -1346,6 +1353,7 @@
|
|||||||
"Support": "Support",
|
"Support": "Support",
|
||||||
"SupportedProtocol": "Protocols",
|
"SupportedProtocol": "Protocols",
|
||||||
"SupportedProtocolHelpText": "Set supported protocols for the asset, you can modify the custom configurations, such as sftp directory, rdp ad domain, etc., by clicking on the set button",
|
"SupportedProtocolHelpText": "Set supported protocols for the asset, you can modify the custom configurations, such as sftp directory, rdp ad domain, etc., by clicking on the set button",
|
||||||
|
"SupportedTypes": "Supported types",
|
||||||
"Sync": "Sync",
|
"Sync": "Sync",
|
||||||
"SyncAction": "Synchronized action",
|
"SyncAction": "Synchronized action",
|
||||||
"SyncDelete": "Sync delete",
|
"SyncDelete": "Sync delete",
|
||||||
@@ -1405,6 +1413,7 @@
|
|||||||
"TemplateCreate": "Create template",
|
"TemplateCreate": "Create template",
|
||||||
"TemplateHelpText": "When selecting a template to add, accounts that do not exist under the asset will be automatically created and pushed",
|
"TemplateHelpText": "When selecting a template to add, accounts that do not exist under the asset will be automatically created and pushed",
|
||||||
"TemplateManagement": "Templates",
|
"TemplateManagement": "Templates",
|
||||||
|
"TemplateVariablesHelpText": "You can select a template and use {{ key }} within the template content to read built-in variables.Note: only the {{ }} syntax is supported; other syntaxes such as {% if title %} are not supported.",
|
||||||
"Templates": "Templates",
|
"Templates": "Templates",
|
||||||
"TencentCloud": "Tencent cloud",
|
"TencentCloud": "Tencent cloud",
|
||||||
"Terminal": "Components",
|
"Terminal": "Components",
|
||||||
@@ -1519,6 +1528,7 @@
|
|||||||
"UserCreate": "Create user",
|
"UserCreate": "Create user",
|
||||||
"UserData": "User data",
|
"UserData": "User data",
|
||||||
"UserDetail": "User details",
|
"UserDetail": "User details",
|
||||||
|
"UserGroup": "User group",
|
||||||
"UserGroupCreate": "Create user group",
|
"UserGroupCreate": "Create user group",
|
||||||
"UserGroupDetail": "User group details",
|
"UserGroupDetail": "User group details",
|
||||||
"UserGroupList": "Groups",
|
"UserGroupList": "Groups",
|
||||||
@@ -1610,6 +1620,7 @@
|
|||||||
"assetId": "Asset ID",
|
"assetId": "Asset ID",
|
||||||
"assetName": "Asset name",
|
"assetName": "Asset name",
|
||||||
"currentTime": "Current time",
|
"currentTime": "Current time",
|
||||||
|
"description": "No data yet",
|
||||||
"disallowSelfUpdateFields": "Not allowed to modify the current fields yourself",
|
"disallowSelfUpdateFields": "Not allowed to modify the current fields yourself",
|
||||||
"forceEnableMFAHelpText": "If force enable, user can not disable by themselves",
|
"forceEnableMFAHelpText": "If force enable, user can not disable by themselves",
|
||||||
"isConsoleCanUse": "is Console page can use",
|
"isConsoleCanUse": "is Console page can use",
|
||||||
@@ -1617,4 +1628,4 @@
|
|||||||
"setVariable": "Set variable",
|
"setVariable": "Set variable",
|
||||||
"userId": "User ID",
|
"userId": "User ID",
|
||||||
"userName": "User name"
|
"userName": "User name"
|
||||||
}
|
}
|
||||||
@@ -447,6 +447,10 @@
|
|||||||
"DangerCommand": "Orden de peligro",
|
"DangerCommand": "Orden de peligro",
|
||||||
"DangerousCommandNum": "Número de comandos peligrosos",
|
"DangerousCommandNum": "Número de comandos peligrosos",
|
||||||
"Dashboard": "panel de control",
|
"Dashboard": "panel de control",
|
||||||
|
"DataMasking": "Desensibilización de datos",
|
||||||
|
"DataMaskingFieldsPatternHelpTip": "Soporte para múltiples nombres de campo, separados por comas, con soporte para comodines *\nPor ejemplo:\nNombre de campo único: password indica que solo se desensibiliza el campo password.\nMúltiples nombres de campo: password,secret indica que se desensibilizan los campos password y secret.\nComodín*: password* indica que se desensibilizan los campos que contienen el prefijo password.\nComodín*: .*password indica que se desensibilizan los campos que contienen el sufijo password.",
|
||||||
|
"DataMaskingRuleHelpHelpMsg": "Al conectar con la base de datos de activos, se puede aplicar esta regla para desensibilizar los resultados de la consulta.",
|
||||||
|
"DataMaskingRuleHelpHelpText": "Al conectar activos de la base de datos, se puede llevar a cabo la desensibilización de los resultados de la consulta según esta regla.",
|
||||||
"Database": "Base de datos",
|
"Database": "Base de datos",
|
||||||
"DatabaseCreate": "crear activo - base de datos",
|
"DatabaseCreate": "crear activo - base de datos",
|
||||||
"DatabasePort": "Puerto del protocolo de la base de datos",
|
"DatabasePort": "Puerto del protocolo de la base de datos",
|
||||||
@@ -571,7 +575,9 @@
|
|||||||
"EsIndex": "es proporcionando el índice predeterminado: jumpserver. Si se habilita el índice por fecha, el valor ingresado se usará como prefijo del índice",
|
"EsIndex": "es proporcionando el índice predeterminado: jumpserver. Si se habilita el índice por fecha, el valor ingresado se usará como prefijo del índice",
|
||||||
"EsUrl": "No puede incluir caracteres especiales `#`; ej: http://es_user:es_password@es_host:es_port",
|
"EsUrl": "No puede incluir caracteres especiales `#`; ej: http://es_user:es_password@es_host:es_port",
|
||||||
"Every": "Cada",
|
"Every": "Cada",
|
||||||
|
"Example": "Ejemplo de valor",
|
||||||
"Exclude": "No incluir",
|
"Exclude": "No incluir",
|
||||||
|
"ExcludeAccount": "Excluir cuenta",
|
||||||
"ExcludeAsset": "Activos omitidos",
|
"ExcludeAsset": "Activos omitidos",
|
||||||
"ExcludeSymbol": "Caracteres excluidos",
|
"ExcludeSymbol": "Caracteres excluidos",
|
||||||
"ExecCloudSyncErrorMsg": "La configuración de la cuenta en la nube está incompleta, por favor actualiza y vuelve a intentarlo",
|
"ExecCloudSyncErrorMsg": "La configuración de la cuenta en la nube está incompleta, por favor actualiza y vuelve a intentarlo",
|
||||||
@@ -865,6 +871,7 @@
|
|||||||
"MoveAssetToNode": "Mover activos al nodo",
|
"MoveAssetToNode": "Mover activos al nodo",
|
||||||
"MoveToAsset": "Mover a activos",
|
"MoveToAsset": "Mover a activos",
|
||||||
"MsgSubscribe": "Suscripción de mensajes",
|
"MsgSubscribe": "Suscripción de mensajes",
|
||||||
|
"MsgTemplate": "Plantilla de mensajes",
|
||||||
"MyAssets": "Mis activos",
|
"MyAssets": "Mis activos",
|
||||||
"MyTickets": "Iniciados por mí",
|
"MyTickets": "Iniciados por mí",
|
||||||
"NUMBER_REQUIRED": "Debe incluir números",
|
"NUMBER_REQUIRED": "Debe incluir números",
|
||||||
@@ -1038,6 +1045,7 @@
|
|||||||
"PrivilegedOnly": "Solo cuentas privilegiadas",
|
"PrivilegedOnly": "Solo cuentas privilegiadas",
|
||||||
"PrivilegedTemplate": "Privilegiado",
|
"PrivilegedTemplate": "Privilegiado",
|
||||||
"Processing": "En proceso",
|
"Processing": "En proceso",
|
||||||
|
"ProcessingMessage": "Tarea en progreso, por favor, espere ⏳",
|
||||||
"Product": "Productos",
|
"Product": "Productos",
|
||||||
"ProfileSetting": "Configuración de información personal",
|
"ProfileSetting": "Configuración de información personal",
|
||||||
"Project": "Nombre del proyecto",
|
"Project": "Nombre del proyecto",
|
||||||
@@ -1152,6 +1160,7 @@
|
|||||||
"ResetSSHKeySuccessMsg": "Tarea de envío de correo electrónico ha sido enviada, el usuario recibirá más tarde un correo electrónico con la clave de reinicio",
|
"ResetSSHKeySuccessMsg": "Tarea de envío de correo electrónico ha sido enviada, el usuario recibirá más tarde un correo electrónico con la clave de reinicio",
|
||||||
"ResetSSHKeyWarningMsg": "¿Está seguro de que desea enviar el correo para restablecer la clave SSH del usuario?",
|
"ResetSSHKeyWarningMsg": "¿Está seguro de que desea enviar el correo para restablecer la clave SSH del usuario?",
|
||||||
"ResetSecret": "Cambio de contraseña permitido",
|
"ResetSecret": "Cambio de contraseña permitido",
|
||||||
|
"ResetSuccessfully": "Restablecimiento exitoso.",
|
||||||
"ResolveSelected": "Resolver lo establecido",
|
"ResolveSelected": "Resolver lo establecido",
|
||||||
"Resource": "Recursos",
|
"Resource": "Recursos",
|
||||||
"ResourceType": "Tipo de recurso",
|
"ResourceType": "Tipo de recurso",
|
||||||
@@ -1352,6 +1361,7 @@
|
|||||||
"Support": "Apoyo",
|
"Support": "Apoyo",
|
||||||
"SupportedProtocol": "Protocolos soportados",
|
"SupportedProtocol": "Protocolos soportados",
|
||||||
"SupportedProtocolHelpText": "Establezca los protocolos compatibles con los activos; al hacer clic en el botón de configuración, podrá modificar la configuración personalizada del protocolo, como el directorio SFTP, el dominio RDP AD, entre otros",
|
"SupportedProtocolHelpText": "Establezca los protocolos compatibles con los activos; al hacer clic en el botón de configuración, podrá modificar la configuración personalizada del protocolo, como el directorio SFTP, el dominio RDP AD, entre otros",
|
||||||
|
"SupportedTypes": "Tipos soportados",
|
||||||
"Sync": "Sincronizar",
|
"Sync": "Sincronizar",
|
||||||
"SyncAction": "Sincronizar Acción",
|
"SyncAction": "Sincronizar Acción",
|
||||||
"SyncDelete": "Sincronizar eliminación",
|
"SyncDelete": "Sincronizar eliminación",
|
||||||
@@ -1412,6 +1422,7 @@
|
|||||||
"TemplateCreate": "Crear plantilla",
|
"TemplateCreate": "Crear plantilla",
|
||||||
"TemplateHelpText": "Al seleccionar una plantilla para añadir, se crearán automáticamente cuentas que no existen en el activo y se enviarán",
|
"TemplateHelpText": "Al seleccionar una plantilla para añadir, se crearán automáticamente cuentas que no existen en el activo y se enviarán",
|
||||||
"TemplateManagement": "Gestión de plantillas",
|
"TemplateManagement": "Gestión de plantillas",
|
||||||
|
"TemplateVariablesHelpText": "Puede elegir una plantilla y utilizar {{ key }} en el contenido de la plantilla para leer variables incorporadas. Tenga en cuenta que solo se admite la sintaxis {{ }}, no se admite ninguna otra. Por ejemplo, {% if title %}",
|
||||||
"Templates": "Plantilla",
|
"Templates": "Plantilla",
|
||||||
"TencentCloud": "Tencent Cloud",
|
"TencentCloud": "Tencent Cloud",
|
||||||
"Terminal": "Configuración de componentes",
|
"Terminal": "Configuración de componentes",
|
||||||
@@ -1525,6 +1536,7 @@
|
|||||||
"UserCreate": "crear usuario",
|
"UserCreate": "crear usuario",
|
||||||
"UserData": "Datos del usuario",
|
"UserData": "Datos del usuario",
|
||||||
"UserDetail": "Detalles del usuario",
|
"UserDetail": "Detalles del usuario",
|
||||||
|
"UserGroup": "Grupo de usuarios",
|
||||||
"UserGroupCreate": "Crear grupo de usuarios",
|
"UserGroupCreate": "Crear grupo de usuarios",
|
||||||
"UserGroupDetail": "Detalles del grupo de usuarios",
|
"UserGroupDetail": "Detalles del grupo de usuarios",
|
||||||
"UserGroupList": "Grupo de usuarios",
|
"UserGroupList": "Grupo de usuarios",
|
||||||
@@ -1617,6 +1629,7 @@
|
|||||||
"assetId": "ID de activo",
|
"assetId": "ID de activo",
|
||||||
"assetName": "Nombre de activo",
|
"assetName": "Nombre de activo",
|
||||||
"currentTime": "Hora actual",
|
"currentTime": "Hora actual",
|
||||||
|
"description": "Sin datos disponibles.",
|
||||||
"disallowSelfUpdateFields": "No se permite modificar el campo actual.",
|
"disallowSelfUpdateFields": "No se permite modificar el campo actual.",
|
||||||
"forceEnableMFAHelpText": "Si se habilita forzosamente, el usuario no podrá desactivarlo por sí mismo",
|
"forceEnableMFAHelpText": "Si se habilita forzosamente, el usuario no podrá desactivarlo por sí mismo",
|
||||||
"isConsoleCanUse": "¿Está disponible la página de gestión?< -SEP->Agregar puerta de enlace al dominio",
|
"isConsoleCanUse": "¿Está disponible la página de gestión?< -SEP->Agregar puerta de enlace al dominio",
|
||||||
|
|||||||
@@ -452,6 +452,10 @@
|
|||||||
"DangerousCommandNum": "危険なコマンド数",
|
"DangerousCommandNum": "危険なコマンド数",
|
||||||
"Dashboard": "ダッシュボード",
|
"Dashboard": "ダッシュボード",
|
||||||
"DataLastUsed": "さいごしようび",
|
"DataLastUsed": "さいごしようび",
|
||||||
|
"DataMasking": "データマスキング",
|
||||||
|
"DataMaskingFieldsPatternHelpTip": "複数のフィールド名をサポートし、カンマで区切ります。ワイルドカード*もサポートしています。\n例えば:\n単一フィールド名: password は password フィールドのみマスキングします。\n複数フィールド名: password, secret は password と secret フィールドの両方をマスキングします。\nワイルドカード*: password* は、password プレフィックスを含むフィールド名をマスキングします。\nワイルドカード*: .*password は、password サフィックスを含むフィールド名をマスキングします。",
|
||||||
|
"DataMaskingRuleHelpHelpMsg": "データベース資産に接続する際、これに基づいてクエリ結果をマスキングすることができます。",
|
||||||
|
"DataMaskingRuleHelpHelpText": "データベース資産に接続する際は、このルールに従ってクエリ結果をマスキングできます。",
|
||||||
"Database": "データベース",
|
"Database": "データベース",
|
||||||
"DatabaseCreate": "資産-データベースの作成",
|
"DatabaseCreate": "資産-データベースの作成",
|
||||||
"DatabasePort": "データベースプロトコルポート",
|
"DatabasePort": "データベースプロトコルポート",
|
||||||
@@ -576,7 +580,9 @@
|
|||||||
"EsIndex": "es はデフォルト index:jumpserverを提供します。日付でインデックスを作成する設定が有効な場合、入力値はインデックスのプレフィックスとして使用されます",
|
"EsIndex": "es はデフォルト index:jumpserverを提供します。日付でインデックスを作成する設定が有効な場合、入力値はインデックスのプレフィックスとして使用されます",
|
||||||
"EsUrl": "特殊文字 `#` は含むことができません;例: http://es_user:es_password@es_host:es_port",
|
"EsUrl": "特殊文字 `#` は含むことができません;例: http://es_user:es_password@es_host:es_port",
|
||||||
"Every": "毎",
|
"Every": "毎",
|
||||||
|
"Example": "例の値",
|
||||||
"Exclude": "除外",
|
"Exclude": "除外",
|
||||||
|
"ExcludeAccount": "アカウント除外",
|
||||||
"ExcludeAsset": "スキップされた資産",
|
"ExcludeAsset": "スキップされた資産",
|
||||||
"ExcludeSymbol": "文字の除外",
|
"ExcludeSymbol": "文字の除外",
|
||||||
"ExecCloudSyncErrorMsg": "クラウドアカウントの設定が完全でないので、更新して再試行してください",
|
"ExecCloudSyncErrorMsg": "クラウドアカウントの設定が完全でないので、更新して再試行してください",
|
||||||
@@ -870,6 +876,7 @@
|
|||||||
"MoveAssetToNode": "アセットをノードに移動",
|
"MoveAssetToNode": "アセットをノードに移動",
|
||||||
"MoveToAsset": "資産へ移動",
|
"MoveToAsset": "資産へ移動",
|
||||||
"MsgSubscribe": "メッセージの購読",
|
"MsgSubscribe": "メッセージの購読",
|
||||||
|
"MsgTemplate": "メッセージテンプレート",
|
||||||
"MyAssets": "私の資産",
|
"MyAssets": "私の資産",
|
||||||
"MyTickets": "私が始めた",
|
"MyTickets": "私が始めた",
|
||||||
"NUMBER_REQUIRED": "数字を含める必要があります",
|
"NUMBER_REQUIRED": "数字を含める必要があります",
|
||||||
@@ -1043,6 +1050,7 @@
|
|||||||
"PrivilegedOnly": "特権アカウントのみ",
|
"PrivilegedOnly": "特権アカウントのみ",
|
||||||
"PrivilegedTemplate": "特別な権限の",
|
"PrivilegedTemplate": "特別な権限の",
|
||||||
"Processing": "処理中",
|
"Processing": "処理中",
|
||||||
|
"ProcessingMessage": "タスクを実行中です。しばらくお待ちください ⏳",
|
||||||
"Product": "商品",
|
"Product": "商品",
|
||||||
"ProfileSetting": "個人情報設定",
|
"ProfileSetting": "個人情報設定",
|
||||||
"Project": "プロジェクト名",
|
"Project": "プロジェクト名",
|
||||||
@@ -1157,6 +1165,7 @@
|
|||||||
"ResetSSHKeySuccessMsg": "メール送信タスクが提出されました。ユーザーは後でリセットキーのメールを受け取ります",
|
"ResetSSHKeySuccessMsg": "メール送信タスクが提出されました。ユーザーは後でリセットキーのメールを受け取ります",
|
||||||
"ResetSSHKeyWarningMsg": "ユーザーのSSH Keyをリセットするメールを送信してもよろしいですか?",
|
"ResetSSHKeyWarningMsg": "ユーザーのSSH Keyをリセットするメールを送信してもよろしいですか?",
|
||||||
"ResetSecret": " パスワード変更可能 ",
|
"ResetSecret": " パスワード変更可能 ",
|
||||||
|
"ResetSuccessfully": "リセット成功",
|
||||||
"ResolveSelected": "解決選択",
|
"ResolveSelected": "解決選択",
|
||||||
"Resource": "リソース",
|
"Resource": "リソース",
|
||||||
"ResourceType": "リソースタイプ",
|
"ResourceType": "リソースタイプ",
|
||||||
@@ -1357,6 +1366,7 @@
|
|||||||
"Support": "サポート",
|
"Support": "サポート",
|
||||||
"SupportedProtocol": "サポートされているプロトコル",
|
"SupportedProtocol": "サポートされているプロトコル",
|
||||||
"SupportedProtocolHelpText": "資産がサポートするプロトコルを設定します。設定ボタンをクリックして、プロトコルのカスタム設定を変更することができます。例えば、SFTPディレクトリやRDP ADドメインなど",
|
"SupportedProtocolHelpText": "資産がサポートするプロトコルを設定します。設定ボタンをクリックして、プロトコルのカスタム設定を変更することができます。例えば、SFTPディレクトリやRDP ADドメインなど",
|
||||||
|
"SupportedTypes": "サポートされているタイプ",
|
||||||
"Sync": "同期する",
|
"Sync": "同期する",
|
||||||
"SyncAction": "同期アクション",
|
"SyncAction": "同期アクション",
|
||||||
"SyncDelete": "同期削除",
|
"SyncDelete": "同期削除",
|
||||||
@@ -1417,6 +1427,7 @@
|
|||||||
"TemplateCreate": "テンプレート作成",
|
"TemplateCreate": "テンプレート作成",
|
||||||
"TemplateHelpText": "テンプレートを選択して追加すると、資産の下に存在しないアカウントが自動的に作成され、プッシュされます",
|
"TemplateHelpText": "テンプレートを選択して追加すると、資産の下に存在しないアカウントが自動的に作成され、プッシュされます",
|
||||||
"TemplateManagement": "テンプレート一覧",
|
"TemplateManagement": "テンプレート一覧",
|
||||||
|
"TemplateVariablesHelpText": "テンプレートの中で {{ key }} を使って組み込み変数を読み取るテンプレートを選択できます。注意:サポートされているのは {{ }} 構文のみで、他の構文はサポートされていません。例えば {% if title %}",
|
||||||
"Templates": "テンプレート",
|
"Templates": "テンプレート",
|
||||||
"TencentCloud": "テンセントクラウド",
|
"TencentCloud": "テンセントクラウド",
|
||||||
"Terminal": "コンポーネント設定",
|
"Terminal": "コンポーネント設定",
|
||||||
@@ -1530,6 +1541,7 @@
|
|||||||
"UserCreate": "ユーザーを作成する",
|
"UserCreate": "ユーザーを作成する",
|
||||||
"UserData": "ユーザーデータ",
|
"UserData": "ユーザーデータ",
|
||||||
"UserDetail": "ユーザーの詳細",
|
"UserDetail": "ユーザーの詳細",
|
||||||
|
"UserGroup": "ユーザーグループ",
|
||||||
"UserGroupCreate": "ユーザーグループの作成",
|
"UserGroupCreate": "ユーザーグループの作成",
|
||||||
"UserGroupDetail": "ユーザーグループ詳細",
|
"UserGroupDetail": "ユーザーグループ詳細",
|
||||||
"UserGroupList": "ユーザーグループ",
|
"UserGroupList": "ユーザーグループ",
|
||||||
@@ -1622,6 +1634,7 @@
|
|||||||
"assetId": "資産ID",
|
"assetId": "資産ID",
|
||||||
"assetName": "資産名",
|
"assetName": "資産名",
|
||||||
"currentTime": "現在の時間",
|
"currentTime": "現在の時間",
|
||||||
|
"description": "データはありません。",
|
||||||
"disallowSelfUpdateFields": "現在のフィールドを自分で変更することは許可されていません",
|
"disallowSelfUpdateFields": "現在のフィールドを自分で変更することは許可されていません",
|
||||||
"forceEnableMFAHelpText": "強制的に有効化すると、ユーザーは自分で無効化することができません。",
|
"forceEnableMFAHelpText": "強制的に有効化すると、ユーザーは自分で無効化することができません。",
|
||||||
"isConsoleCanUse": "管理ページの利用可能性",
|
"isConsoleCanUse": "管理ページの利用可能性",
|
||||||
|
|||||||
@@ -447,6 +447,10 @@
|
|||||||
"DangerCommand": "위험 명령",
|
"DangerCommand": "위험 명령",
|
||||||
"DangerousCommandNum": "위험 명령 수",
|
"DangerousCommandNum": "위험 명령 수",
|
||||||
"Dashboard": "대시보드",
|
"Dashboard": "대시보드",
|
||||||
|
"DataMasking": "데이터 탈민",
|
||||||
|
"DataMaskingFieldsPatternHelpTip": "여러 개의 필드명을 지원하며, 쉼표로 구분됩니다. 또한 와일드카드*도 지원합니다. \n예를 들어: \n단일 필드명: password는 password 필드만 비식별화합니다. \n다수의 필드명: password,secret은 password와 secret 필드를 비식별화합니다. \n와일드카드*: password*는 password 접두사가 포함된 필드명을 비식별화합니다. \n와일드카드*: .*password는 password 접미사가 포함된 필드명을 비식별화합니다.",
|
||||||
|
"DataMaskingRuleHelpHelpMsg": "데이터베이스 자산에 연결할 때, 이 규칙에 따라 쿼리 결과를 비감시 처리할 수 있습니다.",
|
||||||
|
"DataMaskingRuleHelpHelpText": "데이터베이스 자산에 연결할 때, 이 규칙에 따라 조회 결과의 민감 정보를 비공개 처리할 수 있습니다.",
|
||||||
"Database": "데이터베이스",
|
"Database": "데이터베이스",
|
||||||
"DatabaseCreate": "로그인 검토",
|
"DatabaseCreate": "로그인 검토",
|
||||||
"DatabasePort": "라벨",
|
"DatabasePort": "라벨",
|
||||||
@@ -571,7 +575,9 @@
|
|||||||
"EsIndex": "es 기본 인덱스 제공: jumpserver. 날짜별 인덱스 생성을 활성화하면 입력된 값이 인덱스 접두사로 사용됩니다",
|
"EsIndex": "es 기본 인덱스 제공: jumpserver. 날짜별 인덱스 생성을 활성화하면 입력된 값이 인덱스 접두사로 사용됩니다",
|
||||||
"EsUrl": "특수 문자 `#`를 포함할 수 없습니다; 예: http://es_user:es_password@es_host:es_port",
|
"EsUrl": "특수 문자 `#`를 포함할 수 없습니다; 예: http://es_user:es_password@es_host:es_port",
|
||||||
"Every": "매우",
|
"Every": "매우",
|
||||||
|
"Example": "예시 값",
|
||||||
"Exclude": "포함되지 않음",
|
"Exclude": "포함되지 않음",
|
||||||
|
"ExcludeAccount": "계정 제외",
|
||||||
"ExcludeAsset": "건너뛴 자산",
|
"ExcludeAsset": "건너뛴 자산",
|
||||||
"ExcludeSymbol": "제외 문자",
|
"ExcludeSymbol": "제외 문자",
|
||||||
"ExecCloudSyncErrorMsg": "클라우드 계정 구성에 문제가 있습니다. 업데이트 후 다시 시도하십시오.",
|
"ExecCloudSyncErrorMsg": "클라우드 계정 구성에 문제가 있습니다. 업데이트 후 다시 시도하십시오.",
|
||||||
@@ -865,6 +871,7 @@
|
|||||||
"MoveAssetToNode": "이동 자산을 노드로< -SEP-> 역사 기록< -SEP-> 생체 정보< -SEP-> 자산을 노드에 추가< -SEP-> 포함< -SEP-> 장시간 미로그인< -SEP-> 권한 있는 자산< -SEP-> 정기적으로< -SEP-> 변경 후< -SEP-> 연결 가능< -SEP-> 위험< -SEP-> 자산 업데이트 - 데이터베이스< -SEP-> 동기화< -SEP-> 녹화 다운로드< -SEP-> 실행 경로 입력",
|
"MoveAssetToNode": "이동 자산을 노드로< -SEP-> 역사 기록< -SEP-> 생체 정보< -SEP-> 자산을 노드에 추가< -SEP-> 포함< -SEP-> 장시간 미로그인< -SEP-> 권한 있는 자산< -SEP-> 정기적으로< -SEP-> 변경 후< -SEP-> 연결 가능< -SEP-> 위험< -SEP-> 자산 업데이트 - 데이터베이스< -SEP-> 동기화< -SEP-> 녹화 다운로드< -SEP-> 실행 경로 입력",
|
||||||
"MoveToAsset": "자산으로 이동",
|
"MoveToAsset": "자산으로 이동",
|
||||||
"MsgSubscribe": "메시지 구독",
|
"MsgSubscribe": "메시지 구독",
|
||||||
|
"MsgTemplate": "메시지 템플릿",
|
||||||
"MyAssets": "템플릿",
|
"MyAssets": "템플릿",
|
||||||
"MyTickets": "내가 시작한",
|
"MyTickets": "내가 시작한",
|
||||||
"NUMBER_REQUIRED": "숫자를 포함해야 합니다",
|
"NUMBER_REQUIRED": "숫자를 포함해야 합니다",
|
||||||
@@ -1038,6 +1045,7 @@
|
|||||||
"PrivilegedOnly": "특권 계정만",
|
"PrivilegedOnly": "특권 계정만",
|
||||||
"PrivilegedTemplate": "특권의",
|
"PrivilegedTemplate": "특권의",
|
||||||
"Processing": "처리 중",
|
"Processing": "처리 중",
|
||||||
|
"ProcessingMessage": "작업 진행 중입니다. 잠시만 기다려 주십시오 ⏳",
|
||||||
"Product": "제품",
|
"Product": "제품",
|
||||||
"ProfileSetting": "개인 정보 설정",
|
"ProfileSetting": "개인 정보 설정",
|
||||||
"Project": "프로젝트 이름",
|
"Project": "프로젝트 이름",
|
||||||
@@ -1152,6 +1160,7 @@
|
|||||||
"ResetSSHKeySuccessMsg": "메일 전송 작업이 제출되었습니다. 사용자는 나중에 재설정 키 메일을 받게 될 것입니다.",
|
"ResetSSHKeySuccessMsg": "메일 전송 작업이 제출되었습니다. 사용자는 나중에 재설정 키 메일을 받게 될 것입니다.",
|
||||||
"ResetSSHKeyWarningMsg": "사용자의 SSH 키를 재설정하는 이메일을 전송하시겠습니까?",
|
"ResetSSHKeyWarningMsg": "사용자의 SSH 키를 재설정하는 이메일을 전송하시겠습니까?",
|
||||||
"ResetSecret": "변경 가능 비밀번호",
|
"ResetSecret": "변경 가능 비밀번호",
|
||||||
|
"ResetSuccessfully": "재설정 성공",
|
||||||
"ResolveSelected": "선택한 사항 해결",
|
"ResolveSelected": "선택한 사항 해결",
|
||||||
"Resource": "리소스",
|
"Resource": "리소스",
|
||||||
"ResourceType": "자원 유형",
|
"ResourceType": "자원 유형",
|
||||||
@@ -1352,6 +1361,7 @@
|
|||||||
"Support": "지원",
|
"Support": "지원",
|
||||||
"SupportedProtocol": "지원하는 프로토콜",
|
"SupportedProtocol": "지원하는 프로토콜",
|
||||||
"SupportedProtocolHelpText": "자산 지원 프로토콜을 설정하십시오. 설정 버튼을 클릭하면 SFTP 디렉토리, RDP AD 도메인 등과 같은 프로토콜에 대한 사용자 정의 구성을 수정할 수 있습니다.",
|
"SupportedProtocolHelpText": "자산 지원 프로토콜을 설정하십시오. 설정 버튼을 클릭하면 SFTP 디렉토리, RDP AD 도메인 등과 같은 프로토콜에 대한 사용자 정의 구성을 수정할 수 있습니다.",
|
||||||
|
"SupportedTypes": "지원되는 유형",
|
||||||
"Sync": "동기화",
|
"Sync": "동기화",
|
||||||
"SyncAction": "동기화 행동",
|
"SyncAction": "동기화 행동",
|
||||||
"SyncDelete": "동기화 삭제",
|
"SyncDelete": "동기화 삭제",
|
||||||
@@ -1412,6 +1422,7 @@
|
|||||||
"TemplateCreate": "템플릿 생성",
|
"TemplateCreate": "템플릿 생성",
|
||||||
"TemplateHelpText": "템플릿 선택 시, 자산에 존재하지 않는 계정을 자동으로 생성하고 전송",
|
"TemplateHelpText": "템플릿 선택 시, 자산에 존재하지 않는 계정을 자동으로 생성하고 전송",
|
||||||
"TemplateManagement": "템플릿 관리",
|
"TemplateManagement": "템플릿 관리",
|
||||||
|
"TemplateVariablesHelpText": "템플릿에서 {{ key }}를 사용하여 내장 변수를 읽어올 수 있는 템플릿을 선택할 수 있습니다. 주의: {{ }} 문법만 지원하며, 다른 문법은 지원하지 않습니다. 예를 들어 {% if title %}",
|
||||||
"Templates": "기업 버전",
|
"Templates": "기업 버전",
|
||||||
"TencentCloud": "텐센트 클라우드",
|
"TencentCloud": "텐센트 클라우드",
|
||||||
"Terminal": "컴포넌트 설정",
|
"Terminal": "컴포넌트 설정",
|
||||||
@@ -1525,6 +1536,7 @@
|
|||||||
"UserCreate": "사용자 생성",
|
"UserCreate": "사용자 생성",
|
||||||
"UserData": "사용자 데이터",
|
"UserData": "사용자 데이터",
|
||||||
"UserDetail": "사용자 세부사항",
|
"UserDetail": "사용자 세부사항",
|
||||||
|
"UserGroup": "사용자 그룹",
|
||||||
"UserGroupCreate": "사용자 그룹 생성",
|
"UserGroupCreate": "사용자 그룹 생성",
|
||||||
"UserGroupDetail": "사용자 그룹 세부정보",
|
"UserGroupDetail": "사용자 그룹 세부정보",
|
||||||
"UserGroupList": "사용자 그룹",
|
"UserGroupList": "사용자 그룹",
|
||||||
@@ -1617,6 +1629,7 @@
|
|||||||
"assetId": "자산 ID",
|
"assetId": "자산 ID",
|
||||||
"assetName": "자산 이름",
|
"assetName": "자산 이름",
|
||||||
"currentTime": "현재 시간",
|
"currentTime": "현재 시간",
|
||||||
|
"description": "데이터가 없습니다.",
|
||||||
"disallowSelfUpdateFields": "현재 필드를 스스로 수정할 수 없음",
|
"disallowSelfUpdateFields": "현재 필드를 스스로 수정할 수 없음",
|
||||||
"forceEnableMFAHelpText": "강제로 활성화하면 사용자가 스스로 비활성화할 수 없음",
|
"forceEnableMFAHelpText": "강제로 활성화하면 사용자가 스스로 비활성화할 수 없음",
|
||||||
"isConsoleCanUse": "관리 페이지 사용 가능 여부",
|
"isConsoleCanUse": "관리 페이지 사용 가능 여부",
|
||||||
|
|||||||
@@ -448,6 +448,10 @@
|
|||||||
"DangerCommand": "Comando perigoso",
|
"DangerCommand": "Comando perigoso",
|
||||||
"DangerousCommandNum": "Número de Comandos Perigosos",
|
"DangerousCommandNum": "Número de Comandos Perigosos",
|
||||||
"Dashboard": "Painel ",
|
"Dashboard": "Painel ",
|
||||||
|
"DataMasking": "Desensibilização de dados",
|
||||||
|
"DataMaskingFieldsPatternHelpTip": "Suporta múltiplos nomes de campo, separados por vírgula, e aceita caracteres coringa *\nPor exemplo:\nNome de campo único: password indica que apenas o campo password será desensibilizado.\nMúltiplos nomes de campo: password, secret indica que os campos password e secret serão desensibilizados.\nCaractere coringa *: password* indica que todos os campos que contêm o prefixo password serão desensibilizados.\nCaractere coringa *: .*password indica que todos os campos que contêm o sufixo password serão desensibilizados.",
|
||||||
|
"DataMaskingRuleHelpHelpMsg": "Ao conectar ao banco de dados de ativos, é possível aplicar esta regra para desensibilizar os resultados da consulta.",
|
||||||
|
"DataMaskingRuleHelpHelpText": "Ao conectar-se ao ativo do banco de dados, é possível aplicar esta regra para mascarar os resultados da consulta.",
|
||||||
"Database": "Banco de dados",
|
"Database": "Banco de dados",
|
||||||
"DatabaseCreate": "Criar ativo - Banco de dados",
|
"DatabaseCreate": "Criar ativo - Banco de dados",
|
||||||
"DatabasePort": "Porta do protocolo do banco de dados",
|
"DatabasePort": "Porta do protocolo do banco de dados",
|
||||||
@@ -572,7 +576,9 @@
|
|||||||
"EsIndex": "'es' fornece o índice padrão: 'jumpserver'. Se você ativar a criação de índices por data, o valor inserido será usado como prefixo do índice.",
|
"EsIndex": "'es' fornece o índice padrão: 'jumpserver'. Se você ativar a criação de índices por data, o valor inserido será usado como prefixo do índice.",
|
||||||
"EsUrl": "Não pode conter o caractere especial `#`; ex: http://es_user:es_password@es_host:es_port",
|
"EsUrl": "Não pode conter o caractere especial `#`; ex: http://es_user:es_password@es_host:es_port",
|
||||||
"Every": "Cada",
|
"Every": "Cada",
|
||||||
|
"Example": "Exemplo de valor",
|
||||||
"Exclude": "Não inclui",
|
"Exclude": "Não inclui",
|
||||||
|
"ExcludeAccount": "Excluir conta",
|
||||||
"ExcludeAsset": "Ativos ignorados",
|
"ExcludeAsset": "Ativos ignorados",
|
||||||
"ExcludeSymbol": " Excluir caracteres",
|
"ExcludeSymbol": " Excluir caracteres",
|
||||||
"ExecCloudSyncErrorMsg": "A configuração da conta em nuvem não está completa, atualize e tente novamente",
|
"ExecCloudSyncErrorMsg": "A configuração da conta em nuvem não está completa, atualize e tente novamente",
|
||||||
@@ -866,6 +872,7 @@
|
|||||||
"MoveAssetToNode": "Mover ativos para o nó",
|
"MoveAssetToNode": "Mover ativos para o nó",
|
||||||
"MoveToAsset": "Mover para ativos ",
|
"MoveToAsset": "Mover para ativos ",
|
||||||
"MsgSubscribe": "Assinatura de mensagem",
|
"MsgSubscribe": "Assinatura de mensagem",
|
||||||
|
"MsgTemplate": "Modelo de mensagem",
|
||||||
"MyAssets": "Meus ativos",
|
"MyAssets": "Meus ativos",
|
||||||
"MyTickets": "Iniciados por Mim",
|
"MyTickets": "Iniciados por Mim",
|
||||||
"NUMBER_REQUIRED": "Deve conter números",
|
"NUMBER_REQUIRED": "Deve conter números",
|
||||||
@@ -1039,6 +1046,7 @@
|
|||||||
"PrivilegedOnly": "Apenas contas privilegiadas",
|
"PrivilegedOnly": "Apenas contas privilegiadas",
|
||||||
"PrivilegedTemplate": "Privilégios",
|
"PrivilegedTemplate": "Privilégios",
|
||||||
"Processing": "Em processamento",
|
"Processing": "Em processamento",
|
||||||
|
"ProcessingMessage": "Tarefa em andamento, por favor, aguarde ⏳",
|
||||||
"Product": "Produto",
|
"Product": "Produto",
|
||||||
"ProfileSetting": "Configurações de Informações Pessoais",
|
"ProfileSetting": "Configurações de Informações Pessoais",
|
||||||
"Project": "Nome do Projeto",
|
"Project": "Nome do Projeto",
|
||||||
@@ -1153,6 +1161,7 @@
|
|||||||
"ResetSSHKeySuccessMsg": "A tarefa de envio de e-mail foi enviada, o usuário receberá um e-mail de chave de redefinição mais tarde",
|
"ResetSSHKeySuccessMsg": "A tarefa de envio de e-mail foi enviada, o usuário receberá um e-mail de chave de redefinição mais tarde",
|
||||||
"ResetSSHKeyWarningMsg": "Você tem certeza que deseja enviar o e-mail para resetar a chave SSH do usuário?",
|
"ResetSSHKeyWarningMsg": "Você tem certeza que deseja enviar o e-mail para resetar a chave SSH do usuário?",
|
||||||
"ResetSecret": " Pode alterar a senha ",
|
"ResetSecret": " Pode alterar a senha ",
|
||||||
|
"ResetSuccessfully": "Redefinição bem-sucedida.",
|
||||||
"ResolveSelected": "Resolver seleção",
|
"ResolveSelected": "Resolver seleção",
|
||||||
"Resource": "Recursos",
|
"Resource": "Recursos",
|
||||||
"ResourceType": "Tipo de recurso",
|
"ResourceType": "Tipo de recurso",
|
||||||
@@ -1353,6 +1362,7 @@
|
|||||||
"Support": "Suporte",
|
"Support": "Suporte",
|
||||||
"SupportedProtocol": "Protocolos suportados",
|
"SupportedProtocol": "Protocolos suportados",
|
||||||
"SupportedProtocolHelpText": "Configure os protocolos suportados pelos ativos, clicar no botão de configurações permite a personalização, como diretórios SFTP, domínios RDP AD, etc.",
|
"SupportedProtocolHelpText": "Configure os protocolos suportados pelos ativos, clicar no botão de configurações permite a personalização, como diretórios SFTP, domínios RDP AD, etc.",
|
||||||
|
"SupportedTypes": "Tipos suportados",
|
||||||
"Sync": "Sincronizar",
|
"Sync": "Sincronizar",
|
||||||
"SyncAction": "Action de sincronização",
|
"SyncAction": "Action de sincronização",
|
||||||
"SyncDelete": "Sincronizar e excluir",
|
"SyncDelete": "Sincronizar e excluir",
|
||||||
@@ -1413,6 +1423,7 @@
|
|||||||
"TemplateCreate": "Criar modelo",
|
"TemplateCreate": "Criar modelo",
|
||||||
"TemplateHelpText": "Ao selecionar para adicionar um modelo, uma conta que não existe no ativo será criativamente criada e impulsionada",
|
"TemplateHelpText": "Ao selecionar para adicionar um modelo, uma conta que não existe no ativo será criativamente criada e impulsionada",
|
||||||
"TemplateManagement": "Lista de Modelos",
|
"TemplateManagement": "Lista de Modelos",
|
||||||
|
"TemplateVariablesHelpText": "Você pode escolher um modelo e usar {{ key }} no conteúdo do modelo para ler variáveis incorporadas. Observe que apenas a sintaxe {{ }} é suportada; outras sintaxes não são. Por exemplo {% if title %}",
|
||||||
"Templates": "Modelo",
|
"Templates": "Modelo",
|
||||||
"TencentCloud": "Nuvem Tencent",
|
"TencentCloud": "Nuvem Tencent",
|
||||||
"Terminal": "Configuração do componente",
|
"Terminal": "Configuração do componente",
|
||||||
@@ -1526,6 +1537,7 @@
|
|||||||
"UserCreate": "Criar usuário",
|
"UserCreate": "Criar usuário",
|
||||||
"UserData": "Dados do usuário",
|
"UserData": "Dados do usuário",
|
||||||
"UserDetail": "Detalhes do usuário",
|
"UserDetail": "Detalhes do usuário",
|
||||||
|
"UserGroup": "Grupo de usuários",
|
||||||
"UserGroupCreate": "Criar Grupo de Usuários",
|
"UserGroupCreate": "Criar Grupo de Usuários",
|
||||||
"UserGroupDetail": "Detalhes do grupo de usuários",
|
"UserGroupDetail": "Detalhes do grupo de usuários",
|
||||||
"UserGroupList": "Grupo de usuários",
|
"UserGroupList": "Grupo de usuários",
|
||||||
@@ -1618,6 +1630,7 @@
|
|||||||
"assetId": "ID do ativo",
|
"assetId": "ID do ativo",
|
||||||
"assetName": "Nome do ativo",
|
"assetName": "Nome do ativo",
|
||||||
"currentTime": "Hora atual",
|
"currentTime": "Hora atual",
|
||||||
|
"description": "Nenhum dado disponível.",
|
||||||
"disallowSelfUpdateFields": "Não é permitido alterar o campo atual",
|
"disallowSelfUpdateFields": "Não é permitido alterar o campo atual",
|
||||||
"forceEnableMFAHelpText": "Se for habilitado forçosamente, o usuário não pode desativar por conta própria",
|
"forceEnableMFAHelpText": "Se for habilitado forçosamente, o usuário não pode desativar por conta própria",
|
||||||
"isConsoleCanUse": "Se a página de gerenciamento está disponível",
|
"isConsoleCanUse": "Se a página de gerenciamento está disponível",
|
||||||
|
|||||||
@@ -5,14 +5,14 @@
|
|||||||
"AWS_Int": "AWS (Международный)",
|
"AWS_Int": "AWS (Международный)",
|
||||||
"About": "О программе",
|
"About": "О программе",
|
||||||
"Accept": "Принять",
|
"Accept": "Принять",
|
||||||
"AccessDistribution": "Распределение посещений",
|
"AccessDistribution": "Распределение доступа",
|
||||||
"AccessIP": "Белый список IP",
|
"AccessIP": "Белый список IP",
|
||||||
"AccessKey": "Ключ доступа",
|
"AccessKey": "Ключ доступа",
|
||||||
"Account": "Информация об УЗ",
|
"Account": "Информация об УЗ",
|
||||||
"AccountActivities": "Активность учетной записи",
|
"AccountActivities": "Активность учетной записи",
|
||||||
"AccountAndPasswordChangeRank": "Изменение пароля аккаунта по рейтингу",
|
"AccountAndPasswordChangeRank": "Рейтинг изменений паролей и учётных записей",
|
||||||
"AccountAutomationOverview": "Обзор автоматизации",
|
"AccountAutomationOverview": "Обзор автоматизации УЗ",
|
||||||
"AccountAutomationReport": "Автоматизированный отчет по аккаунтам",
|
"AccountAutomationReport": "Отчет об автоматизации учетных записей",
|
||||||
"AccountBackup": "Резервное копирование УЗ",
|
"AccountBackup": "Резервное копирование УЗ",
|
||||||
"AccountBackupCreate": "Создать резервную копию УЗ",
|
"AccountBackupCreate": "Создать резервную копию УЗ",
|
||||||
"AccountBackupDetail": "Подробности резервного копирования УЗ",
|
"AccountBackupDetail": "Подробности резервного копирования УЗ",
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
"AccountBackupUpdate": "Обновить резервную копию УЗ",
|
"AccountBackupUpdate": "Обновить резервную копию УЗ",
|
||||||
"AccountChangeSecret": "Изменение пароля учетной записи",
|
"AccountChangeSecret": "Изменение пароля учетной записи",
|
||||||
"AccountChangeSecretDetail": "Подробности изменения пароля учетной записи",
|
"AccountChangeSecretDetail": "Подробности изменения пароля учетной записи",
|
||||||
"AccountConnectivityStatusDistribution": "Распределение состояния доступности аккаунтов",
|
"AccountConnectivityStatusDistribution": "Распределение статусов подключаемости УЗ",
|
||||||
"AccountCreationSourceDistribution": "Распределение источников создания аккаунтов",
|
"AccountCreationSourceDistribution": "Распределение источников создания УЗ",
|
||||||
"AccountData": "Данные учетной записи",
|
"AccountData": "Данные учетной записи",
|
||||||
"AccountDeleteConfirmMsg": "Удаление учетной записи. Продолжить?",
|
"AccountDeleteConfirmMsg": "Удаление учетной записи. Продолжить?",
|
||||||
"AccountDeleted": "Удаление учетной записи",
|
"AccountDeleted": "Удаление учетной записи",
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"AccountDiscoverTaskUpdate": "Обновить задачу обнаружения учетной записи",
|
"AccountDiscoverTaskUpdate": "Обновить задачу обнаружения учетной записи",
|
||||||
"AccountExportTips": "Экспортируемая информация содержит зашифрованные данные учетных записей, что относится к конфиденциальной информации. Формат экспорта — зашифрованный zip-файл (если не установлен пароль шифрования, пожалуйста, настройте его в Персональной информации).",
|
"AccountExportTips": "Экспортируемая информация содержит зашифрованные данные учетных записей, что относится к конфиденциальной информации. Формат экспорта — зашифрованный zip-файл (если не установлен пароль шифрования, пожалуйста, настройте его в Персональной информации).",
|
||||||
"AccountList": "Учетные записи",
|
"AccountList": "Учетные записи",
|
||||||
"AccountOverview": "Обзор аккаунтов",
|
"AccountOverview": "Обзор учетных записей",
|
||||||
"AccountPasswordChangeTrends": "Тенденции изменения паролей аккаунтов",
|
"AccountPasswordChangeTrends": "Тенденции изменения паролей аккаунтов",
|
||||||
"AccountPolicy": "Политика учетной записи",
|
"AccountPolicy": "Политика учетной записи",
|
||||||
"AccountPolicyHelpText": "При создании учетных записей, не соответствующих требованиям, например: несоответствующий тип ключа, ограничение уникальности, можно выбрать одну из вышеуказанных стратегий.",
|
"AccountPolicyHelpText": "При создании учетных записей, не соответствующих требованиям, например: несоответствующий тип ключа, ограничение уникальности, можно выбрать одну из вышеуказанных стратегий.",
|
||||||
@@ -42,11 +42,11 @@
|
|||||||
"AccountPushList": "Публикация УЗ",
|
"AccountPushList": "Публикация УЗ",
|
||||||
"AccountPushTask": "Задача публикации учетной записи",
|
"AccountPushTask": "Задача публикации учетной записи",
|
||||||
"AccountPushUpdate": "Обновление УЗ для публикации",
|
"AccountPushUpdate": "Обновление УЗ для публикации",
|
||||||
"AccountReport": "Отчет по аккаунтам",
|
"AccountReport": "Отчет по УЗ",
|
||||||
"AccountResult": "Успешное или неудачное изменение секрета УЗ",
|
"AccountResult": "Успешное или неудачное изменение секрета УЗ",
|
||||||
"AccountSelectHelpText": "В список учетных записей добавляется имя пользователя",
|
"AccountSelectHelpText": "В списке учетных записей отображается имя пользователя",
|
||||||
"AccountSessions": "Сессии учетной записи",
|
"AccountSessions": "Сессии учетной записи",
|
||||||
"AccountStatisticsReport": "Отчет по учетным записяч",
|
"AccountStatisticsReport": "Отчет по учетным записям",
|
||||||
"AccountStorage": "Хранилище учетных записей",
|
"AccountStorage": "Хранилище учетных записей",
|
||||||
"AccountSummary": "Сводная информация об УЗ",
|
"AccountSummary": "Сводная информация об УЗ",
|
||||||
"AccountTemplate": "Шаблон учетной записи",
|
"AccountTemplate": "Шаблон учетной записи",
|
||||||
@@ -129,7 +129,6 @@
|
|||||||
"Applets": "RemoteApp",
|
"Applets": "RemoteApp",
|
||||||
"Applicant": "Заявитель",
|
"Applicant": "Заявитель",
|
||||||
"ApplicationDetail": "Информация о приложении",
|
"ApplicationDetail": "Информация о приложении",
|
||||||
"Applicationes": "ApplicationHello",
|
|
||||||
"Applications": "Приложения",
|
"Applications": "Приложения",
|
||||||
"ApplyAsset": "Запрос актива",
|
"ApplyAsset": "Запрос актива",
|
||||||
"ApplyFromCMDFilterRule": "Правила фильтрации команд",
|
"ApplyFromCMDFilterRule": "Правила фильтрации команд",
|
||||||
@@ -153,10 +152,10 @@
|
|||||||
"AssetACLCreate": "Создать правило подключения активов",
|
"AssetACLCreate": "Создать правило подключения активов",
|
||||||
"AssetACLDetail": "Подробности правила подключения активов",
|
"AssetACLDetail": "Подробности правила подключения активов",
|
||||||
"AssetACLUpdate": "Обновить правила подключения активов",
|
"AssetACLUpdate": "Обновить правила подключения активов",
|
||||||
"AssetACLs": "Связь активов",
|
"AssetACLs": "Правила подключения активов",
|
||||||
"AssetAccount": "Учетные записи",
|
"AssetAccount": "Учетные записи",
|
||||||
"AssetAccountDetail": "Подробности учетной записи",
|
"AssetAccountDetail": "Подробности учетной записи",
|
||||||
"AssetActivityReport": "Отчет о деятельности активов",
|
"AssetActivityReport": "Отчет по использованию активов",
|
||||||
"AssetAddress": "Активы (IP/Имя хоста)",
|
"AssetAddress": "Активы (IP/Имя хоста)",
|
||||||
"AssetAmount": "Количество активов",
|
"AssetAmount": "Количество активов",
|
||||||
"AssetAndNode": "Активы/Папки",
|
"AssetAndNode": "Активы/Папки",
|
||||||
@@ -170,7 +169,7 @@
|
|||||||
"AssetListHelpMessage": "Слева расположено дерево активов, правый клик позволяет создать, удалить или изменить папки дерева. Управление активами также организовано в виде папок, справа находятся активы, относящиеся к данной папке",
|
"AssetListHelpMessage": "Слева расположено дерево активов, правый клик позволяет создать, удалить или изменить папки дерева. Управление активами также организовано в виде папок, справа находятся активы, относящиеся к данной папке",
|
||||||
"AssetLoginACLHelpMsg": "Подключение к активам можно контролировать, исходя из IP-адреса пользователя и временного интервала, чтобы определить возможность подключения к активу.",
|
"AssetLoginACLHelpMsg": "Подключение к активам можно контролировать, исходя из IP-адреса пользователя и временного интервала, чтобы определить возможность подключения к активу.",
|
||||||
"AssetLoginACLHelpText": "Подключение к активам можно контролировать, исходя из IP-адреса пользователя и временного интервала, чтобы определить возможность подключения к активу.",
|
"AssetLoginACLHelpText": "Подключение к активам можно контролировать, исходя из IP-адреса пользователя и временного интервала, чтобы определить возможность подключения к активу.",
|
||||||
"AssetLoginTrends": "Тенденция входа в активы",
|
"AssetLoginTrends": "Тенденции входа в активы",
|
||||||
"AssetName": "Название актива",
|
"AssetName": "Название актива",
|
||||||
"AssetOverview": "Обзор активов",
|
"AssetOverview": "Обзор активов",
|
||||||
"AssetPermission": "Доступ к активам",
|
"AssetPermission": "Доступ к активам",
|
||||||
@@ -181,8 +180,8 @@
|
|||||||
"AssetPermissionUpdate": "Обновить правила доступа к активам",
|
"AssetPermissionUpdate": "Обновить правила доступа к активам",
|
||||||
"AssetPermsAmount": "Количество правил доступа",
|
"AssetPermsAmount": "Количество правил доступа",
|
||||||
"AssetProtocolHelpText": "! Протоколы, поддерживаемые активами, ограничены платформой, нажмите кнопку настроек, чтобы просмотреть настройки протоколов. Если требуется обновление, пожалуйста, обновите платформу",
|
"AssetProtocolHelpText": "! Протоколы, поддерживаемые активами, ограничены платформой, нажмите кнопку настроек, чтобы просмотреть настройки протоколов. Если требуется обновление, пожалуйста, обновите платформу",
|
||||||
"AssetReport": "Отчет об активах",
|
"AssetReport": "Отчет по активам",
|
||||||
"AssetStatisticsReport": "Отчет по статистике активов",
|
"AssetStatisticsReport": "Статистика активов",
|
||||||
"AssetTree": "Дерево активов",
|
"AssetTree": "Дерево активов",
|
||||||
"AssetTypeDistribution": "Распределение типов активов",
|
"AssetTypeDistribution": "Распределение типов активов",
|
||||||
"Assets": "Активы",
|
"Assets": "Активы",
|
||||||
@@ -191,7 +190,7 @@
|
|||||||
"AssetsSelected": " Активов Выбрано",
|
"AssetsSelected": " Активов Выбрано",
|
||||||
"AssetsTotal": "Всего активов",
|
"AssetsTotal": "Всего активов",
|
||||||
"AssignedInfo": "Информация об одобрении",
|
"AssignedInfo": "Информация об одобрении",
|
||||||
"Assignee": "Ответсвенный исполнитель",
|
"Assignee": "Ответственный исполнитель",
|
||||||
"Assignees": "Ожидающие исполнители",
|
"Assignees": "Ожидающие исполнители",
|
||||||
"AttrName": "Имя атрибута",
|
"AttrName": "Имя атрибута",
|
||||||
"AttrValue": "Значение атрибута",
|
"AttrValue": "Значение атрибута",
|
||||||
@@ -300,10 +299,10 @@
|
|||||||
"ChangePasswordOverview": "Обзор изменения паролей",
|
"ChangePasswordOverview": "Обзор изменения паролей",
|
||||||
"ChangeSecret": "Изменить секрет",
|
"ChangeSecret": "Изменить секрет",
|
||||||
"ChangeSecretAccountHelpText": "Для учетных записей в одном активе, если существует связь переключения su, смена пароля не должна выполняться в одной задаче, а должна быть разделена на две задачи для выполнения отдельно.",
|
"ChangeSecretAccountHelpText": "Для учетных записей в одном активе, если существует связь переключения su, смена пароля не должна выполняться в одной задаче, а должна быть разделена на две задачи для выполнения отдельно.",
|
||||||
"ChangeSecretDashboard": "Панель смены пароля аккаунта",
|
"ChangeSecretDashboard": "Панель смены секрета УЗ",
|
||||||
"ChangeSecretFailAccounts": "Неудачная смена секрета УЗ",
|
"ChangeSecretFailAccounts": "Неудачная смена секрета УЗ",
|
||||||
"ChangeSecretParams": "Параметры изменения секрета",
|
"ChangeSecretParams": "Параметры изменения секрета",
|
||||||
"ChangeSecretStatus": "Состояние смены пароля",
|
"ChangeSecretStatus": "Состояние смены секрета",
|
||||||
"ChangeSecretTask": "Задача смены секрета УЗ",
|
"ChangeSecretTask": "Задача смены секрета УЗ",
|
||||||
"ChangeViewHelpText": "Нажмите, чтобы переключиться на другой вид",
|
"ChangeViewHelpText": "Нажмите, чтобы переключиться на другой вид",
|
||||||
"Chat": "Чат",
|
"Chat": "Чат",
|
||||||
@@ -352,7 +351,6 @@
|
|||||||
"CommandFilterACLHelpMsg": "С помощью фильтрации команд вы можете контролировать возможность отправки команд активам. В зависимости от установленных вами правил некоторые команды могут быть разрешены, а другие запрещены.",
|
"CommandFilterACLHelpMsg": "С помощью фильтрации команд вы можете контролировать возможность отправки команд активам. В зависимости от установленных вами правил некоторые команды могут быть разрешены, а другие запрещены.",
|
||||||
"CommandFilterACLHelpText": "С помощью фильтрации команд вы можете контролировать возможность отправки команд активам. В зависимости от установленных вами правил некоторые команды могут быть разрешены, а другие запрещены.",
|
"CommandFilterACLHelpText": "С помощью фильтрации команд вы можете контролировать возможность отправки команд активам. В зависимости от установленных вами правил некоторые команды могут быть разрешены, а другие запрещены.",
|
||||||
"CommandFilterACLUpdate": "Обновление правила фильтрации команд",
|
"CommandFilterACLUpdate": "Обновление правила фильтрации команд",
|
||||||
"CommandFilterACLs": "Правила фильтрации команд",
|
|
||||||
"CommandFilterRuleContentHelpText": "По одной команде в строке",
|
"CommandFilterRuleContentHelpText": "По одной команде в строке",
|
||||||
"CommandFilterRules": "Правила фильтрации команд",
|
"CommandFilterRules": "Правила фильтрации команд",
|
||||||
"CommandGroup": "Группа команд",
|
"CommandGroup": "Группа команд",
|
||||||
@@ -366,7 +364,7 @@
|
|||||||
"CommandsTotal": "Всего команд",
|
"CommandsTotal": "Всего команд",
|
||||||
"Comment": "Описание",
|
"Comment": "Описание",
|
||||||
"CommentHelpText": "Описание будет отображаться при наведении курсора на дереве активов пользователя на странице Luna. Обычные пользователи могут просматривать эти комментарии, поэтому не указывайте конфиденциальную информацию.",
|
"CommentHelpText": "Описание будет отображаться при наведении курсора на дереве активов пользователя на странице Luna. Обычные пользователи могут просматривать эти комментарии, поэтому не указывайте конфиденциальную информацию.",
|
||||||
"Common": "Универсальный",
|
"Common": "Общий",
|
||||||
"CommunityEdition": "Редакция Community",
|
"CommunityEdition": "Редакция Community",
|
||||||
"Component": "Компонент",
|
"Component": "Компонент",
|
||||||
"ComponentMonitor": "Мониторинг",
|
"ComponentMonitor": "Мониторинг",
|
||||||
@@ -390,13 +388,13 @@
|
|||||||
"ConnectMethodAclDetail": "Детали правила метода подключения",
|
"ConnectMethodAclDetail": "Детали правила метода подключения",
|
||||||
"ConnectWebSocketError": "Соединение с веб-сокетом не удалось",
|
"ConnectWebSocketError": "Соединение с веб-сокетом не удалось",
|
||||||
"Connectable": "Возможно подключение",
|
"Connectable": "Возможно подключение",
|
||||||
"ConnectedDirectoryServices": "Связанная служба каталога",
|
"ConnectedDirectoryServices": "Связанные службы каталога",
|
||||||
"ConnectionCount": "Количество соединений",
|
"ConnectionCount": "Количество подключений",
|
||||||
"ConnectionDropped": "Соединение разорвано",
|
"ConnectionDropped": "Соединение разорвано",
|
||||||
"ConnectionToken": "Токен подключения",
|
"ConnectionToken": "Токен подключения",
|
||||||
"ConnectionTokenList": "Токен подключения - это информация для аутентификации, которая используется для совмещения аутентификации и подключения активов. Он поддерживает вход пользователя в активы одним щелчком мыши. В настоящее время поддерживаются следующие компоненты: koko, lion, magnus, razor и т.д.",
|
"ConnectionTokenList": "Токен подключения - это информация для аутентификации, которая используется для совмещения аутентификации и подключения активов. Он поддерживает вход пользователя в активы одним щелчком мыши. В настоящее время поддерживаются следующие компоненты: koko, lion, magnus, razor и т.д.",
|
||||||
"Console": "Консоль",
|
"Console": "Консоль",
|
||||||
"ConsoleDashboard": "Консольная панель управления",
|
"ConsoleDashboard": "Панель управления",
|
||||||
"Consult": "Консультация",
|
"Consult": "Консультация",
|
||||||
"ContainAttachment": "Содержит вложение",
|
"ContainAttachment": "Содержит вложение",
|
||||||
"Containers": "Контейнер",
|
"Containers": "Контейнер",
|
||||||
@@ -449,6 +447,10 @@
|
|||||||
"DangerCommand": "Опасная команда",
|
"DangerCommand": "Опасная команда",
|
||||||
"DangerousCommandNum": "Всего опасных команд",
|
"DangerousCommandNum": "Всего опасных команд",
|
||||||
"Dashboard": "Панель инструментов",
|
"Dashboard": "Панель инструментов",
|
||||||
|
"DataMasking": "Демаскировка данных",
|
||||||
|
"DataMaskingFieldsPatternHelpTip": "Поддержка нескольких имен полей, разделенных запятой, поддержка подстановочных знаков *\nНапример:\nОдно имя поля: password означает, что будет проведено действие по хранению в тайне поля password.\nНесколько имен полей: password, secret означает сохранение в тайне полей password и secret.\nПодстановочный знак *: password* означает, что действие будет применено к полям, содержащим префикс password.\nПодстановочный знак *: .*password означает, что действие будет применено к полям, содержащим суффикс password.",
|
||||||
|
"DataMaskingRuleHelpHelpMsg": "При подключении к базе данных активов результаты запроса могут быть обработаны в соответствии с этим правилом для обеспечения безопасности данных.",
|
||||||
|
"DataMaskingRuleHelpHelpText": "При подключении к базе данных активов можно обезопасить результаты запроса в соответствии с данным правилом.",
|
||||||
"Database": "База данных",
|
"Database": "База данных",
|
||||||
"DatabaseCreate": "Создать актив - база данных",
|
"DatabaseCreate": "Создать актив - база данных",
|
||||||
"DatabasePort": "Порт протокола базы данных",
|
"DatabasePort": "Порт протокола базы данных",
|
||||||
@@ -539,10 +541,10 @@
|
|||||||
"EditRecipient": "Изменить получателя",
|
"EditRecipient": "Изменить получателя",
|
||||||
"EditSecret": "Изменить секрет",
|
"EditSecret": "Изменить секрет",
|
||||||
"Edition": "Версия",
|
"Edition": "Версия",
|
||||||
"Effective": "Вступить в силу",
|
"Effective": "Активно",
|
||||||
"Email": "Электронная почта",
|
"Email": "Электронная почта",
|
||||||
"EmailContent": "Настройка содержания",
|
"EmailContent": "Настройка содержания",
|
||||||
"EmailHelpText": "Пожалуйста, нажмите кнопку 'Отправить', чтобы сохранить текущую конфигурацию, а затем нажмите 'Проверить соединение', чтобы убедиться, что информация вступила в силу",
|
"EmailHelpText": "Пожалуйста, нажмите кнопку 'Отправить', чтобы сохранить текущую конфигурацию, а затем нажмите 'Тестовое соединение', чтобы убедиться, чтобы настройки вступили в силу",
|
||||||
"EmailTemplate": "Шаблон",
|
"EmailTemplate": "Шаблон",
|
||||||
"EmailTemplateHelpTip": "Шаблон электронной почты используется для отправки электронных писем и включает префикс темы электронного письма и содержимое электронного письма.",
|
"EmailTemplateHelpTip": "Шаблон электронной почты используется для отправки электронных писем и включает префикс темы электронного письма и содержимое электронного письма.",
|
||||||
"EmailTest": "Тестовое соединение",
|
"EmailTest": "Тестовое соединение",
|
||||||
@@ -573,7 +575,9 @@
|
|||||||
"EsIndex": "es предоставляет индекс по умолчанию: jumpserver. Если включено создание индекса по дате, то введенное значение будет использоваться в качестве префикса индекса",
|
"EsIndex": "es предоставляет индекс по умолчанию: jumpserver. Если включено создание индекса по дате, то введенное значение будет использоваться в качестве префикса индекса",
|
||||||
"EsUrl": "Не может содержать специальные символы `#`; например: http://es_user:es_password@es_host:es_port",
|
"EsUrl": "Не может содержать специальные символы `#`; например: http://es_user:es_password@es_host:es_port",
|
||||||
"Every": "Каждый",
|
"Every": "Каждый",
|
||||||
|
"Example": "Пример",
|
||||||
"Exclude": "Не содержит",
|
"Exclude": "Не содержит",
|
||||||
|
"ExcludeAccount": "Исключить учетную запись",
|
||||||
"ExcludeAsset": "Пропущенные активы",
|
"ExcludeAsset": "Пропущенные активы",
|
||||||
"ExcludeSymbol": "Исключить символ",
|
"ExcludeSymbol": "Исключить символ",
|
||||||
"ExecCloudSyncErrorMsg": "Выполнить",
|
"ExecCloudSyncErrorMsg": "Выполнить",
|
||||||
@@ -672,7 +676,7 @@
|
|||||||
"HistoryDate": "Дата",
|
"HistoryDate": "Дата",
|
||||||
"HistoryPassword": "История паролей",
|
"HistoryPassword": "История паролей",
|
||||||
"HistoryRecord": "История записей",
|
"HistoryRecord": "История записей",
|
||||||
"Host": "Хост.",
|
"Host": "Хост",
|
||||||
"HostCreate": "Создать актив - хост",
|
"HostCreate": "Создать актив - хост",
|
||||||
"HostDeployment": "Развертывание машины публикации",
|
"HostDeployment": "Развертывание машины публикации",
|
||||||
"HostUpdate": "Обновить актив - хост",
|
"HostUpdate": "Обновить актив - хост",
|
||||||
@@ -688,7 +692,7 @@
|
|||||||
"IPNetworkSegment": "Диапазон IP",
|
"IPNetworkSegment": "Диапазон IP",
|
||||||
"IPType": "Тип IP",
|
"IPType": "Тип IP",
|
||||||
"Id": "ID",
|
"Id": "ID",
|
||||||
"IdP": "Поставщик идентификации",
|
"IdP": "Поставщик аутентификации",
|
||||||
"IdeaContent": "Я хочу, чтобы ты выступил в роли терминала Linux. Я буду вводить команды, а ты будешь отвечать тем, что должен отображать терминал. Я прошу отвечать только в одном уникальном блоке кода, без дополнительных комментариев. Когда мне нужно будет что-то тебе сказать, я помещу текст в фигурные скобки{замечание текста}.",
|
"IdeaContent": "Я хочу, чтобы ты выступил в роли терминала Linux. Я буду вводить команды, а ты будешь отвечать тем, что должен отображать терминал. Я прошу отвечать только в одном уникальном блоке кода, без дополнительных комментариев. Когда мне нужно будет что-то тебе сказать, я помещу текст в фигурные скобки{замечание текста}.",
|
||||||
"IdeaTitle": "🌱 терминал Linux",
|
"IdeaTitle": "🌱 терминал Linux",
|
||||||
"IdentityDomain": "Домен идентификации",
|
"IdentityDomain": "Домен идентификации",
|
||||||
@@ -781,7 +785,7 @@
|
|||||||
"LicenseForTest": "Лицензия на тестирование, данная лицензия предназначена только для тестирования (poc) и демонстрации",
|
"LicenseForTest": "Лицензия на тестирование, данная лицензия предназначена только для тестирования (poc) и демонстрации",
|
||||||
"LicenseReachedAssetAmountLimit": "Количество активов превышает лимит, установленный лицензией",
|
"LicenseReachedAssetAmountLimit": "Количество активов превышает лимит, установленный лицензией",
|
||||||
"LicenseWillBe": "Лицензия истекает через",
|
"LicenseWillBe": "Лицензия истекает через",
|
||||||
"LinkedDomains": "Связанный домен",
|
"LinkedDomains": "Связанные домены",
|
||||||
"ListPreference": "Настройка списка",
|
"ListPreference": "Настройка списка",
|
||||||
"LoadTemplate": "Загрузить из шаблона",
|
"LoadTemplate": "Загрузить из шаблона",
|
||||||
"Loading": "Загрузка",
|
"Loading": "Загрузка",
|
||||||
@@ -797,7 +801,7 @@
|
|||||||
"LoginConfirm": "Проверка входа",
|
"LoginConfirm": "Проверка входа",
|
||||||
"LoginConfirmUser": "Подтверждает вход",
|
"LoginConfirmUser": "Подтверждает вход",
|
||||||
"LoginCount": "Количество входов",
|
"LoginCount": "Количество входов",
|
||||||
"LoginCtyDistribution": "Распределение городов входа",
|
"LoginCtyDistribution": "Вход по городам",
|
||||||
"LoginDate": "Дата входа",
|
"LoginDate": "Дата входа",
|
||||||
"LoginFailed": "Вход не удался",
|
"LoginFailed": "Вход не удался",
|
||||||
"LoginFrom": "Источник входа",
|
"LoginFrom": "Источник входа",
|
||||||
@@ -857,7 +861,7 @@
|
|||||||
"Min": "Мин.",
|
"Min": "Мин.",
|
||||||
"MinNumber30": "Число должно быть больше или равно 30",
|
"MinNumber30": "Число должно быть больше или равно 30",
|
||||||
"Modify": "Изменить",
|
"Modify": "Изменить",
|
||||||
"ModifyTheTargetUserTopTank": "Изменение рейтинга целевых пользователей",
|
"ModifyTheTargetUserTopTank": "Топ пользователей с измененными паролями",
|
||||||
"Module": "Модуль",
|
"Module": "Модуль",
|
||||||
"Monday": "Понедельник",
|
"Monday": "Понедельник",
|
||||||
"Monitor": "Мониторинг",
|
"Monitor": "Мониторинг",
|
||||||
@@ -867,6 +871,7 @@
|
|||||||
"MoveAssetToNode": "Переместить актив в папку",
|
"MoveAssetToNode": "Переместить актив в папку",
|
||||||
"MoveToAsset": "Переместить в активы",
|
"MoveToAsset": "Переместить в активы",
|
||||||
"MsgSubscribe": "Подписка",
|
"MsgSubscribe": "Подписка",
|
||||||
|
"MsgTemplate": "Шаблон сообщения",
|
||||||
"MyAssets": "Мои активы",
|
"MyAssets": "Мои активы",
|
||||||
"MyTickets": "Мои запросы",
|
"MyTickets": "Мои запросы",
|
||||||
"NUMBER_REQUIRED": "Должен содержать цифры",
|
"NUMBER_REQUIRED": "Должен содержать цифры",
|
||||||
@@ -874,7 +879,7 @@
|
|||||||
"NavHelp": "Ссылки на навигационную панель",
|
"NavHelp": "Ссылки на навигационную панель",
|
||||||
"Navigation": "Навигация",
|
"Navigation": "Навигация",
|
||||||
"NeedReLogin": "Необходимо войти повторно",
|
"NeedReLogin": "Необходимо войти повторно",
|
||||||
"NeedUpdatePassword": "Необходимость изменения пароля",
|
"NeedUpdatePassword": "Требуется смена пароля",
|
||||||
"NeverLogin": "Никогда не входил",
|
"NeverLogin": "Никогда не входил",
|
||||||
"New": "Создать",
|
"New": "Создать",
|
||||||
"NewAccountsFound": "Найдены новые УЗ",
|
"NewAccountsFound": "Найдены новые УЗ",
|
||||||
@@ -911,7 +916,7 @@
|
|||||||
"NonRunnableAssets": "Неработающие активы",
|
"NonRunnableAssets": "Неработающие активы",
|
||||||
"None": "Нет",
|
"None": "Нет",
|
||||||
"NormalLoad": "Нормальная",
|
"NormalLoad": "Нормальная",
|
||||||
"NotEnableMfa": "MFA не активирована",
|
"NotEnableMfa": "МФА не активирована",
|
||||||
"NotEqual": "Не равно",
|
"NotEqual": "Не равно",
|
||||||
"NotSet": "Не установлено",
|
"NotSet": "Не установлено",
|
||||||
"NotSpecialEmoji": "Ввод специальных эмодзи не допускается",
|
"NotSpecialEmoji": "Ввод специальных эмодзи не допускается",
|
||||||
@@ -949,10 +954,10 @@
|
|||||||
"OpenStatus": "На одобрении",
|
"OpenStatus": "На одобрении",
|
||||||
"OpenTicket": "Создать заявку",
|
"OpenTicket": "Создать заявку",
|
||||||
"OperateLog": "Журналы операций",
|
"OperateLog": "Журналы операций",
|
||||||
"OperatingSystemDistributionOfLoginAssets": "Распределение операционных систем для входа в активы",
|
"OperatingSystemDistributionOfLoginAssets": "Распределение ОС для входа в активы",
|
||||||
"OperationLogNum": "Журналы операций",
|
"OperationLogNum": "Журналы операций",
|
||||||
"Operator": "Операционный пользователь",
|
"Operator": "Пользователь‑исполнитель",
|
||||||
"OperatorGeographicDistribution": "Географическое распределение активных пользователей",
|
"OperatorGeographicDistribution": "Распределение по регионам пользователей‑исполнителей",
|
||||||
"Options": "Параметры",
|
"Options": "Параметры",
|
||||||
"OracleDBNameHelpText": "Введите SID или имя службы (Service Name) базы данных Oracle",
|
"OracleDBNameHelpText": "Введите SID или имя службы (Service Name) базы данных Oracle",
|
||||||
"OrgAdmin": "Администратор организации",
|
"OrgAdmin": "Администратор организации",
|
||||||
@@ -975,13 +980,13 @@
|
|||||||
"Overview": "Обзор",
|
"Overview": "Обзор",
|
||||||
"PageNext": "Дальше",
|
"PageNext": "Дальше",
|
||||||
"PagePrev": "Назад",
|
"PagePrev": "Назад",
|
||||||
"PamDashboard": "Панель привилегированных аккаунтов",
|
"PamDashboard": "Панель PAM",
|
||||||
"Params": "Параметры",
|
"Params": "Параметры",
|
||||||
"ParamsHelpText": "Настройки параметров пароля в настоящее время действуют только для активов типа хост.",
|
"ParamsHelpText": "Настройки параметров пароля в настоящее время действуют только для активов типа хост.",
|
||||||
"PassKey": "Ключ доступа",
|
"PassKey": "Ключ доступа",
|
||||||
"Passkey": "Passkey",
|
"Passkey": "Passkey",
|
||||||
"PasskeyAddDisableInfo": "Ваш источник аутентификации - {source}, добавление Passkey не поддерживается",
|
"PasskeyAddDisableInfo": "Ваш источник аутентификации - {source}, добавление Passkey не поддерживается",
|
||||||
"PasskeySummary": "Безпарольная биометрическая аутентификация",
|
"PasskeySummary": "Аутентификация с биометрией без пароля",
|
||||||
"Passphrase": "Пароль ключа",
|
"Passphrase": "Пароль ключа",
|
||||||
"Password": "Пароль",
|
"Password": "Пароль",
|
||||||
"PasswordAndSSHKey": "Пароль и SSH-ключ",
|
"PasswordAndSSHKey": "Пароль и SSH-ключ",
|
||||||
@@ -1023,7 +1028,7 @@
|
|||||||
"PleaseAgreeToTheTerms": "Пожалуйста, согласитесь с условиями",
|
"PleaseAgreeToTheTerms": "Пожалуйста, согласитесь с условиями",
|
||||||
"PleaseEnterReason": "Введите причину",
|
"PleaseEnterReason": "Введите причину",
|
||||||
"PleaseSelect": "Пожалуйста, выберите ",
|
"PleaseSelect": "Пожалуйста, выберите ",
|
||||||
"PleaseSelectTheDataYouWantToCheck": "Пожалуйста, выберите данные для отметки",
|
"PleaseSelectTheDataYouWantToCheck": "Пожалуйста, выберите данные, которые нужно отметить",
|
||||||
"PolicyName": "Название политики",
|
"PolicyName": "Название политики",
|
||||||
"Port": "Порт",
|
"Port": "Порт",
|
||||||
"Ports": "Портов",
|
"Ports": "Портов",
|
||||||
@@ -1040,6 +1045,7 @@
|
|||||||
"PrivilegedOnly": "Только привилегированные",
|
"PrivilegedOnly": "Только привилегированные",
|
||||||
"PrivilegedTemplate": "Привилегированные",
|
"PrivilegedTemplate": "Привилегированные",
|
||||||
"Processing": "В процессе",
|
"Processing": "В процессе",
|
||||||
|
"ProcessingMessage": "Задача в процессе, пожалуйста, подождите ⏳",
|
||||||
"Product": "Продукт",
|
"Product": "Продукт",
|
||||||
"ProfileSetting": "Данные профиля",
|
"ProfileSetting": "Данные профиля",
|
||||||
"Project": "Название проекта",
|
"Project": "Название проекта",
|
||||||
@@ -1072,7 +1078,7 @@
|
|||||||
"QuickJob": "Быстрые задания",
|
"QuickJob": "Быстрые задания",
|
||||||
"QuickUpdate": "Быстрое обновление",
|
"QuickUpdate": "Быстрое обновление",
|
||||||
"Radius": "Radius",
|
"Radius": "Radius",
|
||||||
"RankByNumberOfAssetAccounts": "Рейтинг количества аккаунтов активов",
|
"RankByNumberOfAssetAccounts": "Рейтинг активов по количеству УЗ",
|
||||||
"Ranking": "Рейтинг",
|
"Ranking": "Рейтинг",
|
||||||
"RazorNotSupport": "Сессия RDP-клиента, мониторинг пока не поддерживается",
|
"RazorNotSupport": "Сессия RDP-клиента, мониторинг пока не поддерживается",
|
||||||
"ReLogin": "Войти снова",
|
"ReLogin": "Войти снова",
|
||||||
@@ -1112,7 +1118,7 @@
|
|||||||
"RelevantSystemUser": "Системный пользователь",
|
"RelevantSystemUser": "Системный пользователь",
|
||||||
"RemoteAddr": "Удалённый адрес",
|
"RemoteAddr": "Удалённый адрес",
|
||||||
"RemoteAssetFoundAccountDeleteMsg": "Удалить аккаунты, обнаруженные с удалённых активов",
|
"RemoteAssetFoundAccountDeleteMsg": "Удалить аккаунты, обнаруженные с удалённых активов",
|
||||||
"RemoteLoginProtocolUsageDistribution": "Распределение использования протоколов удаленного входа",
|
"RemoteLoginProtocolUsageDistribution": "Распределение протоколов входа в активы",
|
||||||
"Remove": "Удалить",
|
"Remove": "Удалить",
|
||||||
"RemoveAssetFromNode": "Удалить активы из папки",
|
"RemoveAssetFromNode": "Удалить активы из папки",
|
||||||
"RemoveSelected": "Удалить выбранное",
|
"RemoveSelected": "Удалить выбранное",
|
||||||
@@ -1131,7 +1137,7 @@
|
|||||||
"Reply": "Ответ",
|
"Reply": "Ответ",
|
||||||
"Report": "Отчет",
|
"Report": "Отчет",
|
||||||
"ReportType": "Тип отчета",
|
"ReportType": "Тип отчета",
|
||||||
"RequestAssetPerm": "Запросить доступ к автивам",
|
"RequestAssetPerm": "Запросить доступ к активам",
|
||||||
"RequestPerm": "Запрос доступа",
|
"RequestPerm": "Запрос доступа",
|
||||||
"RequestTickets": "Новая заявка",
|
"RequestTickets": "Новая заявка",
|
||||||
"RequiredAssetOrNode": "Пожалуйста, выберите хотя бы один актив или папку",
|
"RequiredAssetOrNode": "Пожалуйста, выберите хотя бы один актив или папку",
|
||||||
@@ -1154,6 +1160,7 @@
|
|||||||
"ResetSSHKeySuccessMsg": "Задача отправки электронных писем принята, пользователи вскоре получат письма со ссылкой для сброса",
|
"ResetSSHKeySuccessMsg": "Задача отправки электронных писем принята, пользователи вскоре получат письма со ссылкой для сброса",
|
||||||
"ResetSSHKeyWarningMsg": "Вы уверены, что хотите отправить письмо для сброса SSH-ключа пользователю?",
|
"ResetSSHKeyWarningMsg": "Вы уверены, что хотите отправить письмо для сброса SSH-ключа пользователю?",
|
||||||
"ResetSecret": "Секрет можно изменить",
|
"ResetSecret": "Секрет можно изменить",
|
||||||
|
"ResetSuccessfully": "Сброс выполнен успешно",
|
||||||
"ResolveSelected": "Решение установлено",
|
"ResolveSelected": "Решение установлено",
|
||||||
"Resource": "Ресурсы",
|
"Resource": "Ресурсы",
|
||||||
"ResourceType": "Тип ресурса",
|
"ResourceType": "Тип ресурса",
|
||||||
@@ -1212,7 +1219,7 @@
|
|||||||
"SSHKeyOfProfileSSHUpdatePage": "Вы можете нажать кнопку ниже для сброса и загрузки ключа, или скопировать свой SSH-ключ и отправить его.",
|
"SSHKeyOfProfileSSHUpdatePage": "Вы можете нажать кнопку ниже для сброса и загрузки ключа, или скопировать свой SSH-ключ и отправить его.",
|
||||||
"SSHPort": "SSH-порт",
|
"SSHPort": "SSH-порт",
|
||||||
"SSHSecretKey": "SSH ключ",
|
"SSHSecretKey": "SSH ключ",
|
||||||
"SSO": "Единственный вход",
|
"SSO": "Единый вход (SSO)",
|
||||||
"SafeCommand": "Безопасная команда",
|
"SafeCommand": "Безопасная команда",
|
||||||
"SameAccount": "Своя учетная запись",
|
"SameAccount": "Своя учетная запись",
|
||||||
"SameAccountTip": "Учетная запись с тем же именем пользователя, что и у авторизованных пользователей",
|
"SameAccountTip": "Учетная запись с тем же именем пользователя, что и у авторизованных пользователей",
|
||||||
@@ -1234,7 +1241,7 @@
|
|||||||
"SecretKey": "Ключ",
|
"SecretKey": "Ключ",
|
||||||
"SecretKeyStrategy": "Парольная политика",
|
"SecretKeyStrategy": "Парольная политика",
|
||||||
"SecretReset": "Сброс секрета",
|
"SecretReset": "Сброс секрета",
|
||||||
"SecretType": "Тип пароля",
|
"SecretType": "Тип секрета",
|
||||||
"Secure": "Безопасность",
|
"Secure": "Безопасность",
|
||||||
"Security": "Настройки безопасности",
|
"Security": "Настройки безопасности",
|
||||||
"Select": "Выберите",
|
"Select": "Выберите",
|
||||||
@@ -1354,6 +1361,7 @@
|
|||||||
"Support": "Поддержка",
|
"Support": "Поддержка",
|
||||||
"SupportedProtocol": "Протоколы",
|
"SupportedProtocol": "Протоколы",
|
||||||
"SupportedProtocolHelpText": "Настройте поддерживаемые активом протоколы, нажав кнопку настройки, вы сможете изменить пользовательскую конфигурацию для протоколов, такие как каталог SFTP, домен RDP AD и т.д.",
|
"SupportedProtocolHelpText": "Настройте поддерживаемые активом протоколы, нажав кнопку настройки, вы сможете изменить пользовательскую конфигурацию для протоколов, такие как каталог SFTP, домен RDP AD и т.д.",
|
||||||
|
"SupportedTypes": "Поддерживаемые типы",
|
||||||
"Sync": "Синхронизация",
|
"Sync": "Синхронизация",
|
||||||
"SyncAction": "Синхронное действие",
|
"SyncAction": "Синхронное действие",
|
||||||
"SyncDelete": "Синхронное удаление",
|
"SyncDelete": "Синхронное удаление",
|
||||||
@@ -1400,7 +1408,7 @@
|
|||||||
"Task": "Задача",
|
"Task": "Задача",
|
||||||
"TaskDetail": "Сведения о задаче",
|
"TaskDetail": "Сведения о задаче",
|
||||||
"TaskDone": "Задача завершена",
|
"TaskDone": "Задача завершена",
|
||||||
"TaskExecutionTrends": "Тренд выполнения задач",
|
"TaskExecutionTrends": "Тенденции выполнения задач",
|
||||||
"TaskID": "ID задачи",
|
"TaskID": "ID задачи",
|
||||||
"TaskList": "Задачи",
|
"TaskList": "Задачи",
|
||||||
"TaskMonitor": "Мониторинг",
|
"TaskMonitor": "Мониторинг",
|
||||||
@@ -1414,6 +1422,7 @@
|
|||||||
"TemplateCreate": "Создать шаблон",
|
"TemplateCreate": "Создать шаблон",
|
||||||
"TemplateHelpText": "При выборе шаблона для добавления учетные записи, которые не существуют в активе, будут автоматически созданы и опубликованы",
|
"TemplateHelpText": "При выборе шаблона для добавления учетные записи, которые не существуют в активе, будут автоматически созданы и опубликованы",
|
||||||
"TemplateManagement": "Шаблоны",
|
"TemplateManagement": "Шаблоны",
|
||||||
|
"TemplateVariablesHelpText": "Вы можете выбрать шаблон и использовать {{ key }} в его содержимом для обращения ко встроенным переменным. Поддерживается только синтаксис {{ }}, другие виды синтаксиса не поддерживаются. Например, {% if title %} — не поддерживается",
|
||||||
"Templates": "Шаблоны",
|
"Templates": "Шаблоны",
|
||||||
"TencentCloud": "Tencent Cloud",
|
"TencentCloud": "Tencent Cloud",
|
||||||
"Terminal": "Компоненты",
|
"Terminal": "Компоненты",
|
||||||
@@ -1434,7 +1443,7 @@
|
|||||||
"TestPortErrorMsg": "Ошибка порта, пожалуйста, введите заново",
|
"TestPortErrorMsg": "Ошибка порта, пожалуйста, введите заново",
|
||||||
"TestSelected": "Проверить выбранное",
|
"TestSelected": "Проверить выбранное",
|
||||||
"TestSuccessMsg": "Тест пройден успешно",
|
"TestSuccessMsg": "Тест пройден успешно",
|
||||||
"ThirdPartyMfaHelpText": "Способы входа через третьих лиц включают: OpenID, CAS, SAML2, OAuth2, Корпоративный WeChat, Feishu, Lark, Slack, DingTalk.",
|
"ThirdPartyMfaHelpText": "Поддерживаются сторонние сервисы: OpenID, CAS, SAML2, OAuth2, WeCom, Feishu, Lark, Slack, DingTalk",
|
||||||
"Thursday": "Четверг",
|
"Thursday": "Четверг",
|
||||||
"Ticket": "Система заявок",
|
"Ticket": "Система заявок",
|
||||||
"TicketDetail": "Сведения о заяве",
|
"TicketDetail": "Сведения о заяве",
|
||||||
@@ -1448,7 +1457,7 @@
|
|||||||
"TimeDelta": "Продолжительность",
|
"TimeDelta": "Продолжительность",
|
||||||
"TimeExpression": "Выражение времени",
|
"TimeExpression": "Выражение времени",
|
||||||
"Timeout": "Таймаут",
|
"Timeout": "Таймаут",
|
||||||
"Timeout(s)": "Превышение времени (сек)",
|
"Timeout(s)": "Время ожидания (сек)",
|
||||||
"TimeoutHelpText": "Если это значение равно -1, таймаут не указан.",
|
"TimeoutHelpText": "Если это значение равно -1, таймаут не указан.",
|
||||||
"Timer": "Таймер",
|
"Timer": "Таймер",
|
||||||
"TimerExecution": "Таймер выполнения",
|
"TimerExecution": "Таймер выполнения",
|
||||||
@@ -1457,7 +1466,7 @@
|
|||||||
"Today": "Сегодня",
|
"Today": "Сегодня",
|
||||||
"TodayFailedConnections": "Сбой подключений сегодня",
|
"TodayFailedConnections": "Сбой подключений сегодня",
|
||||||
"Token": "Токен",
|
"Token": "Токен",
|
||||||
"TopRankOfOperateUsers": "Рейтинг операционных пользователей",
|
"TopRankOfOperateUsers": "Топ пользователей выполнявших смену пароля",
|
||||||
"Total": "Всего",
|
"Total": "Всего",
|
||||||
"TotalAccounts": "Всего учетных записей",
|
"TotalAccounts": "Всего учетных записей",
|
||||||
"TotalJobFailed": "Неудачное выполнение",
|
"TotalJobFailed": "Неудачное выполнение",
|
||||||
@@ -1503,7 +1512,7 @@
|
|||||||
"UpdateNodeAssetHardwareInfo": "Обновление информации об оборудовании активов в папке",
|
"UpdateNodeAssetHardwareInfo": "Обновление информации об оборудовании активов в папке",
|
||||||
"UpdatePlatformHelpText": "Актив будет обновлен только в том случае, если исходный тип платформы совпадает с выбранным типом платформы. Если типы платформы до и после обновления различаются, он не будет обновлен.",
|
"UpdatePlatformHelpText": "Актив будет обновлен только в том случае, если исходный тип платформы совпадает с выбранным типом платформы. Если типы платформы до и после обновления различаются, он не будет обновлен.",
|
||||||
"UpdateSSHKey": "Изменить открытый ключ ssh",
|
"UpdateSSHKey": "Изменить открытый ключ ssh",
|
||||||
"UpdateSelected": "Редактировать выбранное",
|
"UpdateSelected": "Обновить выбранные",
|
||||||
"UpdateSuccessMsg": "Успешно обновлено!",
|
"UpdateSuccessMsg": "Успешно обновлено!",
|
||||||
"Updated": "Обновлено",
|
"Updated": "Обновлено",
|
||||||
"UpgradeEnterpriseEdition": "Обновить до корпоративной версии",
|
"UpgradeEnterpriseEdition": "Обновить до корпоративной версии",
|
||||||
@@ -1523,10 +1532,11 @@
|
|||||||
"User": "Пользователь",
|
"User": "Пользователь",
|
||||||
"UserACLss": "Правила входа пользователей",
|
"UserACLss": "Правила входа пользователей",
|
||||||
"UserAssetActivity": "Активность пользователя/актива",
|
"UserAssetActivity": "Активность пользователя/актива",
|
||||||
"UserChangePasswordReport": "Отчет о смене пароля пользователя",
|
"UserChangePasswordReport": "Отчет о смене пароля пользователями",
|
||||||
"UserCreate": "Создать пользователя",
|
"UserCreate": "Создать пользователя",
|
||||||
"UserData": "Данные пользователя",
|
"UserData": "Данные пользователя",
|
||||||
"UserDetail": "Информация о пользователе",
|
"UserDetail": "Информация о пользователе",
|
||||||
|
"UserGroup": "Группа пользователей",
|
||||||
"UserGroupCreate": "Создать группу пользователей",
|
"UserGroupCreate": "Создать группу пользователей",
|
||||||
"UserGroupDetail": "Подробности группы пользователей",
|
"UserGroupDetail": "Подробности группы пользователей",
|
||||||
"UserGroupList": "Группы",
|
"UserGroupList": "Группы",
|
||||||
@@ -1543,12 +1553,12 @@
|
|||||||
"UserLoginACLs": "Управление входом пользователей",
|
"UserLoginACLs": "Управление входом пользователей",
|
||||||
"UserLoginLimit": "Ограничение для пользователей",
|
"UserLoginLimit": "Ограничение для пользователей",
|
||||||
"UserLoginReport": "Отчет о входах пользователей",
|
"UserLoginReport": "Отчет о входах пользователей",
|
||||||
"UserLoginTrend": "Тренд входа пользователей",
|
"UserLoginTrend": "Тенденции входа по учётным записям",
|
||||||
"UserLoginTrends": "Тренды входа пользователей",
|
"UserLoginTrends": "Тенденции входа пользователей",
|
||||||
"UserModificationTrends": "Тенденции изменений пользователями",
|
"UserModificationTrends": "Тенденции смены пароля пользователями",
|
||||||
"UserOverview": "Обзор пользователей",
|
"UserOverview": "Обзор пользователей",
|
||||||
"UserPasswordChangeLog": "Журнал смены пароля пользователя",
|
"UserPasswordChangeLog": "Журнал смены пароля пользователя",
|
||||||
"UserReport": "Отчет о пользователях",
|
"UserReport": "Отчет по пользователям",
|
||||||
"UserSession": "Сессии к активам",
|
"UserSession": "Сессии к активам",
|
||||||
"UserSwitchFrom": "Переключение su с",
|
"UserSwitchFrom": "Переключение su с",
|
||||||
"UserUpdate": "Обновить пользователя",
|
"UserUpdate": "Обновить пользователя",
|
||||||
@@ -1580,7 +1590,7 @@
|
|||||||
"VirtualApp": "Виртуальное приложение",
|
"VirtualApp": "Виртуальное приложение",
|
||||||
"VirtualAppDetail": "Сведения о виртуальном приложении",
|
"VirtualAppDetail": "Сведения о виртуальном приложении",
|
||||||
"VirtualApps": "Виртуальные приложения",
|
"VirtualApps": "Виртуальные приложения",
|
||||||
"VisitTimeDistribution": "Посещение во временные интервалы",
|
"VisitTimeDistribution": "Распределение доступа по периодам",
|
||||||
"Visits": "Посещения",
|
"Visits": "Посещения",
|
||||||
"Volcengine": "Volcengine",
|
"Volcengine": "Volcengine",
|
||||||
"Warning": "Предупреждение",
|
"Warning": "Предупреждение",
|
||||||
@@ -1600,7 +1610,7 @@
|
|||||||
"Week": "Неделя",
|
"Week": "Неделя",
|
||||||
"WeekAdd": "Новое за неделю",
|
"WeekAdd": "Новое за неделю",
|
||||||
"WeekOrTime": "День/Время",
|
"WeekOrTime": "День/Время",
|
||||||
"WeeklyGrowthTrend": "Тренды нового на этой неделе",
|
"WeeklyGrowthTrend": "Тенденция новых объектов за эту неделю",
|
||||||
"WildcardsAllowed": "Допустимые подстановочные знаки",
|
"WildcardsAllowed": "Допустимые подстановочные знаки",
|
||||||
"WindowsPushHelpText": "Отправка ключа для активов Windows пока не поддерживается",
|
"WindowsPushHelpText": "Отправка ключа для активов Windows пока не поддерживается",
|
||||||
"WordSep": " ",
|
"WordSep": " ",
|
||||||
@@ -1619,6 +1629,7 @@
|
|||||||
"assetId": "ID актива",
|
"assetId": "ID актива",
|
||||||
"assetName": "Название актива",
|
"assetName": "Название актива",
|
||||||
"currentTime": "Текущее время",
|
"currentTime": "Текущее время",
|
||||||
|
"description": "Нет данных",
|
||||||
"disallowSelfUpdateFields": "Не разрешено самостоятельно изменять текущие поля.",
|
"disallowSelfUpdateFields": "Не разрешено самостоятельно изменять текущие поля.",
|
||||||
"forceEnableMFAHelpText": "При принудительном включении пользователь не может отключить самостоятельно",
|
"forceEnableMFAHelpText": "При принудительном включении пользователь не может отключить самостоятельно",
|
||||||
"isConsoleCanUse": "Доступна ли Консоль",
|
"isConsoleCanUse": "Доступна ли Консоль",
|
||||||
@@ -1626,5 +1637,5 @@
|
|||||||
"removeWarningMsg": "Вы уверены, что хотите удалить",
|
"removeWarningMsg": "Вы уверены, что хотите удалить",
|
||||||
"setVariable": "Задать переменную",
|
"setVariable": "Задать переменную",
|
||||||
"userId": "ID пользователя",
|
"userId": "ID пользователя",
|
||||||
"userName": "Имя пользовател"
|
"userName": "Имя пользователя"
|
||||||
}
|
}
|
||||||
1641
apps/i18n/lina/vi.json
Normal file
1641
apps/i18n/lina/vi.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -122,7 +122,7 @@
|
|||||||
"AppletHelpText": "在上传过程中,如果应用不存在,则创建该应用;如果已存在,则进行应用更新。",
|
"AppletHelpText": "在上传过程中,如果应用不存在,则创建该应用;如果已存在,则进行应用更新。",
|
||||||
"AppletHostCreate": "添加远程应用发布机",
|
"AppletHostCreate": "添加远程应用发布机",
|
||||||
"AppletHostDetail": "远程应用发布机详情",
|
"AppletHostDetail": "远程应用发布机详情",
|
||||||
"AppletHostSelectHelpMessage": "连接资产时,应用发布机选择是随机的(但优先选择上次使用的),如果想为某个资产固定发布机,可以指定标签 <发布机:发布机名称> 或 <AppletHost:发布机名称>; <br>连接该发布机选择账号时,以下情况会选择用户的 <b>同名账号 或 专有账号(js开头)</b>,否则使用公用账号(jms开头):<br> 1. 发布机和应用都支持并发; <br> 2. 发布机支持并发,应用不支持并发,当前应用没有使用专有账号; <br> 3. 发布机不支持并发,应用支持并发或不支持,没有任一应用使用专有账号; <br> 注意: 应用支不支持并发是开发者决定,主机支不支持是发布机配置中的 单用户单会话决定",
|
"AppletHostSelectHelpMessage": "连接资产时,应用发布机选择是随机的(但优先选择上次使用的),如果想为某个资产固定发布机,可以指定标签 <发布机:发布机名称>、<AppletHost:发布机名称>、<仅发布机:发布机名称>、 <AppletHostOnly:发布机名称>; <br>连接该发布机选择账号时,以下情况会选择用户的 <b>同名账号 或 专有账号(js开头)</b>,否则使用公用账号(jms开头):<br> 1. 发布机和应用都支持并发; <br> 2. 发布机支持并发,应用不支持并发,当前应用没有使用专有账号; <br> 3. 发布机不支持并发,应用支持并发或不支持,没有任一应用使用专有账号; <br> 注意: 应用支不支持并发是开发者决定,主机支不支持是发布机配置中的 单用户单会话决定",
|
||||||
"AppletHostUpdate": "更新远程应用发布机",
|
"AppletHostUpdate": "更新远程应用发布机",
|
||||||
"AppletHostZoneHelpText": "这里的网域属于 System 组织",
|
"AppletHostZoneHelpText": "这里的网域属于 System 组织",
|
||||||
"AppletHosts": "应用发布机",
|
"AppletHosts": "应用发布机",
|
||||||
@@ -447,6 +447,10 @@
|
|||||||
"DangerCommand": "危险命令",
|
"DangerCommand": "危险命令",
|
||||||
"DangerousCommandNum": "危险命令数",
|
"DangerousCommandNum": "危险命令数",
|
||||||
"Dashboard": "仪表盘",
|
"Dashboard": "仪表盘",
|
||||||
|
"DataMasking": "数据脱敏",
|
||||||
|
"DataMaskingFieldsPatternHelpTip": "支持多个字段名,逗号分隔,支持通配符*\n 例如: \n单字段名: password 表示只脱敏 password 字段\n多个字段名: password,secret 表示脱敏 password 和 secret 字段\n通配符*: password* 表示脱敏字段名中包含 password 前缀的字段\n通配符*: .*password 表示脱敏字段名中包含 password 后缀的字段\n",
|
||||||
|
"DataMaskingRuleHelpHelpMsg": "连接数据库资产时,可以根据此规则对查询结果进行脱敏",
|
||||||
|
"DataMaskingRuleHelpHelpText": "连接数据库资产时,可以根据此规则对查询结果进行脱敏",
|
||||||
"Database": "数据库",
|
"Database": "数据库",
|
||||||
"DatabaseCreate": "创建资产-数据库",
|
"DatabaseCreate": "创建资产-数据库",
|
||||||
"DatabasePort": "数据库协议端口",
|
"DatabasePort": "数据库协议端口",
|
||||||
@@ -571,10 +575,11 @@
|
|||||||
"EsIndex": "es 提供默认 index:jumpserver。如果开启按日期建立索引,那么输入的值会作为索引前缀",
|
"EsIndex": "es 提供默认 index:jumpserver。如果开启按日期建立索引,那么输入的值会作为索引前缀",
|
||||||
"EsUrl": "不能包含特殊字符 `#`;eg: http://es_user:es_password@es_host:es_port",
|
"EsUrl": "不能包含特殊字符 `#`;eg: http://es_user:es_password@es_host:es_port",
|
||||||
"Every": "每",
|
"Every": "每",
|
||||||
|
"Example": "示例值",
|
||||||
"Exclude": "不包含",
|
"Exclude": "不包含",
|
||||||
|
"ExcludeAccount": "排除账号",
|
||||||
"ExcludeAsset": "跳过的资产",
|
"ExcludeAsset": "跳过的资产",
|
||||||
"ExcludeSymbol": "排除字符",
|
"ExcludeSymbol": "排除字符",
|
||||||
"ExcludeAccount": "排除账号",
|
|
||||||
"ExecCloudSyncErrorMsg": "云账号配置不完整,请更新后重试",
|
"ExecCloudSyncErrorMsg": "云账号配置不完整,请更新后重试",
|
||||||
"Execute": "执行",
|
"Execute": "执行",
|
||||||
"ExecuteAfterSaving": "保存后执行",
|
"ExecuteAfterSaving": "保存后执行",
|
||||||
@@ -866,6 +871,7 @@
|
|||||||
"MoveAssetToNode": "移动资产到节点",
|
"MoveAssetToNode": "移动资产到节点",
|
||||||
"MoveToAsset": "移动到资产",
|
"MoveToAsset": "移动到资产",
|
||||||
"MsgSubscribe": "消息订阅",
|
"MsgSubscribe": "消息订阅",
|
||||||
|
"MsgTemplate": "消息模板",
|
||||||
"MyAssets": "我的资产",
|
"MyAssets": "我的资产",
|
||||||
"MyTickets": "我发起的",
|
"MyTickets": "我发起的",
|
||||||
"NUMBER_REQUIRED": "必须包含数字",
|
"NUMBER_REQUIRED": "必须包含数字",
|
||||||
@@ -1039,6 +1045,7 @@
|
|||||||
"PrivilegedOnly": "仅特权账号",
|
"PrivilegedOnly": "仅特权账号",
|
||||||
"PrivilegedTemplate": "特权的",
|
"PrivilegedTemplate": "特权的",
|
||||||
"Processing": "处理中",
|
"Processing": "处理中",
|
||||||
|
"ProcessingMessage": "任务进行中,请稍候 ⏳",
|
||||||
"Product": "产品",
|
"Product": "产品",
|
||||||
"ProfileSetting": "个人信息设置",
|
"ProfileSetting": "个人信息设置",
|
||||||
"Project": "项目名",
|
"Project": "项目名",
|
||||||
@@ -1153,6 +1160,7 @@
|
|||||||
"ResetSSHKeySuccessMsg": "发送邮件任务已提交, 用户稍后会收到重置密钥邮件",
|
"ResetSSHKeySuccessMsg": "发送邮件任务已提交, 用户稍后会收到重置密钥邮件",
|
||||||
"ResetSSHKeyWarningMsg": "你确定要发送重置用户的SSH Key的邮件吗?",
|
"ResetSSHKeyWarningMsg": "你确定要发送重置用户的SSH Key的邮件吗?",
|
||||||
"ResetSecret": "可改密",
|
"ResetSecret": "可改密",
|
||||||
|
"ResetSuccessfully": "重置成功",
|
||||||
"ResolveSelected": "解决所选",
|
"ResolveSelected": "解决所选",
|
||||||
"Resource": "资源",
|
"Resource": "资源",
|
||||||
"ResourceType": "资源类型",
|
"ResourceType": "资源类型",
|
||||||
@@ -1353,6 +1361,7 @@
|
|||||||
"Support": "支持",
|
"Support": "支持",
|
||||||
"SupportedProtocol": "支持的协议",
|
"SupportedProtocol": "支持的协议",
|
||||||
"SupportedProtocolHelpText": "设置资产支持的协议,点击设置按钮可以为协议修改自定义配置,如 SFTP 目录,RDP AD 域等",
|
"SupportedProtocolHelpText": "设置资产支持的协议,点击设置按钮可以为协议修改自定义配置,如 SFTP 目录,RDP AD 域等",
|
||||||
|
"SupportedTypes": "支持的类型",
|
||||||
"Sync": "同步",
|
"Sync": "同步",
|
||||||
"SyncAction": "同步动作",
|
"SyncAction": "同步动作",
|
||||||
"SyncDelete": "同步删除",
|
"SyncDelete": "同步删除",
|
||||||
@@ -1413,6 +1422,7 @@
|
|||||||
"TemplateCreate": "创建模版",
|
"TemplateCreate": "创建模版",
|
||||||
"TemplateHelpText": "选择模版添加时,会自动创建资产下不存在的账号并推送",
|
"TemplateHelpText": "选择模版添加时,会自动创建资产下不存在的账号并推送",
|
||||||
"TemplateManagement": "模版管理",
|
"TemplateManagement": "模版管理",
|
||||||
|
"TemplateVariablesHelpText": "您可以选择一个模板在模板内容中使用 {{ key }} 读取内置变量,注意:只支持 {{ }} 语法,其他语法不支持。例如 {% if title %}",
|
||||||
"Templates": "模板",
|
"Templates": "模板",
|
||||||
"TencentCloud": "腾讯云",
|
"TencentCloud": "腾讯云",
|
||||||
"Terminal": "组件设置",
|
"Terminal": "组件设置",
|
||||||
@@ -1526,6 +1536,7 @@
|
|||||||
"UserCreate": "创建用户",
|
"UserCreate": "创建用户",
|
||||||
"UserData": "用户数据",
|
"UserData": "用户数据",
|
||||||
"UserDetail": "用户详情",
|
"UserDetail": "用户详情",
|
||||||
|
"UserGroup": "用户组",
|
||||||
"UserGroupCreate": "创建用户组",
|
"UserGroupCreate": "创建用户组",
|
||||||
"UserGroupDetail": "用户组详情",
|
"UserGroupDetail": "用户组详情",
|
||||||
"UserGroupList": "用户组",
|
"UserGroupList": "用户组",
|
||||||
@@ -1618,6 +1629,7 @@
|
|||||||
"assetId": "资产 ID",
|
"assetId": "资产 ID",
|
||||||
"assetName": "资产名称",
|
"assetName": "资产名称",
|
||||||
"currentTime": "当前时间",
|
"currentTime": "当前时间",
|
||||||
|
"description": "暂无数据",
|
||||||
"disallowSelfUpdateFields": "不允许自己修改当前字段",
|
"disallowSelfUpdateFields": "不允许自己修改当前字段",
|
||||||
"forceEnableMFAHelpText": "如果强制启用,用户无法自行禁用",
|
"forceEnableMFAHelpText": "如果强制启用,用户无法自行禁用",
|
||||||
"isConsoleCanUse": "管理页面是否可用",
|
"isConsoleCanUse": "管理页面是否可用",
|
||||||
@@ -1625,8 +1637,5 @@
|
|||||||
"removeWarningMsg": "你确定要移除",
|
"removeWarningMsg": "你确定要移除",
|
||||||
"setVariable": "设置参数",
|
"setVariable": "设置参数",
|
||||||
"userId": "用户ID",
|
"userId": "用户ID",
|
||||||
"userName": "用户名",
|
"userName": "用户名"
|
||||||
"ExportAsPDF": "导出 PDF",
|
}
|
||||||
"EMailReport": "发送邮件报告",
|
|
||||||
"Print": "打印"
|
|
||||||
}
|
|
||||||
@@ -452,6 +452,10 @@
|
|||||||
"DangerousCommandNum": "危險命令數",
|
"DangerousCommandNum": "危險命令數",
|
||||||
"Dashboard": "儀錶盤",
|
"Dashboard": "儀錶盤",
|
||||||
"DataLastUsed": "最後使用日期",
|
"DataLastUsed": "最後使用日期",
|
||||||
|
"DataMasking": "數據脫敏",
|
||||||
|
"DataMaskingFieldsPatternHelpTip": "支持多個欄位名稱,以逗號分隔,並支持通配符*\n例如:\n單欄位名稱:password 表示僅脫敏 password 欄位\n多個欄位名稱:password,secret 表示脫敏 password 和 secret 欄位\n通配符*:password* 表示脫敏欄位名稱中包含 password 前綴的欄位\n通配符*:.*password 表示脫敏欄位名稱中包含 password 後綴的欄位",
|
||||||
|
"DataMaskingRuleHelpHelpMsg": "連接資料庫資產時,可以根據此規則對查詢結果進行脫敏<–SEP–>任務進行中,請稍候 ⏳",
|
||||||
|
"DataMaskingRuleHelpHelpText": "連接資料庫資產時,可以根據此規則對查詢結果進行脫敏。",
|
||||||
"Database": "資料庫",
|
"Database": "資料庫",
|
||||||
"DatabaseCreate": "創建資產-資料庫",
|
"DatabaseCreate": "創建資產-資料庫",
|
||||||
"DatabasePort": "資料庫協議埠",
|
"DatabasePort": "資料庫協議埠",
|
||||||
@@ -576,7 +580,9 @@
|
|||||||
"EsIndex": "es 提供預設 index:jumpserver。如果開啟按日期建立索引,那麼輸入的值會作為索引前綴",
|
"EsIndex": "es 提供預設 index:jumpserver。如果開啟按日期建立索引,那麼輸入的值會作為索引前綴",
|
||||||
"EsUrl": "不能包含特殊字符 `#`;eg: http://es_user:es_password@es_host:es_port",
|
"EsUrl": "不能包含特殊字符 `#`;eg: http://es_user:es_password@es_host:es_port",
|
||||||
"Every": "每",
|
"Every": "每",
|
||||||
|
"Example": "示例值",
|
||||||
"Exclude": "不包含",
|
"Exclude": "不包含",
|
||||||
|
"ExcludeAccount": "排除帳號",
|
||||||
"ExcludeAsset": "跳過的資產",
|
"ExcludeAsset": "跳過的資產",
|
||||||
"ExcludeSymbol": "排除字元",
|
"ExcludeSymbol": "排除字元",
|
||||||
"ExecCloudSyncErrorMsg": "雲帳號配置不完整,請更新後重試",
|
"ExecCloudSyncErrorMsg": "雲帳號配置不完整,請更新後重試",
|
||||||
@@ -870,6 +876,7 @@
|
|||||||
"MoveAssetToNode": "移動資產到節點",
|
"MoveAssetToNode": "移動資產到節點",
|
||||||
"MoveToAsset": "移動到資產",
|
"MoveToAsset": "移動到資產",
|
||||||
"MsgSubscribe": "消息訂閱",
|
"MsgSubscribe": "消息訂閱",
|
||||||
|
"MsgTemplate": "消息模板",
|
||||||
"MyAssets": "我的資產",
|
"MyAssets": "我的資產",
|
||||||
"MyTickets": "我發起的",
|
"MyTickets": "我發起的",
|
||||||
"NUMBER_REQUIRED": "須包含數字",
|
"NUMBER_REQUIRED": "須包含數字",
|
||||||
@@ -1043,6 +1050,7 @@
|
|||||||
"PrivilegedOnly": "僅特權帳號",
|
"PrivilegedOnly": "僅特權帳號",
|
||||||
"PrivilegedTemplate": "特權的",
|
"PrivilegedTemplate": "特權的",
|
||||||
"Processing": "處理中",
|
"Processing": "處理中",
|
||||||
|
"ProcessingMessage": "任務進行中,請稍候 ⏳\n\n支持多個字段名,逗號分隔,支持通配符*\n例如: \n單字段名: password 表示僅脫敏 password 字段 \n多個字段名: password,secret 表示脫敏 password 與 secret 字段 \n通配符*: password* 表示脫敏字段名中包含 password 前綴的字段 \n通配符*: .*password 表示脫敏字段名中包含 password 後綴的字段",
|
||||||
"Product": "產品",
|
"Product": "產品",
|
||||||
"ProfileSetting": "個人資訊設置",
|
"ProfileSetting": "個人資訊設置",
|
||||||
"Project": "項目名",
|
"Project": "項目名",
|
||||||
@@ -1157,6 +1165,7 @@
|
|||||||
"ResetSSHKeySuccessMsg": "發送郵件任務已提交,用戶稍後會收到重置密鑰郵件",
|
"ResetSSHKeySuccessMsg": "發送郵件任務已提交,用戶稍後會收到重置密鑰郵件",
|
||||||
"ResetSSHKeyWarningMsg": "你確定要傳送重置用戶的SSH Key的郵件嗎?",
|
"ResetSSHKeyWarningMsg": "你確定要傳送重置用戶的SSH Key的郵件嗎?",
|
||||||
"ResetSecret": "可更改密碼",
|
"ResetSecret": "可更改密碼",
|
||||||
|
"ResetSuccessfully": "重置成功",
|
||||||
"ResolveSelected": "解決選定",
|
"ResolveSelected": "解決選定",
|
||||||
"Resource": "資源",
|
"Resource": "資源",
|
||||||
"ResourceType": "資源類型",
|
"ResourceType": "資源類型",
|
||||||
@@ -1357,6 +1366,7 @@
|
|||||||
"Support": "支持",
|
"Support": "支持",
|
||||||
"SupportedProtocol": "支持的協議",
|
"SupportedProtocol": "支持的協議",
|
||||||
"SupportedProtocolHelpText": "設置資產支持的協議,點擊設置按鈕可以為協議修改自訂配置,如 SFTP 目錄,RDP AD 域等",
|
"SupportedProtocolHelpText": "設置資產支持的協議,點擊設置按鈕可以為協議修改自訂配置,如 SFTP 目錄,RDP AD 域等",
|
||||||
|
"SupportedTypes": "支持的類型",
|
||||||
"Sync": "同步",
|
"Sync": "同步",
|
||||||
"SyncAction": "同步動作",
|
"SyncAction": "同步動作",
|
||||||
"SyncDelete": "同步刪除",
|
"SyncDelete": "同步刪除",
|
||||||
@@ -1417,6 +1427,7 @@
|
|||||||
"TemplateCreate": "創建模板",
|
"TemplateCreate": "創建模板",
|
||||||
"TemplateHelpText": "選擇模板添加時,會自動創建資產下不存在的帳號並推送",
|
"TemplateHelpText": "選擇模板添加時,會自動創建資產下不存在的帳號並推送",
|
||||||
"TemplateManagement": "模版列表",
|
"TemplateManagement": "模版列表",
|
||||||
|
"TemplateVariablesHelpText": "您可以選擇一個模板,在模板內容中使用 {{ key }} 來讀取內置變數,注意:只支持 {{ }} 語法,其他語法不支持。例如 {% if title %}",
|
||||||
"Templates": "模板列表",
|
"Templates": "模板列表",
|
||||||
"TencentCloud": "騰訊雲",
|
"TencentCloud": "騰訊雲",
|
||||||
"Terminal": "組件設置",
|
"Terminal": "組件設置",
|
||||||
@@ -1530,6 +1541,7 @@
|
|||||||
"UserCreate": "創建用戶",
|
"UserCreate": "創建用戶",
|
||||||
"UserData": "使用者資料",
|
"UserData": "使用者資料",
|
||||||
"UserDetail": "用戶詳情",
|
"UserDetail": "用戶詳情",
|
||||||
|
"UserGroup": "用戶組",
|
||||||
"UserGroupCreate": "創建用戶組",
|
"UserGroupCreate": "創建用戶組",
|
||||||
"UserGroupDetail": "用戶組詳情",
|
"UserGroupDetail": "用戶組詳情",
|
||||||
"UserGroupList": "用戶組",
|
"UserGroupList": "用戶組",
|
||||||
@@ -1622,6 +1634,7 @@
|
|||||||
"assetId": "資產 ID",
|
"assetId": "資產 ID",
|
||||||
"assetName": "資產名稱",
|
"assetName": "資產名稱",
|
||||||
"currentTime": "當前時間",
|
"currentTime": "當前時間",
|
||||||
|
"description": "目前沒有數據。",
|
||||||
"disallowSelfUpdateFields": "不允許自己修改當前欄位",
|
"disallowSelfUpdateFields": "不允許自己修改當前欄位",
|
||||||
"forceEnableMFAHelpText": "如果強制啟用,用戶無法自行禁用",
|
"forceEnableMFAHelpText": "如果強制啟用,用戶無法自行禁用",
|
||||||
"isConsoleCanUse": "管理頁面是否可用",
|
"isConsoleCanUse": "管理頁面是否可用",
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user