Merge pull request #9733 from jumpserver/dev

v3.0.0
This commit is contained in:
Jiangjie.Bai 2023-02-23 20:15:55 +08:00 committed by GitHub
commit 19276e6bd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 597 additions and 499 deletions

View File

@ -21,7 +21,7 @@ jobs:
TAG=$(basename ${GITHUB_REF})
VERSION=${TAG/v/}
wget https://raw.githubusercontent.com/jumpserver/installer/master/quick_start.sh
sed -i "s@Version=.*@Version=v${VERSION}@g" quick_start.sh
sed -i "s@VERSION=dev@VERSION=v${VERSION}@g" quick_start.sh
echo "::set-output name=TAG::$TAG"
echo "::set-output name=VERSION::$VERSION"
- name: Create Release

View File

@ -7,18 +7,16 @@ from accounts import serializers
from accounts.filters import AccountFilterSet
from accounts.models import Account
from assets.models import Asset
from authentication.const import ConfirmType
from common.permissions import UserConfirmation
from common.permissions import UserConfirmation, ConfirmType
from common.views.mixins import RecordViewLogMixin
from orgs.mixins.api import OrgBulkModelViewSet
from rbac.permissions import RBACPermission
__all__ = [
'AccountViewSet', 'AccountSecretsViewSet',
'AccountHistoriesSecretAPI'
]
from rbac.permissions import RBACPermission
class AccountViewSet(OrgBulkModelViewSet):
model = Account
@ -71,7 +69,7 @@ class AccountHistoriesSecretAPI(RecordViewLogMixin, ListAPIView):
http_method_names = ['get', 'options']
permission_classes = [RBACPermission, UserConfirmation.require(ConfirmType.MFA)]
rbac_perms = {
'list': 'accounts.view_accountsecret',
'GET': 'accounts.view_accountsecret',
}
def get_object(self):

View File

@ -0,0 +1,17 @@
# Generated by Django 3.2.16 on 2023-02-23 09:59
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0007_alter_account_options'),
]
operations = [
migrations.AlterModelOptions(
name='gatheredaccount',
options={'ordering': ['asset'], 'verbose_name': 'Gather account automation'},
),
]

View File

@ -1,10 +1,8 @@
from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.utils.translation import ugettext_lazy as _
from orgs.mixins.models import JMSOrgBaseModel
from accounts.const import AutomationTypes
from orgs.mixins.models import JMSOrgBaseModel
from .base import AccountBaseAutomation
__all__ = ['GatherAccountsAutomation', 'GatheredAccount']
@ -22,7 +20,7 @@ class GatheredAccount(JMSOrgBaseModel):
return self.asset.address
class Meta:
verbose_name = _('Gather account')
verbose_name = _('Gather account automation')
unique_together = [
('username', 'asset'),
]

View File

@ -77,7 +77,7 @@ class AccountAssetSerializer(serializers.ModelSerializer):
class Meta:
model = Asset
fields = ['id', 'name', 'address', 'type', 'category', 'platform']
fields = ['id', 'name', 'address', 'type', 'category', 'platform', 'auto_info']
def to_internal_value(self, data):
if isinstance(data, dict):
@ -119,7 +119,7 @@ class AccountSerializer(AccountSerializerCreateMixin, BaseAccountSerializer):
def setup_eager_loading(cls, queryset):
""" Perform necessary eager loading of data. """
queryset = queryset \
.prefetch_related('asset', 'asset__platform')
.prefetch_related('asset', 'asset__platform', 'asset__platform__automation')
return queryset

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from accounts.const import (

View File

@ -47,7 +47,7 @@ def verify_accounts_connectivity_util(accounts, task_name):
@shared_task(
queue="ansible", verbose_name=_('Verify asset account availability'),
activity_callback=lambda self, account_ids, asset_ids: (account_ids, None)
activity_callback=lambda self, account_ids, *args, **kwargs: (account_ids, None)
)
def verify_accounts_connectivity_task(account_ids):
from accounts.models import Account, VerifyAccountAutomation

View File

@ -9,7 +9,7 @@ import yaml
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext as _
from sshtunnel import SSHTunnelForwarder
from sshtunnel import SSHTunnelForwarder, BaseSSHTunnelForwarderError
from assets.automations.methods import platform_automation_methods
from common.utils import get_logger, lazyproperty
@ -229,7 +229,7 @@ class BasePlaybookManager:
def local_gateway_prepare(self, runner):
info = self.file_to_json(runner.inventory)
servers = []
servers, not_valid = [], []
for k, host in info['all']['hosts'].items():
jms_asset, jms_gateway = host['jms_asset'], host.get('gateway')
if not jms_gateway:
@ -240,10 +240,20 @@ class BasePlaybookManager:
ssh_password=jms_gateway['secret'],
remote_bind_address=(jms_asset['address'], jms_asset['port'])
)
server.start()
jms_asset['address'] = '127.0.0.1'
jms_asset['port'] = server.local_bind_port
servers.append(server)
try:
server.start()
except BaseSSHTunnelForwarderError:
err_msg = 'Gateway is not active: %s' % jms_asset.get('name', '')
print('\033[31m %s \033[0m\n' % err_msg)
not_valid.append(k)
else:
jms_asset['address'] = '127.0.0.1'
jms_asset['port'] = server.local_bind_port
servers.append(server)
# 网域不可连接的,就不继续执行此资源的后续任务了
for a in set(not_valid):
info['all']['hosts'].pop(a)
self.json_to_file(runner.inventory, info)
self.gateway_servers[runner.id] = servers

View File

@ -156,6 +156,7 @@ class Asset(NodesRelationMixin, AbsConnectivity, JMSOrgBaseModel):
'ping_enabled': automation.ping_enabled,
'domain_enabled': platform.domain_enabled,
'ansible_enabled': automation.ansible_enabled,
'push_account_enabled': automation.push_account_enabled,
'gather_facts_enabled': automation.gather_facts_enabled,
'change_secret_enabled': automation.change_secret_enabled,
'verify_account_enabled': automation.verify_account_enabled,

View File

@ -11,7 +11,6 @@ from accounts.serializers import AccountSerializerCreateValidateMixin
from accounts.serializers import AuthValidateMixin
from common.serializers import WritableNestedModelSerializer, SecretReadableMixin, CommonModelSerializer
from common.serializers.fields import LabeledChoiceField
from common.utils import lazyproperty
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from ...const import Category, AllTypes
from ...models import Asset, Node, Platform, Label, Protocol
@ -136,9 +135,11 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
read_only_fields = [
'category', 'type', 'connectivity',
'date_verified', 'created_by', 'date_created',
'auto_info',
]
fields = fields_small + fields_fk + fields_m2m + read_only_fields
extra_kwargs = {
'auto_info': {'label': _('Auto info')},
'name': {'label': _("Name")},
'address': {'label': _('Address')},
'nodes_display': {'label': _('Node path')},
@ -182,10 +183,10 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
@classmethod
def setup_eager_loading(cls, queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.prefetch_related('domain', 'platform') \
queryset = queryset.prefetch_related('domain', 'nodes', 'labels', 'protocols') \
.prefetch_related('platform', 'platform__automation') \
.annotate(category=F("platform__category")) \
.annotate(type=F("platform__type"))
queryset = queryset.prefetch_related('nodes', 'labels', 'protocols')
return queryset
@staticmethod
@ -204,7 +205,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
nodes_to_set.append(node)
instance.nodes.set(nodes_to_set)
@lazyproperty
@property
def _initial_data_platform(self):
if self.instance:
return self.instance.platform

View File

@ -25,7 +25,7 @@ class HostInfoSerializer(serializers.Serializer):
class HostSerializer(AssetSerializer):
info = HostInfoSerializer(required=False)
info = HostInfoSerializer(required=False, label=_('Info'))
class Meta(AssetSerializer.Meta):
model = Host

View File

@ -87,9 +87,6 @@ class PlatformProtocolsSerializer(serializers.ModelSerializer):
class PlatformSerializer(WritableNestedModelSerializer):
name = serializers.CharField(
label=_("Name"), max_length=50, validators=[validators.validate_unicode_slug]
)
charset = LabeledChoiceField(
choices=Platform.CharsetChoices.choices, label=_("Charset")
)

View File

@ -51,7 +51,7 @@ class OperateLogStore(object):
for k, v in raw_diff.items():
before, after = v.split(cls.SEP, 1)
diff_list.append({
'field': k,
'field': _(k),
'before': before if before else _('empty'),
'after': after if after else _('empty'),
})

View File

@ -80,6 +80,8 @@ class OperateLogActionDetailSerializer(serializers.ModelSerializer):
class OperateLogSerializer(serializers.ModelSerializer):
action = LabeledChoiceField(choices=ActionChoices.choices, label=_("Action"))
resource = serializers.SerializerMethodField(label=_("Resource"))
resource_type = serializers.SerializerMethodField(label=_('Resource Type'))
class Meta:
model = models.OperateLog
@ -91,6 +93,14 @@ class OperateLogSerializer(serializers.ModelSerializer):
]
fields = fields_small
@staticmethod
def get_resource_type(instance):
return _(instance.resource_type)
@staticmethod
def get_resource(instance):
return i18n_trans(instance.resource)
class PasswordChangeLogSerializer(serializers.ModelSerializer):
class Meta:

View File

@ -57,8 +57,8 @@ class ActivityLogHandler:
resource_ids, org_id, user = data + ('',) * (3 - len(data))
if not user:
user = str(current_request.user) if current_request else 'System'
if org_id is None:
org_id = current_org.org_id
if not org_id:
org_id = current_org.id
task_display = getattr(task, 'verbose_name', _('Unknown'))
detail = i18n_fmt(
gettext_noop('User %s perform a task for this resource: %s'),

View File

@ -5,6 +5,7 @@ import uuid
from django.apps import apps
from django.db.models.signals import post_save, pre_save, m2m_changed, pre_delete
from django.dispatch import receiver
from django.utils import translation
from audits.handler import (
get_instance_current_with_cache_diff, cache_instance_before_data,
@ -29,39 +30,40 @@ def on_m2m_changed(sender, action, instance, reverse, model, pk_set, **kwargs):
if not instance:
return
resource_type = instance._meta.verbose_name
current_instance = model_to_dict(instance, include_model_fields=False)
with translation.override('en'):
resource_type = instance._meta.verbose_name
current_instance = model_to_dict(instance, include_model_fields=False)
instance_id = current_instance.get('id')
log_id, before_instance = get_instance_dict_from_cache(instance_id)
instance_id = current_instance.get('id')
log_id, before_instance = get_instance_dict_from_cache(instance_id)
field_name = str(model._meta.verbose_name)
objs = model.objects.filter(pk__in=pk_set)
objs_display = [str(o) for o in objs]
action = M2M_ACTION[action]
changed_field = current_instance.get(field_name, [])
field_name = str(model._meta.verbose_name)
objs = model.objects.filter(pk__in=pk_set)
objs_display = [str(o) for o in objs]
action = M2M_ACTION[action]
changed_field = current_instance.get(field_name, [])
after, before, before_value = None, None, None
if action == ActionChoices.create:
before_value = list(set(changed_field) - set(objs_display))
elif action == ActionChoices.delete:
before_value = list(
set(changed_field).symmetric_difference(set(objs_display))
after, before, before_value = None, None, None
if action == ActionChoices.create:
before_value = list(set(changed_field) - set(objs_display))
elif action == ActionChoices.delete:
before_value = list(
set(changed_field).symmetric_difference(set(objs_display))
)
if changed_field:
after = {field_name: changed_field}
if before_value:
before = {field_name: before_value}
if sorted(str(before)) == sorted(str(after)):
return
create_or_update_operate_log(
ActionChoices.update, resource_type,
resource=instance, log_id=log_id, before=before, after=after
)
if changed_field:
after = {field_name: changed_field}
if before_value:
before = {field_name: before_value}
if sorted(str(before)) == sorted(str(after)):
return
create_or_update_operate_log(
ActionChoices.update, resource_type,
resource=instance, log_id=log_id, before=before, after=after
)
def signal_of_operate_log_whether_continue(
sender, instance, created, update_fields=None
@ -93,18 +95,18 @@ def on_object_pre_create_or_update(
)
if not ok:
return
with translation.override('en'):
# users.PrivateToken Model 没有 id 有 pk字段
instance_id = getattr(instance, 'id', getattr(instance, 'pk', None))
instance_before_data = {'id': instance_id}
raw_instance = type(instance).objects.filter(pk=instance_id).first()
# users.PrivateToken Model 没有 id 有 pk字段
instance_id = getattr(instance, 'id', getattr(instance, 'pk', None))
instance_before_data = {'id': instance_id}
raw_instance = type(instance).objects.filter(pk=instance_id).first()
if raw_instance:
instance_before_data = model_to_dict(raw_instance)
operate_log_id = str(uuid.uuid4())
instance_before_data['operate_log_id'] = operate_log_id
setattr(instance, 'operate_log_id', operate_log_id)
cache_instance_before_data(instance_before_data)
if raw_instance:
instance_before_data = model_to_dict(raw_instance)
operate_log_id = str(uuid.uuid4())
instance_before_data['operate_log_id'] = operate_log_id
setattr(instance, 'operate_log_id', operate_log_id)
cache_instance_before_data(instance_before_data)
@receiver(post_save)
@ -116,23 +118,23 @@ def on_object_created_or_update(
)
if not ok:
return
with translation.override('en'):
log_id, before, after = None, None, None
if created:
action = ActionChoices.create
after = model_to_dict(instance)
log_id = getattr(instance, 'operate_log_id', None)
else:
action = ActionChoices.update
current_instance = model_to_dict(instance)
log_id, before, after = get_instance_current_with_cache_diff(current_instance)
log_id, before, after = None, None, None
if created:
action = ActionChoices.create
after = model_to_dict(instance)
log_id = getattr(instance, 'operate_log_id', None)
else:
action = ActionChoices.update
current_instance = model_to_dict(instance)
log_id, before, after = get_instance_current_with_cache_diff(current_instance)
resource_type = sender._meta.verbose_name
object_name = sender._meta.object_name
create_or_update_operate_log(
action, resource_type, resource=instance, log_id=log_id,
before=before, after=after, object_name=object_name
)
resource_type = sender._meta.verbose_name
object_name = sender._meta.object_name
create_or_update_operate_log(
action, resource_type, resource=instance, log_id=log_id,
before=before, after=after, object_name=object_name
)
@receiver(pre_delete)
@ -141,11 +143,12 @@ def on_object_delete(sender, instance=None, **kwargs):
if not ok:
return
resource_type = sender._meta.verbose_name
create_or_update_operate_log(
ActionChoices.delete, resource_type,
resource=instance, before=model_to_dict(instance)
)
with translation.override('en'):
resource_type = sender._meta.verbose_name
create_or_update_operate_log(
ActionChoices.delete, resource_type,
resource=instance, before=model_to_dict(instance)
)
@receiver(django_ready)

View File

@ -45,15 +45,6 @@ def write_login_log(*args, **kwargs):
UserLoginLog.objects.create(**kwargs)
def get_resource_display(resource):
resource_display = str(resource)
setting_serializer = SettingsSerializer()
label = setting_serializer.get_field_label(resource_display)
if label is not None:
resource_display = label
return resource_display
def _get_instance_field_value(
instance, include_model_fields,
model_need_continue_fields, exclude_fields=None

View File

@ -75,6 +75,8 @@ class BaseFileRenderer(BaseRenderer):
value = item.get(field.field_name)
if value is None:
value = ''
elif isinstance(value, dict):
value = json.dumps(value, ensure_ascii=False)
else:
value = str(value)
row.append(value)

View File

@ -10,11 +10,11 @@ from .utils import get_logger
logger = get_logger(__file__)
def task_activity_callback(self, subject, message, from_email, recipient_list, **kwargs):
def task_activity_callback(self, subject, message, recipient_list, **kwargs):
from users.models import User
email_list = recipient_list
resource_ids = list(User.objects.filter(email__in=email_list).values_list('id', flat=True))
return resource_ids
return resource_ids,
@shared_task(verbose_name=_("Send email"), activity_callback=task_activity_callback)

View File

@ -86,12 +86,11 @@ def get_request_os(request):
"""获取请求的操作系统"""
agent = request.META.get('HTTP_USER_AGENT', '').lower()
if agent is None:
return 'unknown'
if 'windows' in agent.lower():
if 'windows' in agent:
return 'windows'
if 'mac' in agent.lower():
elif 'mac' in agent:
return 'mac'
if 'linux' in agent.lower():
elif 'linux' in agent:
return 'linux'
return 'unknown'
else:
return 'unknown'

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
#
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.mixins import UserPassesTestMixin
from django.http.response import JsonResponse
@ -66,8 +67,9 @@ class RecordViewLogMixin:
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
resource_display = self.get_resource_display(request)
resource_type = self.model._meta.verbose_name
with translation.override('en'):
resource_display = self.get_resource_display(request)
resource_type = self.model._meta.verbose_name
create_or_update_operate_log(
self.ACTION, resource_type, force=True,
resource_display=resource_display
@ -76,8 +78,9 @@ class RecordViewLogMixin:
def retrieve(self, request, *args, **kwargs):
response = super().retrieve(request, *args, **kwargs)
resource_type = self.model._meta.verbose_name
create_or_update_operate_log(
self.ACTION, resource_type, force=True, resource=self.get_object()
)
with translation.override('en'):
resource_type = self.model._meta.verbose_name
create_or_update_operate_log(
self.ACTION, resource_type, force=True, resource=self.get_object()
)
return response

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:af57d16430705feb02ebbb99fc3a2f5fc3bab69209f558aa4d69b1e8055a6f5f
size 136036
oid sha256:8c2600b7094db2a9e64862169ff1c826d5064fae9b9e71744545a1cea88cbc65
size 136280

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-22 21:23+0800\n"
"POT-Creation-Date: 2023-02-23 19:11+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"
@ -70,7 +70,7 @@ msgstr "ローカル"
msgid "Collected"
msgstr ""
#: accounts/const/automation.py:22 rbac/tree.py:51
#: accounts/const/automation.py:22 rbac/tree.py:50
msgid "Push account"
msgstr "アカウントプッシュ"
@ -159,20 +159,20 @@ msgid "Only create"
msgstr "作成のみ"
#: accounts/models/account.py:47
#: accounts/models/automations/gather_account.py:16
#: accounts/models/automations/gather_account.py:14
#: accounts/serializers/account/account.py:95
#: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:111
#: accounts/serializers/automations/change_secret.py:131
#: acls/models/base.py:100 acls/serializers/base.py:56
#: assets/models/asset/common.py:92 assets/models/asset/common.py:279
#: assets/models/asset/common.py:92 assets/models/asset/common.py:280
#: assets/models/cmd_filter.py:36 assets/serializers/domain.py:19
#: assets/serializers/label.py:27 audits/models.py:48
#: authentication/models/connection_token.py:33
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:27
#: terminal/backends/command/models.py:20 terminal/models/session/session.py:32
#: terminal/notifications.py:95 terminal/serializers/command.py:17
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:220
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "資産"
@ -195,7 +195,7 @@ msgstr "ソース"
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
#: acls/models/base.py:102 acls/serializers/base.py:57
#: assets/serializers/asset/common.py:125 assets/serializers/gateway.py:28
#: assets/serializers/asset/common.py:124 assets/serializers/gateway.py:28
#: audits/models.py:49 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:32
#: terminal/backends/command/models.py:21 terminal/models/session/session.py:34
@ -249,7 +249,7 @@ msgstr "アカウントバックアップ計画"
#: accounts/models/automations/backup_account.py:83
#: assets/models/automations/base.py:114 audits/models.py:55
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:186
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:191
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:109
#: terminal/models/session/session.py:45
#: tickets/models/ticket/apply_application.py:30
@ -276,7 +276,7 @@ msgid "Trigger mode"
msgstr "トリガーモード"
#: accounts/models/automations/backup_account.py:97 audits/models.py:172
#: terminal/models/session/sharing.py:107 xpack/plugins/cloud/models.py:176
#: terminal/models/session/sharing.py:107 xpack/plugins/cloud/models.py:168
msgid "Reason"
msgstr "理由"
@ -371,7 +371,7 @@ msgstr "開始日"
#: accounts/models/automations/change_secret.py:74
#: assets/models/automations/base.py:115 ops/models/base.py:56
#: ops/models/celery.py:64 ops/models/job.py:187
#: ops/models/celery.py:64 ops/models/job.py:192
#: terminal/models/applet/host.py:110
msgid "Date finished"
msgstr "終了日"
@ -385,15 +385,15 @@ msgstr "間違い"
msgid "Change secret record"
msgstr "パスワード レコードの変更"
#: accounts/models/automations/gather_account.py:14
#: accounts/models/automations/gather_account.py:12
msgid "Present"
msgstr "存在する"
#: accounts/models/automations/gather_account.py:15
#: accounts/models/automations/gather_account.py:13
msgid "Date last login"
msgstr "最終ログイン日"
#: accounts/models/automations/gather_account.py:17
#: accounts/models/automations/gather_account.py:15
#: accounts/models/automations/push_account.py:13 accounts/models/base.py:34
#: acls/serializers/base.py:18 acls/serializers/base.py:49
#: assets/models/_user.py:23 audits/models.py:157 authentication/forms.py:25
@ -406,15 +406,15 @@ msgstr "最終ログイン日"
msgid "Username"
msgstr "ユーザー名"
#: accounts/models/automations/gather_account.py:18
#: accounts/models/automations/gather_account.py:16
msgid "Address last login"
msgstr "最終ログインアドレス"
#: accounts/models/automations/gather_account.py:25 rbac/tree.py:50
msgid "Gather account"
msgstr "アカウントを集める"
#: accounts/models/automations/gather_account.py:23
msgid "Gather account automation"
msgstr "自動収集アカウント"
#: accounts/models/automations/gather_account.py:41
#: accounts/models/automations/gather_account.py:39
#: accounts/tasks/gather_accounts.py:29
msgid "Gather asset accounts"
msgstr "アカウントのコレクション"
@ -446,11 +446,11 @@ msgstr "アカウントの確認"
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
#: assets/models/group.py:20 assets/models/label.py:18
#: assets/models/platform.py:21 assets/models/platform.py:76
#: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142
#: assets/serializers/asset/common.py:67 assets/serializers/asset/common.py:143
#: assets/serializers/platform.py:91 assets/serializers/platform.py:136
#: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:90 ops/models/playbook.py:23 ops/serializers/job.py:19
#: ops/models/job.py:91 ops/models/playbook.py:23 ops/serializers/job.py:19
#: orgs/models.py:69 perms/models/asset_permission.py:56 rbac/models/role.py:29
#: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:27 terminal/models/component/endpoint.py:12
@ -516,12 +516,12 @@ msgstr ""
"情報にアクセスしてください-> ファイル暗号化パスワードを設定してください"
#: accounts/serializers/account/account.py:65
#: assets/serializers/asset/common.py:66 settings/serializers/auth/sms.py:75
#: assets/serializers/asset/common.py:65 settings/serializers/auth/sms.py:75
msgid "Template"
msgstr "テンプレート"
#: accounts/serializers/account/account.py:68
#: assets/serializers/asset/common.py:63
#: assets/serializers/asset/common.py:62
msgid "Push now"
msgstr "今すぐプッシュ"
@ -532,9 +532,9 @@ msgstr "エスクローされたパスワード"
#: accounts/serializers/account/account.py:75 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:77
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
#: assets/serializers/asset/common.py:120 assets/serializers/cagegory.py:8
#: assets/serializers/platform.py:97 assets/serializers/platform.py:137
#: perms/serializers/user_permission.py:25 settings/models.py:35
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13
msgid "Category"
msgstr "カテゴリ"
@ -544,10 +544,10 @@ 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:78
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96
#: assets/serializers/asset/common.py:121 assets/serializers/platform.py:96
#: audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:101
#: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:31
#: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:102
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:31
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:22 terminal/serializers/storage.py:224
@ -592,14 +592,14 @@ msgid "Key password"
msgstr "キーパスワード"
#: accounts/serializers/account/base.py:79
#: assets/serializers/asset/common.py:290
#: assets/serializers/asset/common.py:291
msgid "Spec info"
msgstr "特別情報"
#: accounts/serializers/automations/base.py:22
#: assets/models/automations/base.py:19
#: assets/serializers/automations/base.py:20 ops/models/base.py:17
#: ops/models/job.py:103 ops/serializers/job.py:20
#: ops/models/job.py:104 ops/serializers/job.py:20
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
msgid "Assets"
msgstr "資産"
@ -998,7 +998,7 @@ msgid "Device"
msgstr "インターネット機器"
#: assets/const/category.py:13 assets/models/asset/database.py:9
#: assets/models/asset/database.py:24 assets/serializers/asset/common.py:109
#: assets/models/asset/database.py:24 assets/serializers/asset/common.py:108
msgid "Database"
msgstr "データベース"
@ -1041,13 +1041,12 @@ msgstr "Webサイト"
msgid "Disabled"
msgstr "無効"
#: assets/const/web.py:60 settings/serializers/auth/base.py:10
#: settings/serializers/basic.py:27
#: 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/asset/common.py:117 assets/serializers/platform.py:40
#: assets/serializers/asset/common.py:116 assets/serializers/platform.py:40
msgid "Script"
msgstr "脚本"
@ -1065,20 +1064,20 @@ msgstr "SSHパブリックキー"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 assets/models/group.py:23
#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:109
#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:110
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:158
#: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100
#: terminal/models/session/session.py:47 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:756
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:119
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111
msgid "Comment"
msgstr "コメント"
#: assets/models/_user.py:28 assets/models/automations/base.py:113
#: assets/models/cmd_filter.py:41 assets/models/group.py:22
#: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:185
#: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:190
#: users/models/user.py:943
msgid "Date created"
msgstr "作成された日付"
@ -1176,20 +1175,20 @@ msgstr "クラウド サービス"
msgid "Port"
msgstr "ポート"
#: assets/models/asset/common.py:103 assets/serializers/asset/common.py:143
#: assets/models/asset/common.py:103 assets/serializers/asset/common.py:144
msgid "Address"
msgstr "アドレス"
#: assets/models/asset/common.py:104 assets/models/platform.py:112
#: authentication/serializers/connect_token_secret.py:108
#: perms/serializers/user_permission.py:23
#: xpack/plugins/cloud/serializers/account_attrs.py:179
#: perms/serializers/user_permission.py:24
#: xpack/plugins/cloud/serializers/account_attrs.py:187
msgid "Platform"
msgstr "プラットフォーム"
#: assets/models/asset/common.py:106 assets/models/domain.py:21
#: authentication/serializers/connect_token_secret.py:126
#: perms/serializers/user_permission.py:27
#: perms/serializers/user_permission.py:28
msgid "Domain"
msgstr "ドメイン"
@ -1197,23 +1196,23 @@ msgstr "ドメイン"
msgid "Labels"
msgstr "ラベル"
#: assets/models/asset/common.py:282
#: assets/models/asset/common.py:283
msgid "Can refresh asset hardware info"
msgstr "資産ハードウェア情報を更新できます"
#: assets/models/asset/common.py:283
#: assets/models/asset/common.py:284
msgid "Can test asset connectivity"
msgstr "資産接続をテストできます"
#: assets/models/asset/common.py:284
#: assets/models/asset/common.py:285
msgid "Can match asset"
msgstr "アセットを一致させることができます"
#: assets/models/asset/common.py:285
#: assets/models/asset/common.py:286
msgid "Can change asset nodes"
msgstr "資産ノードを変更できます"
#: assets/models/asset/database.py:10 assets/serializers/asset/common.py:110
#: assets/models/asset/database.py:10 assets/serializers/asset/common.py:109
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "SSLの使用"
@ -1230,7 +1229,7 @@ msgstr "クライアント証明書"
msgid "Client key"
msgstr "クライアントキー"
#: assets/models/asset/database.py:14 assets/serializers/asset/common.py:111
#: assets/models/asset/database.py:14 assets/serializers/asset/common.py:110
msgid "Allow invalid cert"
msgstr "証明書チェックを無視"
@ -1238,23 +1237,23 @@ msgstr "証明書チェックを無視"
msgid "Autofill"
msgstr "自動充填"
#: assets/models/asset/web.py:10 assets/serializers/asset/common.py:114
#: assets/models/asset/web.py:10 assets/serializers/asset/common.py:113
#: assets/serializers/platform.py:32
msgid "Username selector"
msgstr "ユーザー名ピッカー"
#: assets/models/asset/web.py:11 assets/serializers/asset/common.py:115
#: assets/models/asset/web.py:11 assets/serializers/asset/common.py:114
#: assets/serializers/platform.py:35
msgid "Password selector"
msgstr "パスワードセレクター"
#: assets/models/asset/web.py:12 assets/serializers/asset/common.py:116
#: assets/models/asset/web.py:12 assets/serializers/asset/common.py:115
#: assets/serializers/platform.py:38
msgid "Submit selector"
msgstr "ボタンセレクターを確認する"
#: assets/models/automations/base.py:17 assets/models/cmd_filter.py:38
#: assets/serializers/asset/common.py:289 rbac/tree.py:36
#: assets/serializers/asset/common.py:290 rbac/tree.py:35
msgid "Accounts"
msgstr "アカウント"
@ -1267,13 +1266,13 @@ msgid "Asset automation task"
msgstr "アセットの自動化タスク"
#: assets/models/automations/base.py:112 audits/models.py:177
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:178
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:183
#: terminal/models/applet/applet.py:157 terminal/models/applet/host.py:108
#: terminal/models/component/status.py:27 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:172
#: xpack/plugins/cloud/models.py:224
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164
#: xpack/plugins/cloud/models.py:216
msgid "Status"
msgstr "ステータス"
@ -1356,7 +1355,7 @@ msgstr "システム"
msgid "Value"
msgstr "値"
#: assets/models/label.py:40 assets/serializers/asset/common.py:123
#: assets/models/label.py:40 assets/serializers/asset/common.py:122
#: assets/serializers/cagegory.py:6 assets/serializers/cagegory.py:13
#: authentication/serializers/connect_token_secret.py:114
#: common/serializers/common.py:79 settings/serializers/sms.py:7
@ -1396,7 +1395,7 @@ msgstr "ノードを一致させることができます"
msgid "Required"
msgstr "必要"
#: assets/models/platform.py:23 settings/serializers/settings.py:61
#: assets/models/platform.py:23 settings/serializers/settings.py:65
#: users/templates/users/reset_password.html:29
msgid "Setting"
msgstr "設定"
@ -1485,41 +1484,43 @@ msgstr "オートメーション"
msgid "%(value)s is not an even number"
msgstr "%(value)s は偶数ではありません"
#: assets/serializers/asset/common.py:113
#: assets/serializers/asset/common.py:112
msgid "Auto fill"
msgstr "自動充填"
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:99
#: assets/serializers/asset/common.py:123 assets/serializers/platform.py:99
#: authentication/serializers/connect_token_secret.py:28
#: authentication/serializers/connect_token_secret.py:66
#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:107
#: xpack/plugins/cloud/serializers/task.py:38
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99
msgid "Protocols"
msgstr "プロトコル"
#: assets/serializers/asset/common.py:144
#: assets/serializers/asset/common.py:142
#: assets/serializers/asset/common.py:292
msgid "Auto info"
msgstr "自動情報"
#: assets/serializers/asset/common.py:145
msgid "Node path"
msgstr "ノードパスです"
#: assets/serializers/asset/common.py:217
#: assets/serializers/asset/common.py:218
msgid "Platform not exist"
msgstr "プラットフォームが存在しません"
#: assets/serializers/asset/common.py:252
#: assets/serializers/asset/common.py:253
msgid "port out of range (1-65535)"
msgstr "ポート番号が範囲外です (1-65535)"
#: assets/serializers/asset/common.py:259
#: assets/serializers/asset/common.py:260
msgid "Protocol is required: {}"
msgstr "プロトコルが必要です: {}"
#: assets/serializers/asset/common.py:291
msgid "Auto info"
msgstr "自動情報"
#: assets/serializers/asset/database.py:25 common/serializers/fields.py:100
#: tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
#: xpack/plugins/cloud/serializers/account_attrs.py:143
msgid "This field is required."
msgstr "このフィールドは必須です。"
@ -1572,6 +1573,10 @@ msgstr "システムバージョン"
msgid "OS arch"
msgstr "システムアーキテクチャ"
#: assets/serializers/asset/host.py:28
msgid "Info"
msgstr "情報"
#: assets/serializers/cagegory.py:9
msgid "Constraints"
msgstr "制約"
@ -1823,11 +1828,12 @@ msgstr "ファイル名"
msgid "File transfer log"
msgstr "ファイル転送ログ"
#: audits/models.py:67
#: audits/models.py:67 audits/serializers.py:84
msgid "Resource Type"
msgstr "リソースタイプ"
#: audits/models.py:68 audits/models.py:71 audits/models.py:117
#: audits/serializers.py:83
msgid "Resource"
msgstr "リソース"
@ -1901,7 +1907,7 @@ msgstr "ユーザーログインログ"
msgid "Reason display"
msgstr "理由表示"
#: audits/serializers.py:122
#: audits/serializers.py:132
#, python-format
msgid "User %s %s this resource"
msgstr "ユーザー %s %s が現在のリソースをサブスクライブしました。"
@ -2012,11 +2018,6 @@ msgid "Forgot password"
msgstr "パスワードを忘れた"
#: authentication/apps.py:7 settings/serializers/auth/base.py:10
#: settings/serializers/auth/cas.py:10 settings/serializers/auth/dingtalk.py:10
#: settings/serializers/auth/feishu.py:10 settings/serializers/auth/ldap.py:39
#: settings/serializers/auth/oauth2.py:18 settings/serializers/auth/oidc.py:12
#: settings/serializers/auth/radius.py:13 settings/serializers/auth/saml2.py:11
#: settings/serializers/auth/sso.py:10 settings/serializers/auth/wecom.py:10
msgid "Authentication"
msgstr "認証"
@ -3126,15 +3127,15 @@ msgstr "特殊文字を含むべきではない"
msgid "The mobile phone number format is incorrect"
msgstr "携帯電話番号の形式が正しくありません"
#: common/views/mixins.py:57
#: common/views/mixins.py:58
msgid "Export all"
msgstr "すべてエクスポート"
#: common/views/mixins.py:59
#: common/views/mixins.py:60
msgid "Export only selected items"
msgstr "選択項目のみエクスポート"
#: common/views/mixins.py:64
#: common/views/mixins.py:65
#, python-format
msgid "Export filtered: %s"
msgstr "検索のエクスポート: %s"
@ -3239,7 +3240,7 @@ msgstr "タスク実行パラメータエラー"
msgid "Unsupported file content"
msgstr "サポートされていないファイルの内容"
#: ops/apps.py:9 ops/notifications.py:16 rbac/tree.py:56
#: ops/apps.py:9 ops/notifications.py:16 rbac/tree.py:55
msgid "App ops"
msgstr "アプリ操作"
@ -3279,7 +3280,7 @@ msgstr "VCS"
msgid "Adhoc"
msgstr "コマンド#コマンド#"
#: ops/const.py:39 ops/models/job.py:99
#: ops/const.py:39 ops/models/job.py:100
msgid "Playbook"
msgstr "Playbook"
@ -3340,17 +3341,17 @@ msgstr "定期的または定期的に設定を行う必要があります"
msgid "Pattern"
msgstr "パターン"
#: ops/models/adhoc.py:24 ops/models/job.py:94
#: ops/models/adhoc.py:24 ops/models/job.py:95
msgid "Module"
msgstr "モジュール"
#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:93
#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:94
#: terminal/models/component/task.py:16
msgid "Args"
msgstr "アルグ"
#: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53
#: ops/models/job.py:102 ops/models/job.py:184 ops/models/playbook.py:25
#: ops/models/job.py:103 ops/models/job.py:189 ops/models/playbook.py:25
#: terminal/models/session/sharing.py:23
msgid "Creator"
msgstr "作成者"
@ -3367,12 +3368,12 @@ msgstr "最後の実行"
msgid "Date last run"
msgstr "最終実行日"
#: ops/models/base.py:51 ops/models/job.py:182
#: xpack/plugins/cloud/models.py:170
#: ops/models/base.py:51 ops/models/job.py:187
#: xpack/plugins/cloud/models.py:162
msgid "Result"
msgstr "結果"
#: ops/models/base.py:52 ops/models/job.py:183
#: ops/models/base.py:52 ops/models/job.py:188
msgid "Summary"
msgstr "概要"
@ -3412,47 +3413,47 @@ msgstr "発売日"
msgid "Celery Task Execution"
msgstr "Celery タスク実行"
#: ops/models/job.py:96
#: ops/models/job.py:97
msgid "Chdir"
msgstr "実行ディレクトリ"
#: ops/models/job.py:97
#: ops/models/job.py:98
msgid "Timeout (Seconds)"
msgstr "タイムアウト(秒)"
#: ops/models/job.py:104
#: ops/models/job.py:105
msgid "Use Parameter Define"
msgstr "パラメータ定義を使用する"
#: ops/models/job.py:105
#: ops/models/job.py:106
msgid "Parameters define"
msgstr "パラメータ定義"
#: ops/models/job.py:106
#: ops/models/job.py:107
msgid "Runas"
msgstr "ユーザーとして実行"
#: ops/models/job.py:108
#: ops/models/job.py:109
msgid "Runas policy"
msgstr "ユーザー ポリシー"
#: ops/models/job.py:170
#: ops/models/job.py:171
msgid "Job"
msgstr "ジョブ#ジョブ#"
#: ops/models/job.py:181
#: ops/models/job.py:186
msgid "Parameters"
msgstr "パラメータ"
#: ops/models/job.py:189
#: ops/models/job.py:194
msgid "Material"
msgstr ""
#: ops/models/job.py:191
#: ops/models/job.py:196
msgid "Material Type"
msgstr ""
#: ops/models/job.py:442
#: ops/models/job.py:455
msgid "Job Execution"
msgstr "ジョブ実行"
@ -3528,6 +3529,10 @@ msgstr "定期的なタスクの作成または更新"
msgid "Periodic check service performance"
msgstr "サービスのパフォーマンスを定期的に確認する"
#: ops/tasks.py:114
msgid "Clean up unexpected jobs"
msgstr "例外ジョブのクリーンアップ"
#: ops/templates/ops/celery_task_log.html:4
msgid "Task log"
msgstr "タスクログ"
@ -3855,59 +3860,63 @@ msgstr "ロール表示"
msgid "Has bound this role"
msgstr "この役割をバインドしました"
#: rbac/tree.py:18 rbac/tree.py:19
#: rbac/tree.py:17 rbac/tree.py:18
msgid "All permissions"
msgstr "すべての権限"
#: rbac/tree.py:25
#: rbac/tree.py:24
msgid "Console view"
msgstr "コンソールビュー"
#: rbac/tree.py:26
#: rbac/tree.py:25
msgid "Workbench view"
msgstr "ワークスペースビュー"
#: rbac/tree.py:27
#: rbac/tree.py:26
msgid "Audit view"
msgstr "監査ビュー"
#: rbac/tree.py:28 settings/models.py:159
#: rbac/tree.py:27 settings/models.py:159
msgid "System setting"
msgstr "システム設定"
#: rbac/tree.py:29
#: rbac/tree.py:28
msgid "Other"
msgstr "その他"
#: rbac/tree.py:38
#: rbac/tree.py:37
msgid "Session audits"
msgstr "セッション監査"
#: rbac/tree.py:48
#: rbac/tree.py:47
msgid "Cloud import"
msgstr "クラウドインポート"
#: rbac/tree.py:49
#: rbac/tree.py:48
msgid "Backup account"
msgstr "バックアップアカウント"
#: rbac/tree.py:52
#: rbac/tree.py:49
msgid "Gather account"
msgstr "アカウントを集める"
#: rbac/tree.py:51
msgid "Asset change auth"
msgstr "資産の改ざん"
#: rbac/tree.py:53
#: rbac/tree.py:52
msgid "Terminal setting"
msgstr "ターミナル設定"
#: rbac/tree.py:54
#: rbac/tree.py:53
msgid "Task Center"
msgstr "タスクセンター"
#: rbac/tree.py:55
#: rbac/tree.py:54
msgid "My assets"
msgstr "私の資産"
#: rbac/tree.py:57 terminal/models/applet/applet.py:43
#: rbac/tree.py:56 terminal/models/applet/applet.py:43
#: terminal/models/applet/applet.py:154 terminal/models/applet/host.py:28
#: terminal/serializers/applet.py:15
msgid "Applet"
@ -4408,7 +4417,7 @@ msgid "SSO auth key TTL"
msgstr "Token有効期間"
#: settings/serializers/auth/sso.py:17
#: xpack/plugins/cloud/serializers/account_attrs.py:176
#: xpack/plugins/cloud/serializers/account_attrs.py:184
msgid "Unit: second"
msgstr "単位: 秒"
@ -4930,6 +4939,11 @@ msgstr ""
"します。アカウントが共通のログイン都市からログインしている場合、システムはリ"
"モートログインリマインダーを送信します"
#: settings/serializers/settings.py:69
#, python-format
msgid "[%s] %s"
msgstr ""
#: settings/serializers/terminal.py:9
msgid "Hostname"
msgstr "ホスト名"
@ -5821,7 +5835,7 @@ msgstr "アクセスキー"
msgid "Access key secret"
msgstr "アクセスキーシークレット"
#: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:217
#: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:209
msgid "Region"
msgstr "リージョン"
@ -5987,19 +6001,19 @@ msgstr ""
"チケットのタイトル: {} チケット申請者: {} チケットプロセッサ: {} チケットID: "
"{}"
#: tickets/handlers/base.py:86
#: tickets/handlers/base.py:85
msgid "Change field"
msgstr "フィールドを変更"
#: tickets/handlers/base.py:86
#: tickets/handlers/base.py:85
msgid "Before change"
msgstr "変更前"
#: tickets/handlers/base.py:86
#: tickets/handlers/base.py:85
msgid "After change"
msgstr "変更後"
#: tickets/handlers/base.py:98
#: tickets/handlers/base.py:97
msgid "{} {} the ticket"
msgstr "{} {} チケット"
@ -6255,7 +6269,7 @@ msgstr "無効な承認アクション"
msgid "This user is not authorized to approve this ticket"
msgstr "このユーザーはこの作業指示を承認する権限がありません"
#: users/api/user.py:179
#: users/api/user.py:182
msgid "Could not reset self otp, use profile reset instead"
msgstr "自己otpをリセットできませんでした、代わりにプロファイルリセットを使用"
@ -6952,59 +6966,47 @@ msgstr "リージョン"
msgid "Hostname strategy"
msgstr "ホスト名戦略"
#: xpack/plugins/cloud/models.py:100
#, fuzzy
#| msgid "Only admin users"
msgid "Unix admin user"
msgstr "管理者のみ"
#: xpack/plugins/cloud/models.py:104
#, fuzzy
#| msgid "Only admin users"
msgid "Windows admin user"
msgstr "管理者のみ"
#: xpack/plugins/cloud/models.py:110 xpack/plugins/cloud/serializers/task.py:41
#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:40
msgid "IP network segment group"
msgstr "IPネットワークセグメントグループ"
#: xpack/plugins/cloud/models.py:113 xpack/plugins/cloud/serializers/task.py:46
#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:45
msgid "Sync IP type"
msgstr "同期IPタイプ"
#: xpack/plugins/cloud/models.py:116 xpack/plugins/cloud/serializers/task.py:64
#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:62
msgid "Always update"
msgstr "常に更新"
#: xpack/plugins/cloud/models.py:122
#: xpack/plugins/cloud/models.py:114
msgid "Date last sync"
msgstr "最終同期日"
#: xpack/plugins/cloud/models.py:127 xpack/plugins/cloud/models.py:168
#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160
msgid "Sync instance task"
msgstr "インスタンスの同期タスク"
#: xpack/plugins/cloud/models.py:179 xpack/plugins/cloud/models.py:227
#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219
msgid "Date sync"
msgstr "日付の同期"
#: xpack/plugins/cloud/models.py:183
#: xpack/plugins/cloud/models.py:175
msgid "Sync instance task execution"
msgstr "インスタンスタスクの同期実行"
#: xpack/plugins/cloud/models.py:207
#: xpack/plugins/cloud/models.py:199
msgid "Sync task"
msgstr "同期タスク"
#: xpack/plugins/cloud/models.py:211
#: xpack/plugins/cloud/models.py:203
msgid "Sync instance task history"
msgstr "インスタンスタスク履歴の同期"
#: xpack/plugins/cloud/models.py:214
#: xpack/plugins/cloud/models.py:206
msgid "Instance"
msgstr "インスタンス"
#: xpack/plugins/cloud/models.py:231
#: xpack/plugins/cloud/models.py:223
msgid "Sync instance detail"
msgstr "同期インスタンスの詳細"
@ -7218,52 +7220,52 @@ msgstr "テナントID"
msgid "Subscription ID"
msgstr "サブスクリプションID"
#: xpack/plugins/cloud/serializers/account_attrs.py:95
#: xpack/plugins/cloud/serializers/account_attrs.py:100
#: xpack/plugins/cloud/serializers/account_attrs.py:116
#: xpack/plugins/cloud/serializers/account_attrs.py:141
#: xpack/plugins/cloud/serializers/account_attrs.py:98
#: xpack/plugins/cloud/serializers/account_attrs.py:103
#: xpack/plugins/cloud/serializers/account_attrs.py:119
#: xpack/plugins/cloud/serializers/account_attrs.py:149
msgid "API Endpoint"
msgstr "APIエンドポイント"
#: xpack/plugins/cloud/serializers/account_attrs.py:106
#: xpack/plugins/cloud/serializers/account_attrs.py:109
msgid "Auth url"
msgstr "認証アドレス"
#: xpack/plugins/cloud/serializers/account_attrs.py:107
#: xpack/plugins/cloud/serializers/account_attrs.py:110
msgid "eg: http://openstack.example.com:5000/v3"
msgstr "例えば: http://openstack.example.com:5000/v3"
#: xpack/plugins/cloud/serializers/account_attrs.py:110
#: xpack/plugins/cloud/serializers/account_attrs.py:113
msgid "User domain"
msgstr "ユーザードメイン"
#: xpack/plugins/cloud/serializers/account_attrs.py:117
#: xpack/plugins/cloud/serializers/account_attrs.py:120
msgid "Cert File"
msgstr "証明書ファイル"
#: xpack/plugins/cloud/serializers/account_attrs.py:118
#: xpack/plugins/cloud/serializers/account_attrs.py:121
msgid "Key File"
msgstr "キーファイル"
#: xpack/plugins/cloud/serializers/account_attrs.py:134
#: xpack/plugins/cloud/serializers/account_attrs.py:137
msgid "Service account key"
msgstr "サービスアカウントキー"
#: xpack/plugins/cloud/serializers/account_attrs.py:135
#: xpack/plugins/cloud/serializers/account_attrs.py:138
msgid "The file is in JSON format"
msgstr "ファイルはJSON形式です。"
#: xpack/plugins/cloud/serializers/account_attrs.py:148
#: xpack/plugins/cloud/serializers/account_attrs.py:156
msgid "IP address invalid `{}`, {}"
msgstr "IPアドレスが無効: '{}', {}"
#: xpack/plugins/cloud/serializers/account_attrs.py:154
#: xpack/plugins/cloud/serializers/account_attrs.py:162
msgid ""
"Format for comma-delimited string,Such as: 192.168.1.0/24, "
"10.0.0.0-10.0.0.255"
msgstr "形式はコンマ区切りの文字列です192.168.1.0/24,10.0.0.0-10.0.0.255"
#: xpack/plugins/cloud/serializers/account_attrs.py:158
#: xpack/plugins/cloud/serializers/account_attrs.py:166
msgid ""
"The port is used to detect the validity of the IP address. When the "
"synchronization task is executed, only the valid IP address will be "
@ -7273,19 +7275,19 @@ msgstr ""
"実行されると、有効な IP アドレスのみが同期されます。 <br>ポートが0の場合、す"
"べてのIPアドレスが有効です。"
#: xpack/plugins/cloud/serializers/account_attrs.py:166
#: xpack/plugins/cloud/serializers/account_attrs.py:174
msgid "Hostname prefix"
msgstr "ホスト名プレフィックス"
#: xpack/plugins/cloud/serializers/account_attrs.py:169
#: xpack/plugins/cloud/serializers/account_attrs.py:177
msgid "IP segment"
msgstr "IP セグメント"
#: xpack/plugins/cloud/serializers/account_attrs.py:173
#: xpack/plugins/cloud/serializers/account_attrs.py:181
msgid "Test port"
msgstr "テストポート"
#: xpack/plugins/cloud/serializers/account_attrs.py:176
#: xpack/plugins/cloud/serializers/account_attrs.py:184
msgid "Test timeout"
msgstr "テストタイムアウト"
@ -7311,11 +7313,13 @@ msgstr "実行回数"
msgid "Instance count"
msgstr "インスタンス数"
#: xpack/plugins/cloud/serializers/task.py:63
#, fuzzy
#| msgid "Only admin users"
msgid "Linux admin user"
msgstr "管理者のみ"
#: xpack/plugins/cloud/tasks.py:27
msgid "Run sync instance task"
msgstr "同期インスタンス タスクを実行する"
#: xpack/plugins/cloud/tasks.py:41
msgid "Period clean sync instance task execution"
msgstr "同期インスタンス タスクの実行記録を定期的にクリアする"
#: xpack/plugins/cloud/utils.py:69
msgid "Account unavailable"
@ -7329,31 +7333,31 @@ msgstr "デフォルトの復元に成功しました。"
msgid "Interface settings"
msgstr "インターフェイスの設定"
#: xpack/plugins/interface/models.py:22
#: xpack/plugins/interface/models.py:23
msgid "Title of login page"
msgstr "ログインページのタイトル"
#: xpack/plugins/interface/models.py:26
#: xpack/plugins/interface/models.py:27
msgid "Image of login page"
msgstr "ログインページのイメージ"
#: xpack/plugins/interface/models.py:30
#: xpack/plugins/interface/models.py:31
msgid "Website icon"
msgstr "ウェブサイトのアイコン"
#: xpack/plugins/interface/models.py:34
#: xpack/plugins/interface/models.py:35
msgid "Logo of management page"
msgstr "管理ページのロゴ"
#: xpack/plugins/interface/models.py:38
#: xpack/plugins/interface/models.py:39
msgid "Logo of logout page"
msgstr "ログアウトページのロゴ"
#: xpack/plugins/interface/models.py:40
#: xpack/plugins/interface/models.py:41
msgid "Theme"
msgstr "テーマ"
#: xpack/plugins/interface/models.py:43 xpack/plugins/interface/models.py:84
#: xpack/plugins/interface/models.py:44 xpack/plugins/interface/models.py:85
msgid "Interface setting"
msgstr "インターフェイスの設定"
@ -7385,11 +7389,20 @@ msgstr "究極のエディション"
msgid "Community edition"
msgstr "コミュニティ版"
#~ msgid "Run sync instance task"
#~ msgstr "同期インスタンス タスクを実行する"
#, fuzzy
#~| msgid "Only admin users"
#~ msgid "Unix admin user"
#~ msgstr "管理者のみ"
#~ msgid "Period clean sync instance task execution"
#~ msgstr "同期インスタンス タスクの実行記録を定期的にクリアする"
#, fuzzy
#~| msgid "Only admin users"
#~ msgid "Windows admin user"
#~ msgstr "管理者のみ"
#, fuzzy
#~| msgid "Only admin users"
#~ msgid "Linux admin user"
#~ msgstr "管理者のみ"
#~ msgid "Can push account to asset"
#~ msgstr "アカウントをアセットにプッシュできます"

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e68b83ab7aac5be2b88ed9c64a626b41ebfc035ed733a206e2c0d69fcf21337b
size 111773
oid sha256:a29193d2982b254444285cfb2d61f7ef7355ae2bab181cdf366446e879ab32fb
size 111963

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-02-22 21:23+0800\n"
"POT-Creation-Date: 2023-02-23 19:11+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"
@ -69,7 +69,7 @@ msgstr "数据库"
msgid "Collected"
msgstr "收集"
#: accounts/const/automation.py:22 rbac/tree.py:51
#: accounts/const/automation.py:22 rbac/tree.py:50
msgid "Push account"
msgstr "账号推送"
@ -158,20 +158,20 @@ msgid "Only create"
msgstr "仅创建"
#: accounts/models/account.py:47
#: accounts/models/automations/gather_account.py:16
#: accounts/models/automations/gather_account.py:14
#: accounts/serializers/account/account.py:95
#: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:111
#: accounts/serializers/automations/change_secret.py:131
#: acls/models/base.py:100 acls/serializers/base.py:56
#: assets/models/asset/common.py:92 assets/models/asset/common.py:279
#: assets/models/asset/common.py:92 assets/models/asset/common.py:280
#: assets/models/cmd_filter.py:36 assets/serializers/domain.py:19
#: assets/serializers/label.py:27 audits/models.py:48
#: authentication/models/connection_token.py:33
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:27
#: terminal/backends/command/models.py:20 terminal/models/session/session.py:32
#: terminal/notifications.py:95 terminal/serializers/command.py:17
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:220
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "资产"
@ -194,7 +194,7 @@ msgstr "来源"
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
#: acls/models/base.py:102 acls/serializers/base.py:57
#: assets/serializers/asset/common.py:125 assets/serializers/gateway.py:28
#: assets/serializers/asset/common.py:124 assets/serializers/gateway.py:28
#: audits/models.py:49 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:32
#: terminal/backends/command/models.py:21 terminal/models/session/session.py:34
@ -248,7 +248,7 @@ msgstr "账号备份计划"
#: accounts/models/automations/backup_account.py:83
#: assets/models/automations/base.py:114 audits/models.py:55
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:186
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:191
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:109
#: terminal/models/session/session.py:45
#: tickets/models/ticket/apply_application.py:30
@ -275,7 +275,7 @@ msgid "Trigger mode"
msgstr "触发模式"
#: accounts/models/automations/backup_account.py:97 audits/models.py:172
#: terminal/models/session/sharing.py:107 xpack/plugins/cloud/models.py:176
#: terminal/models/session/sharing.py:107 xpack/plugins/cloud/models.py:168
msgid "Reason"
msgstr "原因"
@ -370,7 +370,7 @@ msgstr "开始日期"
#: accounts/models/automations/change_secret.py:74
#: assets/models/automations/base.py:115 ops/models/base.py:56
#: ops/models/celery.py:64 ops/models/job.py:187
#: ops/models/celery.py:64 ops/models/job.py:192
#: terminal/models/applet/host.py:110
msgid "Date finished"
msgstr "结束日期"
@ -384,15 +384,15 @@ msgstr "错误"
msgid "Change secret record"
msgstr "改密记录"
#: accounts/models/automations/gather_account.py:14
#: accounts/models/automations/gather_account.py:12
msgid "Present"
msgstr "存在"
#: accounts/models/automations/gather_account.py:15
#: accounts/models/automations/gather_account.py:13
msgid "Date last login"
msgstr "最后登录日期"
#: accounts/models/automations/gather_account.py:17
#: accounts/models/automations/gather_account.py:15
#: accounts/models/automations/push_account.py:13 accounts/models/base.py:34
#: acls/serializers/base.py:18 acls/serializers/base.py:49
#: assets/models/_user.py:23 audits/models.py:157 authentication/forms.py:25
@ -405,15 +405,15 @@ msgstr "最后登录日期"
msgid "Username"
msgstr "用户名"
#: accounts/models/automations/gather_account.py:18
#: accounts/models/automations/gather_account.py:16
msgid "Address last login"
msgstr "最后登录地址"
#: accounts/models/automations/gather_account.py:25 rbac/tree.py:50
msgid "Gather account"
msgstr "收集账号"
#: accounts/models/automations/gather_account.py:23
msgid "Gather account automation"
msgstr "自动化收集账号"
#: accounts/models/automations/gather_account.py:41
#: accounts/models/automations/gather_account.py:39
#: accounts/tasks/gather_accounts.py:29
msgid "Gather asset accounts"
msgstr "收集账号"
@ -445,11 +445,11 @@ msgstr "账号验证"
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
#: assets/models/group.py:20 assets/models/label.py:18
#: assets/models/platform.py:21 assets/models/platform.py:76
#: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142
#: assets/serializers/asset/common.py:67 assets/serializers/asset/common.py:143
#: assets/serializers/platform.py:91 assets/serializers/platform.py:136
#: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:90 ops/models/playbook.py:23 ops/serializers/job.py:19
#: ops/models/job.py:91 ops/models/playbook.py:23 ops/serializers/job.py:19
#: orgs/models.py:69 perms/models/asset_permission.py:56 rbac/models/role.py:29
#: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:27 terminal/models/component/endpoint.py:12
@ -512,12 +512,12 @@ msgstr ""
"密密码"
#: accounts/serializers/account/account.py:65
#: assets/serializers/asset/common.py:66 settings/serializers/auth/sms.py:75
#: assets/serializers/asset/common.py:65 settings/serializers/auth/sms.py:75
msgid "Template"
msgstr "模板"
#: accounts/serializers/account/account.py:68
#: assets/serializers/asset/common.py:63
#: assets/serializers/asset/common.py:62
msgid "Push now"
msgstr "立即推送"
@ -528,9 +528,9 @@ msgstr "已托管密码"
#: accounts/serializers/account/account.py:75 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:77
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
#: assets/serializers/asset/common.py:120 assets/serializers/cagegory.py:8
#: assets/serializers/platform.py:97 assets/serializers/platform.py:137
#: perms/serializers/user_permission.py:25 settings/models.py:35
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13
msgid "Category"
msgstr "类别"
@ -540,10 +540,10 @@ 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:78
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96
#: assets/serializers/asset/common.py:121 assets/serializers/platform.py:96
#: audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:101
#: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:31
#: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:102
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:31
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:22 terminal/serializers/storage.py:224
@ -588,14 +588,14 @@ msgid "Key password"
msgstr "密钥密码"
#: accounts/serializers/account/base.py:79
#: assets/serializers/asset/common.py:290
#: assets/serializers/asset/common.py:291
msgid "Spec info"
msgstr "特殊信息"
#: accounts/serializers/automations/base.py:22
#: assets/models/automations/base.py:19
#: assets/serializers/automations/base.py:20 ops/models/base.py:17
#: ops/models/job.py:103 ops/serializers/job.py:20
#: ops/models/job.py:104 ops/serializers/job.py:20
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
msgid "Assets"
msgstr "资产"
@ -990,7 +990,7 @@ msgid "Device"
msgstr "网络设备"
#: assets/const/category.py:13 assets/models/asset/database.py:9
#: assets/models/asset/database.py:24 assets/serializers/asset/common.py:109
#: assets/models/asset/database.py:24 assets/serializers/asset/common.py:108
msgid "Database"
msgstr "数据库"
@ -1033,13 +1033,12 @@ msgstr "网站"
msgid "Disabled"
msgstr "禁用"
#: assets/const/web.py:60 settings/serializers/auth/base.py:10
#: settings/serializers/basic.py:27
#: 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/asset/common.py:117 assets/serializers/platform.py:40
#: assets/serializers/asset/common.py:116 assets/serializers/platform.py:40
msgid "Script"
msgstr "脚本"
@ -1057,20 +1056,20 @@ msgstr "SSH公钥"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 assets/models/group.py:23
#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:109
#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:110
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:158
#: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100
#: terminal/models/session/session.py:47 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:756
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:119
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111
msgid "Comment"
msgstr "备注"
#: assets/models/_user.py:28 assets/models/automations/base.py:113
#: assets/models/cmd_filter.py:41 assets/models/group.py:22
#: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:185
#: common/db/models.py:35 ops/models/base.py:54 ops/models/job.py:190
#: users/models/user.py:943
msgid "Date created"
msgstr "创建日期"
@ -1168,20 +1167,20 @@ msgstr "云服务"
msgid "Port"
msgstr "端口"
#: assets/models/asset/common.py:103 assets/serializers/asset/common.py:143
#: assets/models/asset/common.py:103 assets/serializers/asset/common.py:144
msgid "Address"
msgstr "地址"
#: assets/models/asset/common.py:104 assets/models/platform.py:112
#: authentication/serializers/connect_token_secret.py:108
#: perms/serializers/user_permission.py:23
#: xpack/plugins/cloud/serializers/account_attrs.py:179
#: perms/serializers/user_permission.py:24
#: xpack/plugins/cloud/serializers/account_attrs.py:187
msgid "Platform"
msgstr "系统平台"
#: assets/models/asset/common.py:106 assets/models/domain.py:21
#: authentication/serializers/connect_token_secret.py:126
#: perms/serializers/user_permission.py:27
#: perms/serializers/user_permission.py:28
msgid "Domain"
msgstr "网域"
@ -1189,23 +1188,23 @@ msgstr "网域"
msgid "Labels"
msgstr "标签管理"
#: assets/models/asset/common.py:282
#: assets/models/asset/common.py:283
msgid "Can refresh asset hardware info"
msgstr "可以更新资产硬件信息"
#: assets/models/asset/common.py:283
#: assets/models/asset/common.py:284
msgid "Can test asset connectivity"
msgstr "可以测试资产连接性"
#: assets/models/asset/common.py:284
#: assets/models/asset/common.py:285
msgid "Can match asset"
msgstr "可以匹配资产"
#: assets/models/asset/common.py:285
#: assets/models/asset/common.py:286
msgid "Can change asset nodes"
msgstr "可以修改资产节点"
#: assets/models/asset/database.py:10 assets/serializers/asset/common.py:110
#: assets/models/asset/database.py:10 assets/serializers/asset/common.py:109
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "使用 SSL"
@ -1222,7 +1221,7 @@ msgstr "客户端证书"
msgid "Client key"
msgstr "客户端密钥"
#: assets/models/asset/database.py:14 assets/serializers/asset/common.py:111
#: assets/models/asset/database.py:14 assets/serializers/asset/common.py:110
msgid "Allow invalid cert"
msgstr "忽略证书校验"
@ -1230,23 +1229,23 @@ msgstr "忽略证书校验"
msgid "Autofill"
msgstr "自动代填"
#: assets/models/asset/web.py:10 assets/serializers/asset/common.py:114
#: assets/models/asset/web.py:10 assets/serializers/asset/common.py:113
#: assets/serializers/platform.py:32
msgid "Username selector"
msgstr "用户名选择器"
#: assets/models/asset/web.py:11 assets/serializers/asset/common.py:115
#: assets/models/asset/web.py:11 assets/serializers/asset/common.py:114
#: assets/serializers/platform.py:35
msgid "Password selector"
msgstr "密码选择器"
#: assets/models/asset/web.py:12 assets/serializers/asset/common.py:116
#: assets/models/asset/web.py:12 assets/serializers/asset/common.py:115
#: assets/serializers/platform.py:38
msgid "Submit selector"
msgstr "确认按钮选择器"
#: assets/models/automations/base.py:17 assets/models/cmd_filter.py:38
#: assets/serializers/asset/common.py:289 rbac/tree.py:36
#: assets/serializers/asset/common.py:290 rbac/tree.py:35
msgid "Accounts"
msgstr "账号管理"
@ -1259,13 +1258,13 @@ msgid "Asset automation task"
msgstr "资产自动化任务"
#: assets/models/automations/base.py:112 audits/models.py:177
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:178
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:183
#: terminal/models/applet/applet.py:157 terminal/models/applet/host.py:108
#: terminal/models/component/status.py:27 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:172
#: xpack/plugins/cloud/models.py:224
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164
#: xpack/plugins/cloud/models.py:216
msgid "Status"
msgstr "状态"
@ -1348,7 +1347,7 @@ msgstr "系统"
msgid "Value"
msgstr "值"
#: assets/models/label.py:40 assets/serializers/asset/common.py:123
#: assets/models/label.py:40 assets/serializers/asset/common.py:122
#: assets/serializers/cagegory.py:6 assets/serializers/cagegory.py:13
#: authentication/serializers/connect_token_secret.py:114
#: common/serializers/common.py:79 settings/serializers/sms.py:7
@ -1388,7 +1387,7 @@ msgstr "可以匹配节点"
msgid "Required"
msgstr "必须的"
#: assets/models/platform.py:23 settings/serializers/settings.py:61
#: assets/models/platform.py:23 settings/serializers/settings.py:65
#: users/templates/users/reset_password.html:29
msgid "Setting"
msgstr "设置"
@ -1477,41 +1476,43 @@ msgstr "自动化"
msgid "%(value)s is not an even number"
msgstr "%(value)s is not an even number"
#: assets/serializers/asset/common.py:113
#: assets/serializers/asset/common.py:112
msgid "Auto fill"
msgstr "自动代填"
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:99
#: assets/serializers/asset/common.py:123 assets/serializers/platform.py:99
#: authentication/serializers/connect_token_secret.py:28
#: authentication/serializers/connect_token_secret.py:66
#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:107
#: xpack/plugins/cloud/serializers/task.py:38
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99
msgid "Protocols"
msgstr "协议组"
#: assets/serializers/asset/common.py:144
#: assets/serializers/asset/common.py:142
#: assets/serializers/asset/common.py:292
msgid "Auto info"
msgstr "自动化信息"
#: assets/serializers/asset/common.py:145
msgid "Node path"
msgstr "节点路径"
#: assets/serializers/asset/common.py:217
#: assets/serializers/asset/common.py:218
msgid "Platform not exist"
msgstr "平台不存在"
#: assets/serializers/asset/common.py:252
#: assets/serializers/asset/common.py:253
msgid "port out of range (1-65535)"
msgstr "端口超出范围 (1-65535)"
#: assets/serializers/asset/common.py:259
#: assets/serializers/asset/common.py:260
msgid "Protocol is required: {}"
msgstr "协议是必填的: {}"
#: assets/serializers/asset/common.py:291
msgid "Auto info"
msgstr "自动化信息"
#: assets/serializers/asset/database.py:25 common/serializers/fields.py:100
#: tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
#: xpack/plugins/cloud/serializers/account_attrs.py:143
msgid "This field is required."
msgstr "该字段是必填项。"
@ -1564,6 +1565,10 @@ msgstr "系统版本"
msgid "OS arch"
msgstr "系统架构"
#: assets/serializers/asset/host.py:28
msgid "Info"
msgstr "信息"
#: assets/serializers/cagegory.py:9
msgid "Constraints"
msgstr "约束"
@ -1813,11 +1818,12 @@ msgstr "文件名"
msgid "File transfer log"
msgstr "文件管理"
#: audits/models.py:67
#: audits/models.py:67 audits/serializers.py:84
msgid "Resource Type"
msgstr "资源类型"
#: audits/models.py:68 audits/models.py:71 audits/models.py:117
#: audits/serializers.py:83
msgid "Resource"
msgstr "资源"
@ -1891,7 +1897,7 @@ msgstr "用户登录日志"
msgid "Reason display"
msgstr "原因描述"
#: audits/serializers.py:122
#: audits/serializers.py:132
#, python-format
msgid "User %s %s this resource"
msgstr "用户 %s %s 了当前资源"
@ -2000,11 +2006,6 @@ msgid "Forgot password"
msgstr "忘记密码"
#: authentication/apps.py:7 settings/serializers/auth/base.py:10
#: settings/serializers/auth/cas.py:10 settings/serializers/auth/dingtalk.py:10
#: settings/serializers/auth/feishu.py:10 settings/serializers/auth/ldap.py:39
#: settings/serializers/auth/oauth2.py:18 settings/serializers/auth/oidc.py:12
#: settings/serializers/auth/radius.py:13 settings/serializers/auth/saml2.py:11
#: settings/serializers/auth/sso.py:10 settings/serializers/auth/wecom.py:10
msgid "Authentication"
msgstr "认证"
@ -3096,15 +3097,15 @@ msgstr "不能包含特殊字符"
msgid "The mobile phone number format is incorrect"
msgstr "手机号格式不正确"
#: common/views/mixins.py:57
#: common/views/mixins.py:58
msgid "Export all"
msgstr "导出所有"
#: common/views/mixins.py:59
#: common/views/mixins.py:60
msgid "Export only selected items"
msgstr "仅导出选择项"
#: common/views/mixins.py:64
#: common/views/mixins.py:65
#, python-format
msgid "Export filtered: %s"
msgstr "导出搜素: %s"
@ -3204,7 +3205,7 @@ msgstr "任务 {} 执行参数错误"
msgid "Unsupported file content"
msgstr "不支持的文件内容"
#: ops/apps.py:9 ops/notifications.py:16 rbac/tree.py:56
#: ops/apps.py:9 ops/notifications.py:16 rbac/tree.py:55
msgid "App ops"
msgstr "作业中心"
@ -3244,7 +3245,7 @@ msgstr "VCS"
msgid "Adhoc"
msgstr "命令"
#: ops/const.py:39 ops/models/job.py:99
#: ops/const.py:39 ops/models/job.py:100
msgid "Playbook"
msgstr "Playbook"
@ -3305,17 +3306,17 @@ msgstr "需要周期或定期设置"
msgid "Pattern"
msgstr "模式"
#: ops/models/adhoc.py:24 ops/models/job.py:94
#: ops/models/adhoc.py:24 ops/models/job.py:95
msgid "Module"
msgstr "模块"
#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:93
#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:94
#: terminal/models/component/task.py:16
msgid "Args"
msgstr "参数"
#: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53
#: ops/models/job.py:102 ops/models/job.py:184 ops/models/playbook.py:25
#: ops/models/job.py:103 ops/models/job.py:189 ops/models/playbook.py:25
#: terminal/models/session/sharing.py:23
msgid "Creator"
msgstr "创建者"
@ -3332,12 +3333,12 @@ msgstr "最后执行"
msgid "Date last run"
msgstr "最后运行日期"
#: ops/models/base.py:51 ops/models/job.py:182
#: xpack/plugins/cloud/models.py:170
#: ops/models/base.py:51 ops/models/job.py:187
#: xpack/plugins/cloud/models.py:162
msgid "Result"
msgstr "结果"
#: ops/models/base.py:52 ops/models/job.py:183
#: ops/models/base.py:52 ops/models/job.py:188
msgid "Summary"
msgstr "汇总"
@ -3377,47 +3378,47 @@ msgstr "发布日期"
msgid "Celery Task Execution"
msgstr "Celery 任务执行"
#: ops/models/job.py:96
#: ops/models/job.py:97
msgid "Chdir"
msgstr "运行目录"
#: ops/models/job.py:97
#: ops/models/job.py:98
msgid "Timeout (Seconds)"
msgstr "超时时间(秒)"
#: ops/models/job.py:104
#: ops/models/job.py:105
msgid "Use Parameter Define"
msgstr "使用参数定义"
#: ops/models/job.py:105
#: ops/models/job.py:106
msgid "Parameters define"
msgstr "参数定义"
#: ops/models/job.py:106
#: ops/models/job.py:107
msgid "Runas"
msgstr "运行用户"
#: ops/models/job.py:108
#: ops/models/job.py:109
msgid "Runas policy"
msgstr "用户策略"
#: ops/models/job.py:170
#: ops/models/job.py:171
msgid "Job"
msgstr "作业"
#: ops/models/job.py:181
#: ops/models/job.py:186
msgid "Parameters"
msgstr "参数"
#: ops/models/job.py:189
#: ops/models/job.py:194
msgid "Material"
msgstr ""
#: ops/models/job.py:191
#: ops/models/job.py:196
msgid "Material Type"
msgstr ""
#: ops/models/job.py:442
#: ops/models/job.py:455
msgid "Job Execution"
msgstr "作业执行"
@ -3493,6 +3494,10 @@ msgstr "创建或更新周期任务"
msgid "Periodic check service performance"
msgstr "周期检测服务性能"
#: ops/tasks.py:114
msgid "Clean up unexpected jobs"
msgstr "清理异常作业"
#: ops/templates/ops/celery_task_log.html:4
msgid "Task log"
msgstr "任务列表"
@ -3818,59 +3823,63 @@ msgstr "角色显示"
msgid "Has bound this role"
msgstr "已经绑定"
#: rbac/tree.py:18 rbac/tree.py:19
#: rbac/tree.py:17 rbac/tree.py:18
msgid "All permissions"
msgstr "所有权限"
#: rbac/tree.py:25
#: rbac/tree.py:24
msgid "Console view"
msgstr "控制台"
#: rbac/tree.py:26
#: rbac/tree.py:25
msgid "Workbench view"
msgstr "工作台"
#: rbac/tree.py:27
#: rbac/tree.py:26
msgid "Audit view"
msgstr "审计台"
#: rbac/tree.py:28 settings/models.py:159
#: rbac/tree.py:27 settings/models.py:159
msgid "System setting"
msgstr "系统设置"
#: rbac/tree.py:29
#: rbac/tree.py:28
msgid "Other"
msgstr "其它"
#: rbac/tree.py:38
#: rbac/tree.py:37
msgid "Session audits"
msgstr "会话审计"
#: rbac/tree.py:48
#: rbac/tree.py:47
msgid "Cloud import"
msgstr "云同步"
#: rbac/tree.py:49
#: rbac/tree.py:48
msgid "Backup account"
msgstr "备份账号"
#: rbac/tree.py:52
#: rbac/tree.py:49
msgid "Gather account"
msgstr "收集账号"
#: rbac/tree.py:51
msgid "Asset change auth"
msgstr "资产改密"
#: rbac/tree.py:53
#: rbac/tree.py:52
msgid "Terminal setting"
msgstr "终端设置"
#: rbac/tree.py:54
#: rbac/tree.py:53
msgid "Task Center"
msgstr "任务中心"
#: rbac/tree.py:55
#: rbac/tree.py:54
msgid "My assets"
msgstr "我的资产"
#: rbac/tree.py:57 terminal/models/applet/applet.py:43
#: rbac/tree.py:56 terminal/models/applet/applet.py:43
#: terminal/models/applet/applet.py:154 terminal/models/applet/host.py:28
#: terminal/serializers/applet.py:15
msgid "Applet"
@ -4369,7 +4378,7 @@ msgid "SSO auth key TTL"
msgstr "令牌有效期"
#: settings/serializers/auth/sso.py:17
#: xpack/plugins/cloud/serializers/account_attrs.py:176
#: xpack/plugins/cloud/serializers/account_attrs.py:184
msgid "Unit: second"
msgstr "单位: 秒"
@ -4871,6 +4880,11 @@ msgstr ""
"根据登录 IP 是否所属常用登录城市进行判断,若账号在非常用城市登录,会发送异地"
"登录提醒"
#: settings/serializers/settings.py:69
#, python-format
msgid "[%s] %s"
msgstr ""
#: settings/serializers/terminal.py:9
msgid "Hostname"
msgstr "主机名"
@ -5747,7 +5761,7 @@ msgstr "Access key ID(AK)"
msgid "Access key secret"
msgstr "Access key secret(SK)"
#: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:217
#: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:209
msgid "Region"
msgstr "地域"
@ -5909,19 +5923,19 @@ msgid ""
msgstr ""
"通过工单创建, 工单标题: {}, 工单申请人: {}, 工单处理人: {}, 工单 ID: {}"
#: tickets/handlers/base.py:86
#: tickets/handlers/base.py:85
msgid "Change field"
msgstr "变更字段"
#: tickets/handlers/base.py:86
#: tickets/handlers/base.py:85
msgid "Before change"
msgstr "变更前"
#: tickets/handlers/base.py:86
#: tickets/handlers/base.py:85
msgid "After change"
msgstr "变更后"
#: tickets/handlers/base.py:98
#: tickets/handlers/base.py:97
msgid "{} {} the ticket"
msgstr "{} {} 工单"
@ -6175,7 +6189,7 @@ msgstr "无效的审批动作"
msgid "This user is not authorized to approve this ticket"
msgstr "此用户无权审批此工单"
#: users/api/user.py:179
#: users/api/user.py:182
msgid "Could not reset self otp, use profile reset instead"
msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置"
@ -6860,55 +6874,47 @@ msgstr "地域"
msgid "Hostname strategy"
msgstr "主机名策略"
#: xpack/plugins/cloud/models.py:100
msgid "Unix admin user"
msgstr "Unix 管理员"
#: xpack/plugins/cloud/models.py:104
msgid "Windows admin user"
msgstr "Windows 管理员"
#: xpack/plugins/cloud/models.py:110 xpack/plugins/cloud/serializers/task.py:41
#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:40
msgid "IP network segment group"
msgstr "IP网段组"
#: xpack/plugins/cloud/models.py:113 xpack/plugins/cloud/serializers/task.py:46
#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:45
msgid "Sync IP type"
msgstr "同步IP类型"
#: xpack/plugins/cloud/models.py:116 xpack/plugins/cloud/serializers/task.py:64
#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:62
msgid "Always update"
msgstr "总是更新"
#: xpack/plugins/cloud/models.py:122
#: xpack/plugins/cloud/models.py:114
msgid "Date last sync"
msgstr "最后同步日期"
#: xpack/plugins/cloud/models.py:127 xpack/plugins/cloud/models.py:168
#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160
msgid "Sync instance task"
msgstr "同步实例任务"
#: xpack/plugins/cloud/models.py:179 xpack/plugins/cloud/models.py:227
#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219
msgid "Date sync"
msgstr "同步日期"
#: xpack/plugins/cloud/models.py:183
#: xpack/plugins/cloud/models.py:175
msgid "Sync instance task execution"
msgstr "同步实例任务执行"
#: xpack/plugins/cloud/models.py:207
#: xpack/plugins/cloud/models.py:199
msgid "Sync task"
msgstr "同步任务"
#: xpack/plugins/cloud/models.py:211
#: xpack/plugins/cloud/models.py:203
msgid "Sync instance task history"
msgstr "同步实例任务历史"
#: xpack/plugins/cloud/models.py:214
#: xpack/plugins/cloud/models.py:206
msgid "Instance"
msgstr "实例"
#: xpack/plugins/cloud/models.py:231
#: xpack/plugins/cloud/models.py:223
msgid "Sync instance detail"
msgstr "同步实例详情"
@ -7122,52 +7128,52 @@ msgstr "租户 ID"
msgid "Subscription ID"
msgstr "订阅 ID"
#: xpack/plugins/cloud/serializers/account_attrs.py:95
#: xpack/plugins/cloud/serializers/account_attrs.py:100
#: xpack/plugins/cloud/serializers/account_attrs.py:116
#: xpack/plugins/cloud/serializers/account_attrs.py:141
#: xpack/plugins/cloud/serializers/account_attrs.py:98
#: xpack/plugins/cloud/serializers/account_attrs.py:103
#: xpack/plugins/cloud/serializers/account_attrs.py:119
#: xpack/plugins/cloud/serializers/account_attrs.py:149
msgid "API Endpoint"
msgstr "API 端点"
#: xpack/plugins/cloud/serializers/account_attrs.py:106
#: xpack/plugins/cloud/serializers/account_attrs.py:109
msgid "Auth url"
msgstr "认证地址"
#: xpack/plugins/cloud/serializers/account_attrs.py:107
#: xpack/plugins/cloud/serializers/account_attrs.py:110
msgid "eg: http://openstack.example.com:5000/v3"
msgstr "如: http://openstack.example.com:5000/v3"
#: xpack/plugins/cloud/serializers/account_attrs.py:110
#: xpack/plugins/cloud/serializers/account_attrs.py:113
msgid "User domain"
msgstr "用户域"
#: xpack/plugins/cloud/serializers/account_attrs.py:117
#: xpack/plugins/cloud/serializers/account_attrs.py:120
msgid "Cert File"
msgstr "证书文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:118
#: xpack/plugins/cloud/serializers/account_attrs.py:121
msgid "Key File"
msgstr "密钥文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:134
#: xpack/plugins/cloud/serializers/account_attrs.py:137
msgid "Service account key"
msgstr "服务账号密钥"
#: xpack/plugins/cloud/serializers/account_attrs.py:135
#: xpack/plugins/cloud/serializers/account_attrs.py:138
msgid "The file is in JSON format"
msgstr "JSON 格式的文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:148
#: xpack/plugins/cloud/serializers/account_attrs.py:156
msgid "IP address invalid `{}`, {}"
msgstr "IP 地址无效: `{}`, {}"
#: xpack/plugins/cloud/serializers/account_attrs.py:154
#: xpack/plugins/cloud/serializers/account_attrs.py:162
msgid ""
"Format for comma-delimited string,Such as: 192.168.1.0/24, "
"10.0.0.0-10.0.0.255"
msgstr "格式为逗号分隔的字符串192.168.1.0/24,10.0.0.0-10.0.0.255"
#: xpack/plugins/cloud/serializers/account_attrs.py:158
#: xpack/plugins/cloud/serializers/account_attrs.py:166
msgid ""
"The port is used to detect the validity of the IP address. When the "
"synchronization task is executed, only the valid IP address will be "
@ -7176,19 +7182,19 @@ msgstr ""
"端口用来检测 IP 地址的有效性,在同步任务执行时,只会同步有效的 IP 地址。 <br>"
"如果端口为 0则表示所有 IP 地址均有效。"
#: xpack/plugins/cloud/serializers/account_attrs.py:166
#: xpack/plugins/cloud/serializers/account_attrs.py:174
msgid "Hostname prefix"
msgstr "主机名前缀"
#: xpack/plugins/cloud/serializers/account_attrs.py:169
#: xpack/plugins/cloud/serializers/account_attrs.py:177
msgid "IP segment"
msgstr "IP 网段"
#: xpack/plugins/cloud/serializers/account_attrs.py:173
#: xpack/plugins/cloud/serializers/account_attrs.py:181
msgid "Test port"
msgstr "测试端口"
#: xpack/plugins/cloud/serializers/account_attrs.py:176
#: xpack/plugins/cloud/serializers/account_attrs.py:184
msgid "Test timeout"
msgstr "测试超时时间"
@ -7212,9 +7218,13 @@ msgstr "执行次数"
msgid "Instance count"
msgstr "实例个数"
#: xpack/plugins/cloud/serializers/task.py:63
msgid "Linux admin user"
msgstr "Linux 管理员"
#: xpack/plugins/cloud/tasks.py:27
msgid "Run sync instance task"
msgstr "执行同步实例任务"
#: xpack/plugins/cloud/tasks.py:41
msgid "Period clean sync instance task execution"
msgstr "定期清除同步实例任务执行记录"
#: xpack/plugins/cloud/utils.py:69
msgid "Account unavailable"
@ -7228,31 +7238,31 @@ msgstr "恢复默认成功!"
msgid "Interface settings"
msgstr "界面设置"
#: xpack/plugins/interface/models.py:22
#: xpack/plugins/interface/models.py:23
msgid "Title of login page"
msgstr "登录页面标题"
#: xpack/plugins/interface/models.py:26
#: xpack/plugins/interface/models.py:27
msgid "Image of login page"
msgstr "登录页面图片"
#: xpack/plugins/interface/models.py:30
#: xpack/plugins/interface/models.py:31
msgid "Website icon"
msgstr "网站图标"
#: xpack/plugins/interface/models.py:34
#: xpack/plugins/interface/models.py:35
msgid "Logo of management page"
msgstr "管理页面logo"
#: xpack/plugins/interface/models.py:38
#: xpack/plugins/interface/models.py:39
msgid "Logo of logout page"
msgstr "退出页面logo"
#: xpack/plugins/interface/models.py:40
#: xpack/plugins/interface/models.py:41
msgid "Theme"
msgstr "主题"
#: xpack/plugins/interface/models.py:43 xpack/plugins/interface/models.py:84
#: xpack/plugins/interface/models.py:44 xpack/plugins/interface/models.py:85
msgid "Interface setting"
msgstr "界面设置"
@ -7284,11 +7294,14 @@ msgstr "旗舰版"
msgid "Community edition"
msgstr "社区版"
#~ msgid "Run sync instance task"
#~ msgstr "执行同步实例任务"
#~ msgid "Unix admin user"
#~ msgstr "Unix 管理员"
#~ msgid "Period clean sync instance task execution"
#~ msgstr "定期清除同步实例任务执行记录"
#~ msgid "Windows admin user"
#~ msgstr "Windows 管理员"
#~ msgid "Linux admin user"
#~ msgstr "Linux 管理员"
#~ msgid "Can push account to asset"
#~ msgstr "可以推送账号到资产"

View File

@ -3,6 +3,7 @@ import logging
import os
import uuid
from collections import defaultdict
from datetime import timedelta
from celery import current_task
from django.conf import settings
@ -172,6 +173,10 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin):
ordering = ['date_created']
zombie_task_exception = Exception(
'This task has been marked as a zombie task because it has not updated its status for too long')
class JobExecution(JMSOrgBaseModel):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
task_id = models.UUIDField(null=True)
@ -190,6 +195,14 @@ class JobExecution(JMSOrgBaseModel):
job_type = models.CharField(max_length=128, choices=Types.choices, default=Types.adhoc,
verbose_name=_("Material Type"))
# clean up zombie execution
@classmethod
def clean_unexpected_execution(cls):
for execution in cls.objects.filter(status__in=[JobStatus.running]).all():
if execution.date_created < (timezone.now() - timedelta(hours=3)):
execution.set_error(zombie_task_exception)
@property
def current_job(self):
if self.job.version != self.job_version:

View File

@ -5,7 +5,7 @@ from celery.exceptions import SoftTimeLimitExceeded
from django.utils.translation import ugettext_lazy as _
from common.utils import get_logger, get_object_or_none
from orgs.utils import tmp_to_org
from orgs.utils import tmp_to_org, tmp_to_root_org
from .celery.decorator import (
register_as_period_task, after_app_ready_start
)
@ -109,3 +109,10 @@ def create_or_update_registered_periodic_tasks():
@register_as_period_task(interval=3600)
def check_server_performance_period():
ServerPerformanceCheckUtil().check_and_publish()
@shared_task(verbose_name=_("Clean up unexpected jobs"))
@register_as_period_task(interval=3600)
def clean_up_unexpected_jobs():
with tmp_to_root_org():
JobExecution.clean_unexpected_execution()

View File

@ -13,7 +13,7 @@ class CeleryTaskLogView(PermissionsMixin, TemplateView):
template_name = 'ops/celery_task_log.html'
permission_classes = [RBACPermission]
rbac_perms = {
'GET': 'ops.view_tasklog'
'GET': 'ops.view_celerytask'
}
def get_context_data(self, **kwargs):

View File

@ -29,13 +29,12 @@ class BaseUserPermedAssetsApi(SelfOrPKUserMixin, ListAPIView):
ordering_fields = ("name", "address")
filterset_class = AssetFilterSet
serializer_class = serializers.AssetPermedSerializer
only_fields = serializers.AssetPermedSerializer.Meta.only_fields
def get_queryset(self):
if getattr(self, 'swagger_fake_view', False):
return Asset.objects.none()
assets = self.get_assets()
assets = assets.prefetch_related('platform').only(*self.only_fields)
assets = self.serializer_class.setup_eager_loading(assets)
return assets
@abc.abstractmethod

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
from django.db.models import F
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
@ -32,9 +33,18 @@ class AssetPermedSerializer(OrgResourceModelSerializerMixin):
"id", "name", "address", 'domain', 'platform',
"comment", "org_id", "is_active",
]
fields = only_fields + ['protocols', 'category', 'type', 'spec_info'] + ['org_name']
fields = only_fields + ['protocols', 'category', 'type'] + ['org_name']
read_only_fields = fields
@classmethod
def setup_eager_loading(cls, queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.prefetch_related('domain', 'nodes', 'labels') \
.prefetch_related('platform', 'protocols') \
.annotate(category=F("platform__category")) \
.annotate(type=F("platform__type"))
return queryset
class NodePermedSerializer(serializers.ModelSerializer):
class Meta:

View File

@ -18,11 +18,11 @@ __all__ = [
class RoleViewSet(JMSModelViewSet):
queryset = Role.objects.all()
ordering = ('-builtin', 'scope', 'name')
serializer_classes = {
'default': RoleSerializer,
'users': RoleUserSerializer,
}
ordering = ('-builtin', 'name')
filterset_class = RoleFilter
search_fields = ('name', 'scope', 'builtin')
rbac_perms = {
@ -56,11 +56,15 @@ class RoleViewSet(JMSModelViewSet):
return
instance.permissions.set(clone.get_permissions())
@staticmethod
def set_users_amount(queryset):
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
queryset = queryset.order_by(*self.ordering)
return queryset
def set_users_amount(self, queryset):
"""设置角色的用户绑定数量,以减少查询"""
ids = [role.id for role in queryset]
queryset = Role.objects.filter(id__in=ids)
queryset = Role.objects.filter(id__in=ids).order_by(*self.ordering)
org_id = current_org.id
q = Q(role__scope=Role.Scope.system) | Q(role__scope=Role.Scope.org, org_id=org_id)
role_bindings = RoleBinding.objects.filter(q).values_list('role_id').annotate(user_count=Count('user_id'))
@ -95,14 +99,16 @@ class SystemRoleViewSet(RoleViewSet):
perm_model = SystemRole
def get_queryset(self):
return super().get_queryset().filter(scope='system')
qs = super().get_queryset().filter(scope='system')
return qs
class OrgRoleViewSet(RoleViewSet):
perm_model = OrgRole
def get_queryset(self):
return super().get_queryset().filter(scope='org')
qs = super().get_queryset().filter(scope='org')
return qs
class BaseRolePermissionsViewSet(PermissionViewSet):

View File

@ -61,6 +61,8 @@ exclude_permissions = (
('accounts', 'accountbackupexecution', 'delete,change', 'accountbackupexecution'),
('accounts', 'changesecretrecord', 'add,delete,change', 'changesecretrecord'),
('accounts', 'account', 'change', 'accountsecret'),
('accounts', 'account', 'view', 'historyaccount'),
('accounts', 'account', 'view', 'historyaccountsecret'),
('perms', 'userassetgrantedtreenoderelation', '*', '*'),
('perms', 'permedaccount', '*', '*'),

View File

@ -1,14 +1,13 @@
#!/usr/bin/python
import os
from typing import Callable
from django.apps import apps
from django.conf import settings
from django.db.models import F
from django.utils.translation import gettext_lazy as _, gettext, get_language
from treelib import Tree
from treelib.exceptions import NodeIDAbsentError
from django.utils.translation import gettext_lazy as _, gettext, get_language
from django.conf import settings
from django.apps import apps
from django.db.models import F, Count
from common.tree import TreeNode
from .models import Permission, ContentType
@ -77,6 +76,7 @@ special_pid_mapper = {
"accounts.pushaccountautomation": "push_account_node",
"accounts.view_pushaccountexecution": "push_account_node",
"accounts.add_pushaccountexecution": "push_account_node",
"accounts.gatheredaccount": "gather_account_node",
"accounts.gatheraccountsautomation": "gather_account_node",
"accounts.view_gatheraccountsexecution": "gather_account_node",
"accounts.add_gatheraccountsexecution": "gather_account_node",

View File

@ -7,7 +7,7 @@ __all__ = [
class AuthSettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('Basic'))
PREFIX_TITLE = _('Authentication')
AUTH_CAS = serializers.BooleanField(required=False, label=_('CAS Auth'))
AUTH_OPENID = serializers.BooleanField(required=False, label=_('OPENID Auth'))

View File

@ -7,7 +7,7 @@ __all__ = [
class CASSettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('CAS'))
PREFIX_TITLE = _('CAS')
AUTH_CAS = serializers.BooleanField(required=False, label=_('Enable CAS Auth'))
CAS_SERVER_URL = serializers.CharField(required=False, max_length=1024, label=_('Server url'))

View File

@ -7,7 +7,7 @@ __all__ = ['DingTalkSettingSerializer']
class DingTalkSettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('DingTalk'))
PREFIX_TITLE = _('DingTalk')
DINGTALK_AGENTID = serializers.CharField(max_length=256, required=True, label='AgentId')
DINGTALK_APPKEY = serializers.CharField(max_length=256, required=True, label='AppKey')

View File

@ -7,7 +7,7 @@ __all__ = ['FeiShuSettingSerializer']
class FeiShuSettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('FeiShu'))
PREFIX_TITLE = _('FeiShu')
FEISHU_APP_ID = serializers.CharField(max_length=256, required=True, label='App ID')
FEISHU_APP_SECRET = EncryptedField(max_length=256, required=False, label='App Secret')

View File

@ -36,7 +36,7 @@ class LDAPUserSerializer(serializers.Serializer):
class LDAPSettingSerializer(serializers.Serializer):
# encrypt_fields 现在使用 write_only 来判断了
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('LDAP'))
PREFIX_TITLE = _('LDAP')
AUTH_LDAP_SERVER_URI = serializers.CharField(
required=True, max_length=1024, label=_('LDAP server'),

View File

@ -15,7 +15,7 @@ class SettingImageField(serializers.ImageField):
class OAuth2SettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('OAuth2'))
PREFIX_TITLE = _('OAuth2')
AUTH_OAUTH2 = serializers.BooleanField(
default=False, label=_('Enable OAuth2 Auth')

View File

@ -9,7 +9,7 @@ __all__ = [
class CommonSettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('OIDC'))
PREFIX_TITLE = _('OIDC')
# OpenID 公有配置参数 (version <= 1.5.8 或 version >= 1.5.8)
BASE_SITE_URL = serializers.CharField(
required=False, allow_null=True, allow_blank=True,

View File

@ -10,7 +10,7 @@ __all__ = ['RadiusSettingSerializer']
class RadiusSettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('Radius'))
PREFIX_TITLE = _('Radius')
AUTH_RADIUS = serializers.BooleanField(required=False, label=_('Enable Radius Auth'))
RADIUS_SERVER = serializers.CharField(required=False, allow_blank=True, max_length=1024, label=_('Host'))

View File

@ -8,7 +8,7 @@ __all__ = [
class SAML2SettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('SAML2'))
PREFIX_TITLE = _('SAML2')
AUTH_SAML2 = serializers.BooleanField(
default=False, required=False, label=_('Enable SAML2 Auth')

View File

@ -7,7 +7,7 @@ __all__ = [
class SSOSettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('SSO'))
PREFIX_TITLE = _('SSO')
AUTH_SSO = serializers.BooleanField(
required=False, label=_('Enable SSO auth'),

View File

@ -7,7 +7,7 @@ __all__ = ['WeComSettingSerializer']
class WeComSettingSerializer(serializers.Serializer):
PREFIX_TITLE = '%s-%s' % (_('Authentication'), _('WeCom'))
PREFIX_TITLE = _('WeCom')
WECOM_CORPID = serializers.CharField(max_length=256, required=True, label='corpid')
WECOM_AGENTID = serializers.CharField(max_length=256, required=True, label='agentid')

View File

@ -1,7 +1,9 @@
# coding: utf-8
from django.core.cache import cache
from django.utils.translation import ugettext_lazy as _
from django.utils import translation
from django.utils.translation import gettext_noop, ugettext_lazy as _
from common.utils import i18n_fmt
from .basic import BasicSettingSerializer
from .other import OtherSettingSerializer
from .email import EmailSettingSerializer, EmailContentSettingSerializer
@ -55,13 +57,16 @@ class SettingsSerializer(
# 单次计算量不大,搞个缓存,以防操作日志大量写入时,这里影响性能
def get_field_label(self, field_name):
self.fields_label_mapping = cache.get(self.CACHE_KEY, None)
if self.fields_label_mapping is None:
self.fields_label_mapping = {}
for subclass in SettingsSerializer.__bases__:
prefix = getattr(subclass, 'PREFIX_TITLE', _('Setting'))
fields = subclass().get_fields()
for name, item in fields.items():
label = '[%s] %s' % (prefix, getattr(item, 'label', ''))
self.fields_label_mapping[name] = label
with translation.override('en'):
for subclass in SettingsSerializer.__bases__:
prefix = getattr(subclass, 'PREFIX_TITLE', _('Setting'))
fields = subclass().get_fields()
for name, item in fields.items():
label = getattr(item, 'label', '')
detail = i18n_fmt(gettext_noop('[%s] %s'), prefix, label)
self.fields_label_mapping[name] = detail
cache.set(self.CACHE_KEY, self.fields_label_mapping, 3600 * 24)
return self.fields_label_mapping.get(field_name)

View File

@ -148,7 +148,7 @@ class AppletMethod:
class ConnectMethodUtil:
_all_methods = None
_all_methods = {}
@classmethod
def protocols(cls):
@ -210,7 +210,7 @@ class ConnectMethodUtil:
@classmethod
def refresh_methods(cls):
cls._all_methods = None
cls._all_methods = {}
@classmethod
def get_filtered_protocols_connect_methods(cls, os):
@ -245,8 +245,8 @@ class ConnectMethodUtil:
@classmethod
def get_protocols_connect_methods(cls, os):
if cls._all_methods is not None:
return cls._all_methods
if cls._all_methods.get('os'):
return cls._all_methods['os']
methods = defaultdict(list)
web_methods = WebMethod.get_methods()
@ -298,5 +298,5 @@ class ConnectMethodUtil:
method['component'] = TerminalType.tinker.value
methods[protocol].extend(applet_methods)
cls._all_methods = methods
cls._all_methods[os] = methods
return methods