merge: 合并 dev

pull/10829/head
ibuler 2023-07-04 11:43:33 +08:00
commit d72ec653f4
23 changed files with 536 additions and 390 deletions

View File

@ -6,8 +6,7 @@ labels: 类型:需求
assignees:
- ibuler
- baijiangjie
- wojiushixiaobai
---
**请描述您的需求或者改进建议.**

View File

@ -21,17 +21,44 @@ jobs:
actions: 'remove-labels'
labels: '状态:待反馈'
add-label-if-not-author:
add-label-if-is-member:
runs-on: ubuntu-latest
if: (github.event.issue.user.id != github.event.comment.user.id) && !github.event.issue.pull_request && (github.event.issue.state == 'open')
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Get Organization name
id: org_name
run: echo "data=$(echo '${{ github.repository }}' | cut -d '/' -f 1)" >> $GITHUB_OUTPUT
- name: Get Organization public members
uses: octokit/request-action@v2.x
id: members
with:
route: GET /orgs/${{ steps.org_name.outputs.data }}/public_members
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Process public members data
# 将 members 中的数据转化为 login 字段的拼接字符串
id: member_names
run: echo "data=$(echo '${{ steps.members.outputs.data }}' | jq '[.[].login] | join(",")')" >> $GITHUB_OUTPUT
- run: "echo members: '${{ steps.members.outputs.data }}'"
- run: "echo member names: '${{ steps.member_names.outputs.data }}'"
- run: "echo comment user: '${{ github.event.comment.user.login }}'"
- run: "echo contains? : '${{ contains(steps.member_names.outputs.data, github.event.comment.user.login) }}'"
- name: Add require replay label
if: contains(steps.member_names.outputs.data, github.event.comment.user.login)
uses: actions-cool/issues-helper@v2
with:
actions: 'add-labels'
labels: '状态:待反馈'
- name: Remove require handle label
if: contains(steps.member_names.outputs.data, github.event.comment.user.login)
uses: actions-cool/issues-helper@v2
with:
actions: 'remove-labels'

View File

@ -45,7 +45,7 @@ class AccountFilterSet(BaseFilterSet):
class Meta:
model = Account
fields = ['id', 'asset_id', 'source_id']
fields = ['id', 'asset_id', 'source_id', 'secret_type']
class GatheredAccountFilterSet(BaseFilterSet):

View File

@ -1,3 +1,3 @@
from .base import *
from .account import *
from .automations import *
from .base import *

View File

@ -78,5 +78,8 @@ class BaseAccountSerializer(AuthValidateMixin, BulkOrgResourceModelSerializer):
]
extra_kwargs = {
'spec_info': {'label': _('Spec info')},
'username': {'help_text': _("Tip: If no username is required for authentication, fill in `null`")}
'username': {'help_text': _(
"Tip: If no username is required for authentication, fill in `null`, "
"If AD account, like `username@domain`"
)},
}

View File

@ -121,6 +121,10 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
NodeFilterBackend, AttrRulesFilterBackend
]
def get_queryset(self):
return super().get_queryset().prefetch_related('nodes', 'protocols')\
.select_related('platform', 'domain')
def get_serializer_class(self):
cls = super().get_serializer_class()
if self.action == "retrieve":

View File

@ -4,20 +4,20 @@ from rest_framework.decorators import action
from rest_framework.response import Response
from assets.const import AllTypes
from assets.models import Platform, Node, Asset
from assets.serializers import PlatformSerializer
from assets.models import Platform, Node, Asset, PlatformProtocol
from assets.serializers import PlatformSerializer, PlatformProtocolSerializer
from common.api import JMSModelViewSet
from common.permissions import IsValidUser
from common.serializers import GroupedChoiceSerializer
__all__ = ['AssetPlatformViewSet', 'PlatformAutomationMethodsApi']
__all__ = ['AssetPlatformViewSet', 'PlatformAutomationMethodsApi', 'PlatformProtocolViewSet']
class AssetPlatformViewSet(JMSModelViewSet):
queryset = Platform.objects.all()
serializer_classes = {
'default': PlatformSerializer,
'categories': GroupedChoiceSerializer
'categories': GroupedChoiceSerializer,
}
filterset_fields = ['name', 'category', 'type']
search_fields = ['name']
@ -25,7 +25,7 @@ class AssetPlatformViewSet(JMSModelViewSet):
'categories': 'assets.view_platform',
'type_constraints': 'assets.view_platform',
'ops_methods': 'assets.view_platform',
'filter_nodes_assets': 'assets.view_platform'
'filter_nodes_assets': 'assets.view_platform',
}
def get_queryset(self):
@ -61,6 +61,15 @@ class AssetPlatformViewSet(JMSModelViewSet):
return Response(serializer.data)
class PlatformProtocolViewSet(JMSModelViewSet):
queryset = PlatformProtocol.objects.all()
serializer_class = PlatformProtocolSerializer
filterset_fields = ['name', 'platform__name']
rbac_perms = {
'*': 'assets.add_platform'
}
class PlatformAutomationMethodsApi(generics.ListAPIView):
permission_classes = (IsValidUser,)

View File

@ -1,7 +1,8 @@
from django.db import models
from django.db.models import TextChoices
from django.utils.translation import gettext_lazy as _
from jumpserver.utils import has_valid_xpack_license
from .protocol import Protocol
class Type:
@ -28,6 +29,12 @@ class Type:
)
class FillType(models.TextChoices):
no = 'no', _('Disabled')
basic = 'basic', _('Basic')
script = 'script', _('Script')
class BaseType(TextChoices):
"""
约束应该考虑代是对平台对限制避免多余对选项: mysql 开启 ssh,
@ -57,6 +64,7 @@ class BaseType(TextChoices):
@classmethod
def _parse_protocols(cls, protocol, tp):
from .protocol import Protocol
settings = Protocol.settings()
choices = protocol.get('choices', [])
if choices == '__self__':

View File

@ -1,6 +1,8 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from common.db.models import ChoicesMixin
from .base import FillType
__all__ = ['Protocol']
@ -22,8 +24,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
mongodb = 'mongodb', 'MongoDB'
k8s = 'k8s', 'K8S'
http = 'http', 'HTTP'
_settings = None
http = 'http', 'HTTP(s)'
@classmethod
def device_protocols(cls):
@ -32,16 +33,40 @@ class Protocol(ChoicesMixin, models.TextChoices):
'port': 22,
'secret_types': ['password', 'ssh_key'],
'setting': {
'sftp_enabled': True,
'sftp_home': '/tmp',
'sftp_enabled': {
'type': 'bool',
'default': True,
'label': _('SFTP enabled')
},
'sftp_home': {
'type': 'str',
'default': '/tmp',
'label': _('SFTP home')
},
}
},
cls.rdp: {
'port': 3389,
'secret_types': ['password'],
'setting': {
'console': False,
'security': 'any',
'console': {
'type': 'bool',
'default': False,
'label': _('Console'),
'help_text': _("Connect to console session")
},
'security': {
'type': 'choice',
'choices': [('any', _('Any')), ('rdp', 'RDP'), ('tls', 'TLS'), ('nla', 'NLA')],
'default': 'any',
'label': _('Security'),
'help_text': _("Security layer to use for the connection")
},
# 'ad_domain': {
# 'type': 'str',
# "required": False,
# 'label': _('AD domain')
# }
}
},
cls.vnc: {
@ -56,7 +81,11 @@ class Protocol(ChoicesMixin, models.TextChoices):
'port': 5985,
'secret_types': ['password'],
'setting': {
'use_ssl': False,
'use_ssl': {
'type': 'bool',
'default': False,
'label': _('Use SSL')
},
}
},
}
@ -105,7 +134,11 @@ class Protocol(ChoicesMixin, models.TextChoices):
'required': True,
'secret_types': ['password'],
'setting': {
'auth_username': True,
'auth_username': {
'type': 'bool',
'default': False,
'label': _('Auth username')
},
}
},
}
@ -121,10 +154,28 @@ class Protocol(ChoicesMixin, models.TextChoices):
cls.http: {
'port': 80,
'secret_types': ['password'],
'label': 'HTTP(s)',
'setting': {
'username_selector': 'name=username',
'password_selector': 'name=password',
'submit_selector': 'id=login_button',
'autofill': {
'type': 'choice',
'choices': FillType.choices,
'default': 'basic',
},
'username_selector': {
'type': 'str',
'default': 'name=username',
'label': _('Username selector')
},
'password_selector': {
'type': 'str',
'default': 'name=password',
'label': _('Password selector')
},
'submit_selector': {
'type': 'str',
'default': 'type=submit',
'label': _('Submit selector')
}
}
},
}

View File

@ -1,4 +1,3 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from .base import BaseType
@ -53,9 +52,3 @@ class WebTypes(BaseType):
return [
cls.WEBSITE,
]
class FillType(models.TextChoices):
no = 'no', _('Disabled')
basic = 'basic', _('Basic')
script = 'script', _('Script')

View File

@ -1,7 +1,7 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from assets.const.web import FillType
from assets.const import FillType
from .common import Asset

View File

@ -1,7 +1,7 @@
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from assets.const.web import FillType
from assets.const import FillType
from assets.models import Database, Web
from common.serializers.fields import LabeledChoiceField
@ -14,6 +14,7 @@ class DatabaseSpecSerializer(serializers.ModelSerializer):
class WebSpecSerializer(serializers.ModelSerializer):
autofill = LabeledChoiceField(choices=FillType.choices, label=_('Autofill'))
class Meta:
model = Web
fields = [

View File

@ -1,48 +1,17 @@
from django.db.models import QuerySet
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from assets.const.web import FillType
from common.serializers import WritableNestedModelSerializer, type_field_map
from common.serializers import (
WritableNestedModelSerializer, type_field_map, MethodSerializer,
DictSerializer, create_serializer_class
)
from common.serializers.fields import LabeledChoiceField
from common.utils import lazyproperty
from ..const import Category, AllTypes
from ..const import Category, AllTypes, Protocol
from ..models import Platform, PlatformProtocol, PlatformAutomation
__all__ = ["PlatformSerializer", "PlatformOpsMethodSerializer"]
class ProtocolSettingSerializer(serializers.Serializer):
SECURITY_CHOICES = [
("any", "Any"),
("rdp", "RDP"),
("tls", "TLS"),
("nla", "NLA"),
]
# RDP
console = serializers.BooleanField(required=False, default=False)
security = serializers.ChoiceField(choices=SECURITY_CHOICES, default="any")
# SFTP
sftp_enabled = serializers.BooleanField(default=True, label=_("SFTP enabled"))
sftp_home = serializers.CharField(default="/tmp", label=_("SFTP home"))
# HTTP
autofill = serializers.ChoiceField(default='basic', choices=FillType.choices, label=_("Autofill"))
username_selector = serializers.CharField(
default="", allow_blank=True, label=_("Username selector")
)
password_selector = serializers.CharField(
default="", allow_blank=True, label=_("Password selector")
)
submit_selector = serializers.CharField(
default="", allow_blank=True, label=_("Submit selector")
)
script = serializers.JSONField(default=list, label=_("Script"))
# Redis
auth_username = serializers.BooleanField(default=False, label=_("Auth with username"))
# WinRM
use_ssl = serializers.BooleanField(default=False, label=_("Use SSL"))
__all__ = ["PlatformSerializer", "PlatformOpsMethodSerializer", "PlatformProtocolSerializer"]
class PlatformAutomationSerializer(serializers.ModelSerializer):
@ -76,7 +45,7 @@ class PlatformAutomationSerializer(serializers.ModelSerializer):
class PlatformProtocolSerializer(serializers.ModelSerializer):
setting = ProtocolSettingSerializer(required=False, allow_null=True)
setting = MethodSerializer(required=False, label=_("Setting"))
class Meta:
model = PlatformProtocol
@ -85,6 +54,47 @@ class PlatformProtocolSerializer(serializers.ModelSerializer):
"required", "default", "public",
"secret_types", "setting",
]
extra_kwargs = {
"primary": {
"help_text": _(
"This protocol is primary, and it must be set when adding assets. "
"Additionally, there can only be one primary protocol."
)
},
"required": {
"help_text": _("This protocol is required, and it must be set when adding assets.")
},
"default": {
"help_text": _("This protocol is default, when adding assets, it will be displayed by default.")
},
"public": {
"help_text": _("This protocol is public, asset will show this protocol to user")
},
}
def get_setting_serializer(self):
request = self.context.get('request')
default_field = DictSerializer()
if not request:
return default_field
if self.instance and isinstance(self.instance, (QuerySet, list)):
instance = self.instance[0]
else:
instance = self.instance
protocol = request.query_params.get('name', '')
if instance and not protocol:
protocol = instance.name
protocol_settings = Protocol.settings()
setting_fields = protocol_settings.get(protocol, {}).get('setting')
if not setting_fields:
return default_field
setting_fields = [{'name': k, **v} for k, v in setting_fields.items()]
name = '{}ProtocolSettingSerializer'.format(protocol.capitalize())
return create_serializer_class(name, setting_fields)()
def to_file_representation(self, data):
return '{name}/{port}'.format(**data)

View File

@ -21,6 +21,7 @@ router.register(r'nodes', api.NodeViewSet, 'node')
router.register(r'domains', api.DomainViewSet, 'domain')
router.register(r'gateways', api.GatewayViewSet, 'gateway')
router.register(r'favorite-assets', api.FavoriteAssetViewSet, 'favorite-asset')
router.register(r'protocol-settings', api.PlatformProtocolViewSet, 'protocol-setting')
urlpatterns = [
# path('assets/<uuid:pk>/gateways/', api.AssetGatewayListApi.as_view(), name='asset-gateway-list'),
@ -46,7 +47,8 @@ urlpatterns = [
path('nodes/<uuid:pk>/tasks/', api.NodeTaskCreateApi.as_view(), name='node-task-create'),
path('gateways/<uuid:pk>/test-connective/', api.GatewayTestConnectionApi.as_view(), name='test-gateway-connective'),
path('platform-automation-methods/', api.PlatformAutomationMethodsApi.as_view(), name='platform-automation-methods'),
path('platform-automation-methods/', api.PlatformAutomationMethodsApi.as_view(),
name='platform-automation-methods'),
]
urlpatterns += router.urls

View File

@ -11,7 +11,7 @@ from django.conf import settings
from django.contrib.auth import BACKEND_SESSION_KEY
from django.contrib.auth import login as auth_login, logout as auth_logout
from django.db import IntegrityError
from django.http import HttpRequest, HttpResponse
from django.http import HttpRequest
from django.shortcuts import reverse, redirect
from django.templatetags.static import static
from django.urls import reverse_lazy
@ -204,7 +204,9 @@ class UserLoginView(mixins.AuthMixin, UserLoginContextMixin, FormView):
def form_valid(self, form):
if not self.request.session.test_cookie_worked():
return HttpResponse(_("Please enable cookies and try again."))
form.add_error(None, _("Login timeout, please try again."))
return self.form_invalid(form)
# https://docs.djangoproject.com/en/3.1/topics/http/sessions/#setting-test-cookies
self.request.session.delete_test_cookie()

View File

@ -50,6 +50,10 @@ class DateTimeMixin:
t = local_now() - timezone.timedelta(days=days)
return t
@lazyproperty
def date_start_end(self):
return self.days_to_datetime.date(), local_now().date()
@lazyproperty
def dates_list(self):
now = local_now()
@ -143,101 +147,40 @@ class DatesLoginMetricMixin:
operate_logs_queryset: OperateLog.objects
password_change_logs_queryset: PasswordChangeLog.objects
@staticmethod
def get_cache_key(date, tp):
date_str = date.strftime("%Y%m%d")
key = "SESSION_DATE_{}_{}_{}".format(current_org.id, tp, date_str)
return key
def __get_data_from_cache(self, date, tp):
if date == timezone.now().date():
return None
cache_key = self.get_cache_key(date, tp)
count = cache.get(cache_key)
return count
def __set_data_to_cache(self, date, tp, count):
cache_key = self.get_cache_key(date, tp)
cache.set(cache_key, count, 3600)
@staticmethod
def get_date_start_2_end(d):
time_min = timezone.datetime.min.time()
time_max = timezone.datetime.max.time()
tz = timezone.get_current_timezone()
ds = timezone.datetime.combine(d, time_min).replace(tzinfo=tz)
de = timezone.datetime.combine(d, time_max).replace(tzinfo=tz)
return ds, de
def get_date_login_count(self, date):
tp = "LOGIN-USER"
count = self.__get_data_from_cache(date, tp)
if count is not None:
return count
ds, de = self.get_date_start_2_end(date)
count = UserLoginLog.objects.filter(datetime__range=(ds, de)).count()
self.__set_data_to_cache(date, tp, count)
return count
def get_dates_metrics_total_count_login(self):
data = []
for d in self.dates_list:
count = self.get_date_login_count(d)
data.append(count)
if len(data) == 0:
data = [0]
return data
def get_date_user_count(self, date):
tp = "USER"
count = self.__get_data_from_cache(date, tp)
if count is not None:
return count
ds, de = self.get_date_start_2_end(date)
count = len(set(Session.objects.filter(date_start__range=(ds, de)).values_list('user_id', flat=True)))
self.__set_data_to_cache(date, tp, count)
return count
queryset = UserLoginLog.objects \
.filter(datetime__range=(self.date_start_end)) \
.values('datetime__date').annotate(id__count=Count(id)) \
.order_by('datetime__date')
map_date_logincount = {i['datetime__date']: i['id__count'] for i in queryset}
return [map_date_logincount.get(d, 0) for d in self.dates_list]
def get_dates_metrics_total_count_active_users(self):
data = []
for d in self.dates_list:
count = self.get_date_user_count(d)
data.append(count)
return data
def get_date_asset_count(self, date):
tp = "ASSET"
count = self.__get_data_from_cache(date, tp)
if count is not None:
return count
ds, de = self.get_date_start_2_end(date)
count = len(set(Session.objects.filter(date_start__range=(ds, de)).values_list('asset', flat=True)))
self.__set_data_to_cache(date, tp, count)
return count
queryset = Session.objects \
.filter(date_start__range=(self.date_start_end)) \
.values('date_start__date') \
.annotate(id__count=Count('user_id', distinct=True)) \
.order_by('date_start__date')
map_date_usercount = {i['date_start__date']: i['id__count'] for i in queryset}
return [map_date_usercount.get(d, 0) for d in self.dates_list]
def get_dates_metrics_total_count_active_assets(self):
data = []
for d in self.dates_list:
count = self.get_date_asset_count(d)
data.append(count)
return data
def get_date_session_count(self, date):
tp = "SESSION"
count = self.__get_data_from_cache(date, tp)
if count is not None:
return count
ds, de = self.get_date_start_2_end(date)
count = Session.objects.filter(date_start__range=(ds, de)).count()
self.__set_data_to_cache(date, tp, count)
return count
queryset = Session.objects \
.filter(date_start__range=(self.date_start_end)) \
.values('date_start__date') \
.annotate(id__count=Count('asset_id', distinct=True)) \
.order_by('date_start__date')
map_date_assetcount = {i['date_start__date']: i['id__count'] for i in queryset}
return [map_date_assetcount.get(d, 0) for d in self.dates_list]
def get_dates_metrics_total_count_sessions(self):
data = []
for d in self.dates_list:
count = self.get_date_session_count(d)
data.append(count)
return data
queryset = Session.objects \
.filter(date_start__range=(self.date_start_end)) \
.values('date_start__date') \
.annotate(id__count=Count(id)) \
.order_by('date_start__date')
map_date_usercount = {i['date_start__date']: i['id__count'] for i in queryset}
return [map_date_usercount.get(d, 0) for d in self.dates_list]
@lazyproperty
def get_type_to_assets(self):

View File

@ -315,7 +315,7 @@ msgstr "理由"
#: accounts/models/automations/backup_account.py:99
#: accounts/serializers/automations/change_secret.py:111
#: accounts/serializers/automations/change_secret.py:134
#: ops/serializers/job.py:56 terminal/serializers/session.py:46
#: ops/serializers/job.py:56 terminal/serializers/session.py:43
msgid "Is success"
msgstr "成功は"
@ -485,8 +485,8 @@ msgstr "アカウントの確認"
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
#: assets/models/group.py:17 assets/models/label.py:18
#: assets/models/platform.py:13 assets/models/platform.py:81
#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:99
#: assets/serializers/platform.py:199
#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:109
#: assets/serializers/platform.py:209
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:92 ops/models/playbook.py:23 ops/serializers/job.py:20
@ -566,7 +566,7 @@ msgstr "アカウントの存在ポリシー"
#: accounts/serializers/account/account.py:180 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:82
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
#: assets/serializers/platform.py:117 assets/serializers/platform.py:200
#: assets/serializers/platform.py:127 assets/serializers/platform.py:210
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13
msgid "Category"
@ -577,13 +577,13 @@ msgstr "カテゴリ"
#: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:83
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:101
#: assets/serializers/platform.py:116 audits/serializers.py:48
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
#: assets/serializers/platform.py:126 audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:103
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:23 terminal/serializers/storage.py:224
#: terminal/serializers/session.py:20 terminal/serializers/storage.py:224
#: terminal/serializers/storage.py:236 tickets/models/comment.py:26
#: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16
#: tickets/models/ticket/general.py:275 tickets/serializers/flow.py:53
@ -693,9 +693,13 @@ msgstr "キーパスワード"
msgid "Spec info"
msgstr "特別情報"
#: accounts/serializers/account/base.py:81
msgid "Tip: If no username is required for authentication, fill in `null`"
msgstr "ヒント: 認証にユーザー名が必要ない場合は、null を入力してください"
#: accounts/serializers/account/base.py:82
msgid ""
"Tip: If no username is required for authentication, fill in `null`, If AD "
"account, like `username@domain`"
msgstr ""
"ヒント: 認証にユーザー名が必要ない場合は、`null`を入力します。ADアカウントの"
"場合は、`username@domain`のようになります。"
#: accounts/serializers/automations/base.py:23
#: assets/models/asset/common.py:155 assets/models/automations/base.py:18
@ -969,7 +973,7 @@ msgstr "アプリケーション"
msgid "Can match application"
msgstr "アプリケーションを一致させることができます"
#: assets/api/asset/asset.py:149
#: assets/api/asset/asset.py:153
msgid "Cannot create asset directly, you should create a host or other"
msgstr ""
"資産を直接作成することはできません。ホストまたはその他を作成する必要がありま"
@ -1049,6 +1053,19 @@ msgstr "テストゲートウェイ"
msgid "Gather facts"
msgstr "資産情報の収集"
#: assets/const/base.py:33 audits/const.py:47
#: terminal/serializers/applet_host.py:32
msgid "Disabled"
msgstr "無効"
#: assets/const/base.py:34 settings/serializers/basic.py:27
msgid "Basic"
msgstr "基本"
#: assets/const/base.py:35 assets/models/asset/web.py:13
msgid "Script"
msgstr "脚本"
#: assets/const/category.py:10 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67
#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17
@ -1111,28 +1128,65 @@ msgstr "ファイアウォール"
msgid "Other"
msgstr "その他"
#: assets/const/protocol.py:39
msgid "SFTP enabled"
msgstr "SFTP が有効"
#: assets/const/protocol.py:44
msgid "SFTP home"
msgstr "SFTP ルート パス"
#: assets/const/protocol.py:55
msgid "Console"
msgstr "Console"
#: assets/const/protocol.py:56
msgid "Connect to console session"
msgstr "コンソールセッションに接続"
#: assets/const/protocol.py:60
msgid "Any"
msgstr "任意"
#: assets/const/protocol.py:62 settings/serializers/security.py:151
msgid "Security"
msgstr "セキュリティ"
#: assets/const/protocol.py:63
msgid "Security layer to use for the connection"
msgstr "接続に使用するセキュリティ レイヤー"
#: assets/const/protocol.py:87 assets/models/asset/database.py:10
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "SSLの使用"
#: assets/const/protocol.py:140
#, fuzzy
#| msgid "Auth with username"
msgid "Auth username"
msgstr "ユーザー名で認証する"
#: assets/const/protocol.py:167 assets/models/asset/web.py:10
msgid "Username selector"
msgstr "ユーザー名ピッカー"
#: assets/const/protocol.py:172 assets/models/asset/web.py:11
msgid "Password selector"
msgstr "パスワードセレクター"
#: assets/const/protocol.py:177 assets/models/asset/web.py:12
msgid "Submit selector"
msgstr "ボタンセレクターを確認する"
#: assets/const/types.py:222
msgid "All types"
msgstr "いろんなタイプ"
#: assets/const/web.py:8
#: assets/const/web.py:7
msgid "Website"
msgstr "Webサイト"
#: assets/const/web.py:59 audits/const.py:47
#: terminal/serializers/applet_host.py:32
msgid "Disabled"
msgstr "無効"
#: assets/const/web.py:60 settings/serializers/basic.py:27
msgid "Basic"
msgstr "基本"
#: assets/const/web.py:61 assets/models/asset/web.py:13
#: assets/serializers/platform.py:40
msgid "Script"
msgstr "脚本"
#: assets/exceptions.py:12
msgid "This function is not supported temporarily"
msgstr "この機能は一時的にサポートされていません"
@ -1199,8 +1253,8 @@ msgstr "ユーザーと同じユーザー名"
#: assets/models/_user.py:52 authentication/models/connection_token.py:41
#: authentication/serializers/connect_token_secret.py:111
#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:21
#: terminal/serializers/session.py:42 terminal/serializers/storage.py:68
#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18
#: terminal/serializers/session.py:39 terminal/serializers/storage.py:68
msgid "Protocol"
msgstr "プロトコル"
@ -1308,11 +1362,6 @@ msgstr "資産ノードを変更できます"
msgid "Custom asset"
msgstr "カスタム アセット"
#: assets/models/asset/database.py:10 assets/serializers/platform.py:45
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "SSLの使用"
#: assets/models/asset/database.py:11
msgid "CA cert"
msgstr "CA 証明書"
@ -1330,22 +1379,9 @@ msgid "Allow invalid cert"
msgstr "証明書チェックを無視"
#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
#: assets/serializers/platform.py:30
msgid "Autofill"
msgstr "自動充填"
#: assets/models/asset/web.py:10 assets/serializers/platform.py:32
msgid "Username selector"
msgstr "ユーザー名ピッカー"
#: assets/models/asset/web.py:11 assets/serializers/platform.py:35
msgid "Password selector"
msgstr "パスワードセレクター"
#: assets/models/asset/web.py:12 assets/serializers/platform.py:38
msgid "Submit selector"
msgstr "ボタンセレクターを確認する"
#: assets/models/automations/base.py:22 ops/models/job.py:187
#: settings/serializers/auth/sms.py:99
msgid "Parameters"
@ -1428,7 +1464,7 @@ msgstr "ゲートウェイ"
msgid "Asset group"
msgstr "資産グループ"
#: assets/models/group.py:31 assets/models/platform.py:17
#: assets/models/group.py:34 assets/models/platform.py:17
#: assets/serializers/platform.py:102
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
@ -1452,7 +1488,7 @@ msgstr "値"
#: assets/models/label.py:40 assets/serializers/asset/common.py:123
#: assets/serializers/cagegory.py:6 assets/serializers/cagegory.py:13
#: assets/serializers/platform.py:100
#: assets/serializers/platform.py:110
#: authentication/serializers/connect_token_secret.py:121
#: common/serializers/common.py:85 perms/serializers/user_permission.py:28
#: settings/serializers/sms.py:7
@ -1500,7 +1536,8 @@ msgstr "必要"
msgid "Public"
msgstr "開ける"
#: assets/models/platform.py:19 settings/serializers/settings.py:67
#: assets/models/platform.py:19 assets/serializers/platform.py:48
#: settings/serializers/settings.py:67
#: users/templates/users/reset_password.html:29
msgid "Setting"
msgstr "設定"
@ -1514,11 +1551,11 @@ msgstr "有効化"
msgid "Ansible config"
msgstr "Ansible 構成"
#: assets/models/platform.py:34 assets/serializers/platform.py:63
#: assets/models/platform.py:34 assets/serializers/platform.py:32
msgid "Ping enabled"
msgstr "アセット ディスカバリを有効にする"
#: assets/models/platform.py:35 assets/serializers/platform.py:64
#: assets/models/platform.py:35 assets/serializers/platform.py:33
msgid "Ping method"
msgstr "資産検出方法"
@ -1527,12 +1564,12 @@ msgid "Ping params"
msgstr "資産検出パラメータ"
#: assets/models/platform.py:38 assets/models/platform.py:62
#: assets/serializers/platform.py:65
#: assets/serializers/platform.py:34
msgid "Gather facts enabled"
msgstr "資産情報の収集を有効にする"
#: assets/models/platform.py:40 assets/models/platform.py:64
#: assets/serializers/platform.py:66
#: assets/serializers/platform.py:35
msgid "Gather facts method"
msgstr "情報収集の方法"
@ -1540,11 +1577,11 @@ msgstr "情報収集の方法"
msgid "Gather facts params"
msgstr "情報収集パラメータ"
#: assets/models/platform.py:44 assets/serializers/platform.py:69
#: assets/models/platform.py:44 assets/serializers/platform.py:38
msgid "Change secret enabled"
msgstr "パスワードの変更が有効"
#: assets/models/platform.py:46 assets/serializers/platform.py:70
#: assets/models/platform.py:46 assets/serializers/platform.py:39
msgid "Change secret method"
msgstr "パスワード変更モード"
@ -1552,11 +1589,11 @@ msgstr "パスワード変更モード"
msgid "Change secret params"
msgstr "パスワード変更パラメータ"
#: assets/models/platform.py:50 assets/serializers/platform.py:71
#: assets/models/platform.py:50 assets/serializers/platform.py:40
msgid "Push account enabled"
msgstr "アカウントのプッシュを有効にする"
#: assets/models/platform.py:52 assets/serializers/platform.py:72
#: assets/models/platform.py:52 assets/serializers/platform.py:41
msgid "Push account method"
msgstr "アカウントプッシュ方式"
@ -1564,11 +1601,11 @@ msgstr "アカウントプッシュ方式"
msgid "Push account params"
msgstr "アカウントプッシュパラメータ"
#: assets/models/platform.py:56 assets/serializers/platform.py:67
#: assets/models/platform.py:56 assets/serializers/platform.py:36
msgid "Verify account enabled"
msgstr "アカウントの確認をオンにする"
#: assets/models/platform.py:58 assets/serializers/platform.py:68
#: assets/models/platform.py:58 assets/serializers/platform.py:37
msgid "Verify account method"
msgstr "アカウント認証方法"
@ -1584,23 +1621,23 @@ msgstr "メタ"
msgid "Internal"
msgstr "ビルトイン"
#: assets/models/platform.py:89 assets/serializers/platform.py:115
#: assets/models/platform.py:89 assets/serializers/platform.py:125
msgid "Charset"
msgstr "シャーセット"
#: assets/models/platform.py:91 assets/serializers/platform.py:143
#: assets/models/platform.py:91 assets/serializers/platform.py:153
msgid "Domain enabled"
msgstr "ドメインを有効にする"
#: assets/models/platform.py:93 assets/serializers/platform.py:142
#: assets/models/platform.py:93 assets/serializers/platform.py:152
msgid "Su enabled"
msgstr "アカウントの切り替えを有効にする"
#: assets/models/platform.py:94 assets/serializers/platform.py:121
#: assets/models/platform.py:94 assets/serializers/platform.py:131
msgid "Su method"
msgstr "アカウントの切り替え方法"
#: assets/models/platform.py:95 assets/serializers/platform.py:124
#: assets/models/platform.py:95 assets/serializers/platform.py:134
msgid "Custom fields"
msgstr "カスタムフィールド"
@ -1617,7 +1654,7 @@ msgstr ""
"プラットフォームタイプがスキップされた資産に合致しない、資産内の一括更新プ"
"ラットフォーム"
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:118
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:128
#: authentication/serializers/connect_token_secret.py:29
#: authentication/serializers/connect_token_secret.py:72
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99
@ -1733,47 +1770,60 @@ msgstr "値"
msgid "Can't contains: /"
msgstr "含まれない:/"
#: assets/serializers/platform.py:26
msgid "SFTP enabled"
msgstr "SFTP が有効"
#: assets/serializers/platform.py:27
msgid "SFTP home"
msgstr "SFTP ルート パス"
#: assets/serializers/platform.py:42
msgid "Auth with username"
msgstr "ユーザー名で認証する"
#: assets/serializers/platform.py:73
msgid "Gather accounts enabled"
msgstr "アカウント収集を有効にする"
#: assets/serializers/platform.py:74
#: assets/serializers/platform.py:43
msgid "Gather accounts method"
msgstr "アカウントの収集方法"
#: assets/serializers/platform.py:103
#: assets/serializers/platform.py:60
msgid ""
"This protocol is primary, and it must be set when adding assets. "
"Additionally, there can only be one primary protocol."
msgstr ""
"このプロトコルはプライマリであり、資産を追加するときに設定する必要がありま"
"す。また、プライマリプロトコルは1つしかありません"
#: assets/serializers/platform.py:65
msgid "This protocol is required, and it must be set when adding assets."
msgstr "このプロトコルは必須であり、資産を追加するときに設定する必要があります"
#: assets/serializers/platform.py:68
msgid ""
"This protocol is default, when adding assets, it will be displayed by "
"default."
msgstr ""
"このプロトコルはデフォルトです。資産を追加するときに、デフォルトで表示されま"
"す"
#: assets/serializers/platform.py:71
msgid "This protocol is public, asset will show this protocol to user"
msgstr ""
"このプロトコルは公開されており、資産はこのプロトコルをユーザーに表示します"
#: assets/serializers/platform.py:113
msgid "Help text"
msgstr "ヘルプ"
#: assets/serializers/platform.py:104
#: assets/serializers/platform.py:114
msgid "Choices"
msgstr "せんたく"
#: assets/serializers/platform.py:119
#: assets/serializers/platform.py:129
msgid "Automation"
msgstr "オートメーション"
#: assets/serializers/platform.py:144
#: assets/serializers/platform.py:154
msgid "Default Domain"
msgstr "デフォルト ドメイン"
#: assets/serializers/platform.py:153
#: assets/serializers/platform.py:163
msgid "type is required"
msgstr "タイプ このフィールドは必須です."
#: assets/serializers/platform.py:176
#: assets/serializers/platform.py:186
msgid "Protocols is required"
msgstr "同意が必要です"
@ -1917,7 +1967,7 @@ msgstr "パスワードを変更する"
#: audits/const.py:35 settings/serializers/terminal.py:6
#: terminal/models/applet/host.py:25 terminal/models/component/terminal.py:163
#: terminal/serializers/session.py:49 terminal/serializers/session.py:58
#: terminal/serializers/session.py:46 terminal/serializers/session.py:55
msgid "Terminal"
msgstr "ターミナル"
@ -3001,6 +3051,9 @@ msgstr "{} 認証へのリダイレクト"
#: authentication/views/login.py:207
msgid "Please enable cookies and try again."
msgstr "クッキーを有効にして、もう一度お試しください。"
#: authentication/views/login.py:207
msgid "Login timeout, please try again."
msgstr "ログインタイムアウト、もう一度お試しください"
#: authentication/views/login.py:248
msgid "User email already exists ({})"
@ -3711,7 +3764,7 @@ msgstr "保存後に実行"
msgid "Job type"
msgstr "タスクの種類"
#: ops/serializers/job.py:57 terminal/serializers/session.py:50
#: ops/serializers/job.py:57 terminal/serializers/session.py:47
msgid "Is finished"
msgstr "終了しました"
@ -4157,23 +4210,23 @@ msgstr "テストの成功"
msgid "Test mail sent to {}, please check"
msgstr "{}に送信されたテストメールを確認してください"
#: settings/api/ldap.py:173
#: settings/api/ldap.py:176
msgid "Synchronization start, please wait."
msgstr "同期開始、お待ちください。"
#: settings/api/ldap.py:177
#: settings/api/ldap.py:180
msgid "Synchronization is running, please wait."
msgstr "同期が実行中です。しばらくお待ちください。"
#: settings/api/ldap.py:182
#: settings/api/ldap.py:185
msgid "Synchronization error: {}"
msgstr "同期エラー: {}"
#: settings/api/ldap.py:220
#: settings/api/ldap.py:223
msgid "Get ldap users is None"
msgstr "Ldapユーザーを取得するにはNone"
#: settings/api/ldap.py:230
#: settings/api/ldap.py:233
msgid "Imported {} users successfully (Organization: {})"
msgstr "{} 人のユーザーを正常にインポートしました (組織: {})"
@ -5087,10 +5140,6 @@ msgstr "ログインcaptchaの有効化"
msgid "Enable captcha to prevent robot authentication"
msgstr "Captchaを有効にしてロボット認証を防止する"
#: settings/serializers/security.py:151
msgid "Security"
msgstr "セキュリティ"
#: settings/serializers/security.py:154
msgid "Enable terminal register"
msgstr "ターミナルレジスタの有効化"
@ -6113,35 +6162,35 @@ msgstr ""
msgid "Asset IP"
msgstr "資産 IP"
#: terminal/serializers/session.py:25 terminal/serializers/session.py:47
#: terminal/serializers/session.py:22 terminal/serializers/session.py:44
msgid "Can replay"
msgstr "再生できます"
#: terminal/serializers/session.py:26 terminal/serializers/session.py:48
#: terminal/serializers/session.py:23 terminal/serializers/session.py:45
msgid "Can join"
msgstr "参加できます"
#: terminal/serializers/session.py:27 terminal/serializers/session.py:51
#: terminal/serializers/session.py:24 terminal/serializers/session.py:48
msgid "Can terminate"
msgstr "終了できます"
#: terminal/serializers/session.py:43
#: terminal/serializers/session.py:40
msgid "User ID"
msgstr "ユーザーID"
#: terminal/serializers/session.py:44
#: terminal/serializers/session.py:41
msgid "Asset ID"
msgstr "資産ID"
#: terminal/serializers/session.py:45
#: terminal/serializers/session.py:42
msgid "Login from display"
msgstr "表示からのログイン"
#: terminal/serializers/session.py:52
#: terminal/serializers/session.py:49
msgid "Terminal display"
msgstr "ターミナルディスプレイ"
#: terminal/serializers/session.py:57
#: terminal/serializers/session.py:54
msgid "Command amount"
msgstr "コマンド量"
@ -7735,3 +7784,6 @@ msgstr "究極のエディション"
#: xpack/plugins/license/models.py:86
msgid "Community edition"
msgstr "コミュニティ版"
#~ msgid "Please enable cookies and try again."
#~ msgstr "クッキーを有効にして、もう一度お試しください。"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-27 16:02+0800\n"
"POT-Creation-Date: 2023-06-15 15:35+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -314,7 +314,7 @@ msgstr "原因"
#: accounts/models/automations/backup_account.py:99
#: accounts/serializers/automations/change_secret.py:111
#: accounts/serializers/automations/change_secret.py:134
#: ops/serializers/job.py:56 terminal/serializers/session.py:46
#: ops/serializers/job.py:56 terminal/serializers/session.py:43
msgid "Is success"
msgstr "是否成功"
@ -484,8 +484,8 @@ msgstr "账号验证"
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
#: assets/models/group.py:17 assets/models/label.py:18
#: assets/models/platform.py:13 assets/models/platform.py:81
#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:99
#: assets/serializers/platform.py:199
#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:109
#: assets/serializers/platform.py:209
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:92 ops/models/playbook.py:23 ops/serializers/job.py:20
@ -562,7 +562,7 @@ msgstr "账号存在策略"
#: accounts/serializers/account/account.py:180 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:82
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
#: assets/serializers/platform.py:117 assets/serializers/platform.py:200
#: assets/serializers/platform.py:127 assets/serializers/platform.py:210
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13
msgid "Category"
@ -573,13 +573,13 @@ msgstr "类别"
#: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:83
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:101
#: assets/serializers/platform.py:116 audits/serializers.py:48
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
#: assets/serializers/platform.py:126 audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:103
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:23 terminal/serializers/storage.py:224
#: terminal/serializers/session.py:20 terminal/serializers/storage.py:224
#: terminal/serializers/storage.py:236 tickets/models/comment.py:26
#: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16
#: tickets/models/ticket/general.py:275 tickets/serializers/flow.py:53
@ -689,9 +689,13 @@ msgstr "密钥密码"
msgid "Spec info"
msgstr "特殊信息"
#: accounts/serializers/account/base.py:81
msgid "Tip: If no username is required for authentication, fill in `null`"
msgstr "提示: 如果认证时不需要用户名,可填写为 null"
#: accounts/serializers/account/base.py:82
msgid ""
"Tip: If no username is required for authentication, fill in `null`, If AD "
"account, like `username@domain`"
msgstr ""
"提示: 如果认证时不需要用户名,可填写为 null, 如果是 AD 账号,格式为 "
"username@domain"
#: accounts/serializers/automations/base.py:23
#: assets/models/asset/common.py:155 assets/models/automations/base.py:18
@ -964,7 +968,7 @@ msgstr "应用程序"
msgid "Can match application"
msgstr "匹配应用"
#: assets/api/asset/asset.py:149
#: assets/api/asset/asset.py:153
msgid "Cannot create asset directly, you should create a host or other"
msgstr "不能直接创建资产, 你应该创建主机或其他资产"
@ -1042,6 +1046,19 @@ msgstr "测试网关"
msgid "Gather facts"
msgstr "收集资产信息"
#: assets/const/base.py:33 audits/const.py:47
#: terminal/serializers/applet_host.py:32
msgid "Disabled"
msgstr "禁用"
#: assets/const/base.py:34 settings/serializers/basic.py:27
msgid "Basic"
msgstr "基本"
#: assets/const/base.py:35 assets/models/asset/web.py:13
msgid "Script"
msgstr "脚本"
#: assets/const/category.py:10 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67
#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17
@ -1104,28 +1121,63 @@ msgstr "防火墙"
msgid "Other"
msgstr "其它"
#: assets/const/protocol.py:39
msgid "SFTP enabled"
msgstr "SFTP 已启用"
#: assets/const/protocol.py:44
msgid "SFTP home"
msgstr "SFTP 根路径"
#: assets/const/protocol.py:55
msgid "Console"
msgstr "控制台"
#: assets/const/protocol.py:56
msgid "Connect to console session"
msgstr "连接到控制台会话"
#: assets/const/protocol.py:60
msgid "Any"
msgstr "任意"
#: assets/const/protocol.py:62 settings/serializers/security.py:151
msgid "Security"
msgstr "安全"
#: assets/const/protocol.py:63
msgid "Security layer to use for the connection"
msgstr "连接 RDP 使用的安全层"
#: assets/const/protocol.py:87 assets/models/asset/database.py:10
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "使用 SSL"
#: assets/const/protocol.py:140
msgid "Auth username"
msgstr "使用用户名认证"
#: assets/const/protocol.py:167 assets/models/asset/web.py:10
msgid "Username selector"
msgstr "用户名选择器"
#: assets/const/protocol.py:172 assets/models/asset/web.py:11
msgid "Password selector"
msgstr "密码选择器"
#: assets/const/protocol.py:177 assets/models/asset/web.py:12
msgid "Submit selector"
msgstr "确认按钮选择器"
#: assets/const/types.py:222
msgid "All types"
msgstr "所有类型"
#: assets/const/web.py:8
#: assets/const/web.py:7
msgid "Website"
msgstr "网站"
#: assets/const/web.py:59 audits/const.py:47
#: terminal/serializers/applet_host.py:32
msgid "Disabled"
msgstr "禁用"
#: assets/const/web.py:60 settings/serializers/basic.py:27
msgid "Basic"
msgstr "基本"
#: assets/const/web.py:61 assets/models/asset/web.py:13
#: assets/serializers/platform.py:40
msgid "Script"
msgstr "脚本"
#: assets/exceptions.py:12
msgid "This function is not supported temporarily"
msgstr "暂时不支持此功能"
@ -1192,8 +1244,8 @@ msgstr "用户名与用户相同"
#: assets/models/_user.py:52 authentication/models/connection_token.py:41
#: authentication/serializers/connect_token_secret.py:111
#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:21
#: terminal/serializers/session.py:42 terminal/serializers/storage.py:68
#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18
#: terminal/serializers/session.py:39 terminal/serializers/storage.py:68
msgid "Protocol"
msgstr "协议"
@ -1301,11 +1353,6 @@ msgstr "可以修改资产节点"
msgid "Custom asset"
msgstr "自定义资产"
#: assets/models/asset/database.py:10 assets/serializers/platform.py:45
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "使用 SSL"
#: assets/models/asset/database.py:11
msgid "CA cert"
msgstr "CA 证书"
@ -1323,22 +1370,9 @@ msgid "Allow invalid cert"
msgstr "忽略证书校验"
#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
#: assets/serializers/platform.py:30
msgid "Autofill"
msgstr "自动代填"
#: assets/models/asset/web.py:10 assets/serializers/platform.py:32
msgid "Username selector"
msgstr "用户名选择器"
#: assets/models/asset/web.py:11 assets/serializers/platform.py:35
msgid "Password selector"
msgstr "密码选择器"
#: assets/models/asset/web.py:12 assets/serializers/platform.py:38
msgid "Submit selector"
msgstr "确认按钮选择器"
#: assets/models/automations/base.py:22 ops/models/job.py:187
#: settings/serializers/auth/sms.py:99
msgid "Parameters"
@ -1421,7 +1455,7 @@ msgstr "网关"
msgid "Asset group"
msgstr "资产组"
#: assets/models/group.py:31 assets/models/platform.py:17
#: assets/models/group.py:34 assets/models/platform.py:17
#: assets/serializers/platform.py:102
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
@ -1445,7 +1479,7 @@ msgstr "值"
#: assets/models/label.py:40 assets/serializers/asset/common.py:123
#: assets/serializers/cagegory.py:6 assets/serializers/cagegory.py:13
#: assets/serializers/platform.py:100
#: assets/serializers/platform.py:110
#: authentication/serializers/connect_token_secret.py:121
#: common/serializers/common.py:85 perms/serializers/user_permission.py:28
#: settings/serializers/sms.py:7
@ -1493,7 +1527,8 @@ msgstr "必须的"
msgid "Public"
msgstr "开放的"
#: assets/models/platform.py:19 settings/serializers/settings.py:67
#: assets/models/platform.py:19 assets/serializers/platform.py:48
#: settings/serializers/settings.py:67
#: users/templates/users/reset_password.html:29
msgid "Setting"
msgstr "设置"
@ -1507,11 +1542,11 @@ msgstr "启用"
msgid "Ansible config"
msgstr "Ansible 配置"
#: assets/models/platform.py:34 assets/serializers/platform.py:63
#: assets/models/platform.py:34 assets/serializers/platform.py:32
msgid "Ping enabled"
msgstr "启用资产探活"
#: assets/models/platform.py:35 assets/serializers/platform.py:64
#: assets/models/platform.py:35 assets/serializers/platform.py:33
msgid "Ping method"
msgstr "资产探活方式"
@ -1520,12 +1555,12 @@ msgid "Ping params"
msgstr "资产探活参数"
#: assets/models/platform.py:38 assets/models/platform.py:62
#: assets/serializers/platform.py:65
#: assets/serializers/platform.py:34
msgid "Gather facts enabled"
msgstr "启用收集资产信息"
#: assets/models/platform.py:40 assets/models/platform.py:64
#: assets/serializers/platform.py:66
#: assets/serializers/platform.py:35
msgid "Gather facts method"
msgstr "收集信息方式"
@ -1533,11 +1568,11 @@ msgstr "收集信息方式"
msgid "Gather facts params"
msgstr "收集信息参数"
#: assets/models/platform.py:44 assets/serializers/platform.py:69
#: assets/models/platform.py:44 assets/serializers/platform.py:38
msgid "Change secret enabled"
msgstr "启用改密"
#: assets/models/platform.py:46 assets/serializers/platform.py:70
#: assets/models/platform.py:46 assets/serializers/platform.py:39
msgid "Change secret method"
msgstr "改密方式"
@ -1545,11 +1580,11 @@ msgstr "改密方式"
msgid "Change secret params"
msgstr "改密参数"
#: assets/models/platform.py:50 assets/serializers/platform.py:71
#: assets/models/platform.py:50 assets/serializers/platform.py:40
msgid "Push account enabled"
msgstr "启用账号推送"
#: assets/models/platform.py:52 assets/serializers/platform.py:72
#: assets/models/platform.py:52 assets/serializers/platform.py:41
msgid "Push account method"
msgstr "账号推送方式"
@ -1557,11 +1592,11 @@ msgstr "账号推送方式"
msgid "Push account params"
msgstr "账号推送参数"
#: assets/models/platform.py:56 assets/serializers/platform.py:67
#: assets/models/platform.py:56 assets/serializers/platform.py:36
msgid "Verify account enabled"
msgstr "开启账号验证"
#: assets/models/platform.py:58 assets/serializers/platform.py:68
#: assets/models/platform.py:58 assets/serializers/platform.py:37
msgid "Verify account method"
msgstr "账号验证方式"
@ -1577,23 +1612,23 @@ msgstr "元数据"
msgid "Internal"
msgstr "内置"
#: assets/models/platform.py:89 assets/serializers/platform.py:115
#: assets/models/platform.py:89 assets/serializers/platform.py:125
msgid "Charset"
msgstr "编码"
#: assets/models/platform.py:91 assets/serializers/platform.py:143
#: assets/models/platform.py:91 assets/serializers/platform.py:153
msgid "Domain enabled"
msgstr "启用网域"
#: assets/models/platform.py:93 assets/serializers/platform.py:142
#: assets/models/platform.py:93 assets/serializers/platform.py:152
msgid "Su enabled"
msgstr "启用账号切换"
#: assets/models/platform.py:94 assets/serializers/platform.py:121
#: assets/models/platform.py:94 assets/serializers/platform.py:131
msgid "Su method"
msgstr "账号切换方式"
#: assets/models/platform.py:95 assets/serializers/platform.py:124
#: assets/models/platform.py:95 assets/serializers/platform.py:134
msgid "Custom fields"
msgstr "自定义属性"
@ -1608,7 +1643,7 @@ msgid ""
"type"
msgstr "资产中批量更新平台,不符合平台类型跳过的资产"
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:118
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:128
#: authentication/serializers/connect_token_secret.py:29
#: authentication/serializers/connect_token_secret.py:72
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99
@ -1724,47 +1759,55 @@ msgstr "值"
msgid "Can't contains: /"
msgstr "不能包含: /"
#: assets/serializers/platform.py:26
msgid "SFTP enabled"
msgstr "SFTP 已启用"
#: assets/serializers/platform.py:27
msgid "SFTP home"
msgstr "SFTP 根路径"
#: assets/serializers/platform.py:42
msgid "Auth with username"
msgstr "使用用户名认证"
#: assets/serializers/platform.py:73
msgid "Gather accounts enabled"
msgstr "启用账号收集"
#: assets/serializers/platform.py:74
#: assets/serializers/platform.py:43
msgid "Gather accounts method"
msgstr "收集账号方式"
#: assets/serializers/platform.py:103
#: assets/serializers/platform.py:60
msgid ""
"This protocol is primary, and it must be set when adding assets. "
"Additionally, there can only be one primary protocol."
msgstr "该协议是主要的,添加资产时必须设置。并且只能有一个主要协议"
#: assets/serializers/platform.py:65
msgid "This protocol is required, and it must be set when adding assets."
msgstr "该协议是必填的,添加资产时必须设置"
#: assets/serializers/platform.py:68
msgid ""
"This protocol is default, when adding assets, it will be displayed by "
"default."
msgstr "该协议是默认的,添加资产时,将默认显示"
#: assets/serializers/platform.py:71
msgid "This protocol is public, asset will show this protocol to user"
msgstr "该协议是公开的,资产将向用户显示该协议并可以连接使用"
#: assets/serializers/platform.py:113
msgid "Help text"
msgstr "帮助"
#: assets/serializers/platform.py:104
#: assets/serializers/platform.py:114
msgid "Choices"
msgstr "选择"
#: assets/serializers/platform.py:119
#: assets/serializers/platform.py:129
msgid "Automation"
msgstr "自动化"
#: assets/serializers/platform.py:144
#: assets/serializers/platform.py:154
msgid "Default Domain"
msgstr "默认网域"
#: assets/serializers/platform.py:153
#: assets/serializers/platform.py:163
msgid "type is required"
msgstr "类型 该字段是必填项。"
#: assets/serializers/platform.py:176
#: assets/serializers/platform.py:186
msgid "Protocols is required"
msgstr "协议是必填的"
@ -1906,7 +1949,7 @@ msgstr "改密"
#: audits/const.py:35 settings/serializers/terminal.py:6
#: terminal/models/applet/host.py:25 terminal/models/component/terminal.py:163
#: terminal/serializers/session.py:49 terminal/serializers/session.py:58
#: terminal/serializers/session.py:46 terminal/serializers/session.py:55
msgid "Terminal"
msgstr "终端"
@ -2964,14 +3007,14 @@ msgid "Redirecting to {} authentication"
msgstr "正在跳转到 {} 认证"
#: authentication/views/login.py:207
msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie"
msgid "Login timeout, please try again."
msgstr "登录超时,请重新登录"
#: authentication/views/login.py:248
#: authentication/views/login.py:247
msgid "User email already exists ({})"
msgstr "用户邮箱已存在 ({})"
#: authentication/views/login.py:326
#: authentication/views/login.py:325
msgid ""
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
" Don't close this page"
@ -2979,15 +3022,15 @@ msgstr ""
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
" 不要关闭本页面"
#: authentication/views/login.py:331
#: authentication/views/login.py:330
msgid "No ticket found"
msgstr "没有发现工单"
#: authentication/views/login.py:367
#: authentication/views/login.py:366
msgid "Logout success"
msgstr "退出登录成功"
#: authentication/views/login.py:368
#: authentication/views/login.py:367
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
@ -3669,7 +3712,7 @@ msgstr "保存后执行"
msgid "Job type"
msgstr "任务类型"
#: ops/serializers/job.py:57 terminal/serializers/session.py:50
#: ops/serializers/job.py:57 terminal/serializers/session.py:47
msgid "Is finished"
msgstr "是否完成"
@ -4113,23 +4156,23 @@ msgstr "测试成功"
msgid "Test mail sent to {}, please check"
msgstr "邮件已经发送{}, 请检查"
#: settings/api/ldap.py:173
#: settings/api/ldap.py:176
msgid "Synchronization start, please wait."
msgstr "同步开始,请稍等"
#: settings/api/ldap.py:177
#: settings/api/ldap.py:180
msgid "Synchronization is running, please wait."
msgstr "同步正在运行,请稍等"
#: settings/api/ldap.py:182
#: settings/api/ldap.py:185
msgid "Synchronization error: {}"
msgstr "同步错误: {}"
#: settings/api/ldap.py:220
#: settings/api/ldap.py:223
msgid "Get ldap users is None"
msgstr "获取 LDAP 用户为 None"
#: settings/api/ldap.py:230
#: settings/api/ldap.py:233
msgid "Imported {} users successfully (Organization: {})"
msgstr "成功导入 {} 个用户 ( 组织: {} )"
@ -5022,10 +5065,6 @@ msgstr "启用登录验证码"
msgid "Enable captcha to prevent robot authentication"
msgstr "开启验证码,防止机器人登录"
#: settings/serializers/security.py:151
msgid "Security"
msgstr "安全"
#: settings/serializers/security.py:154
msgid "Enable terminal register"
msgstr "终端注册"
@ -6026,35 +6065,35 @@ msgstr "如果不同端点下的资产 IP 有冲突,使用资产标签实现"
msgid "Asset IP"
msgstr "资产 IP"
#: terminal/serializers/session.py:25 terminal/serializers/session.py:47
#: terminal/serializers/session.py:22 terminal/serializers/session.py:44
msgid "Can replay"
msgstr "是否可重放"
#: terminal/serializers/session.py:26 terminal/serializers/session.py:48
#: terminal/serializers/session.py:23 terminal/serializers/session.py:45
msgid "Can join"
msgstr "是否可加入"
#: terminal/serializers/session.py:27 terminal/serializers/session.py:51
#: terminal/serializers/session.py:24 terminal/serializers/session.py:48
msgid "Can terminate"
msgstr "是否可中断"
#: terminal/serializers/session.py:43
#: terminal/serializers/session.py:40
msgid "User ID"
msgstr "用户 ID"
#: terminal/serializers/session.py:44
#: terminal/serializers/session.py:41
msgid "Asset ID"
msgstr "资产 ID"
#: terminal/serializers/session.py:45
#: terminal/serializers/session.py:42
msgid "Login from display"
msgstr "登录来源名称"
#: terminal/serializers/session.py:52
#: terminal/serializers/session.py:49
msgid "Terminal display"
msgstr "终端显示"
#: terminal/serializers/session.py:57
#: terminal/serializers/session.py:54
msgid "Command amount"
msgstr "命令数量"
@ -7626,3 +7665,6 @@ msgstr "旗舰版"
#: xpack/plugins/license/models.py:86
msgid "Community edition"
msgstr "社区版"
#~ msgid "Please enable cookies and try again."
#~ msgstr "设置你的浏览器支持cookie"

View File

@ -194,7 +194,7 @@ class Message(metaclass=MessageType):
return self.markdown_msg
def get_feishu_msg(self) -> dict:
return self.text_msg
return self.markdown_msg
def get_email_msg(self) -> dict:
return self.html_msg_with_sign

View File

@ -109,21 +109,21 @@ class DefaultCallback:
pass
def playbook_on_stats(self, event_data, **kwargs):
failed = []
error_func = lambda err, task_detail: err + f"{task_detail[0]}: {task_detail[1]['stderr']};"
for tp in ['dark', 'failures']:
for host, tasks in self.result[tp].items():
failed.append(host)
error = reduce(error_func, tasks.items(), '').strip(';')
self.summary[tp][host] = error
failures = list(self.result['failures'].keys())
dark_or_failures = list(self.result['dark'].keys()) + failures
for host, tasks in self.result.get('ignored', {}).items():
ignore_errors = reduce(error_func, tasks.items(), '').strip(';')
if host in failed:
if host in failures:
self.summary['failures'][host] += {ignore_errors}
self.summary['ok'] = list(set(self.result['ok'].keys()) - set(failed))
self.summary['skipped'] = list(set(self.result['skipped'].keys()) - set(failed))
self.summary['ok'] = list(set(self.result['ok'].keys()) - set(dark_or_failures))
self.summary['skipped'] = list(set(self.result['skipped'].keys()) - set(dark_or_failures))
def playbook_on_include(self, event_data, **kwargs):
pass

View File

@ -10,7 +10,7 @@ from rest_framework.generics import CreateAPIView
from rest_framework.views import Response, APIView
from common.api import AsyncApiMixin
from common.utils import get_logger, is_uuid
from common.utils import get_logger
from orgs.models import Organization
from orgs.utils import current_org
from users.models import User
@ -166,6 +166,9 @@ class LDAPUserListApi(generics.ListAPIView):
sync_util = LDAPSyncUtil()
# 还没有同步任务
if sync_util.task_no_start:
ok, msg = LDAPTestUtil().test_config()
if not ok:
return Response(data={'msg': msg}, status=400)
# 任务外部设置 task running 状态
sync_util.set_task_status(sync_util.TASK_STATUS_IS_RUNNING)
t = threading.Thread(target=sync_ldap_user)

View File

@ -39,7 +39,7 @@ class WebMethod(TextChoices):
if not settings.XPACK_ENABLED:
return methods
web_gui_dbs = [Protocol.mysql, Protocol.mariadb, Protocol.oracle, Protocol.postgresql]
web_gui_dbs = [Protocol.mysql, Protocol.mariadb, Protocol.oracle, Protocol.postgresql, Protocol.sqlserver]
for db in web_gui_dbs:
methods[db].append(cls.web_gui)
return methods
@ -188,7 +188,7 @@ class ConnectMethodUtil:
'listen': [Protocol.http],
'support': [
Protocol.mysql, Protocol.postgresql,
Protocol.oracle
Protocol.oracle, Protocol.sqlserver,
],
'match': 'm2m'
},

View File

@ -1,7 +1,6 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from assets.const import Protocol
from common.serializers.fields import LabeledChoiceField
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .terminal import TerminalSmallSerializer
@ -14,11 +13,9 @@ __all__ = [
]
class SessionSerializer(BulkOrgResourceModelSerializer):
org_id = serializers.CharField(allow_blank=True)
protocol = serializers.ChoiceField(choices=Protocol.choices, label=_("Protocol"))
protocol = serializers.CharField(max_length=128, label=_("Protocol"))
type = LabeledChoiceField(
choices=SessionType.choices, label=_("Type"), default=SessionType.normal
)