Merge pull request #14990 from jumpserver/pam

Pam
pull/14991/head
feng626 2025-03-10 19:14:00 +08:00 committed by GitHub
commit 3a1d3c1f5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 1772 additions and 1580 deletions

View File

@ -1,121 +0,0 @@
<p align="center">
<a href="https://jumpserver.org"><img src="https://download.jumpserver.org/images/jumpserver-logo.svg" alt="JumpServer" width="300" /></a>
</p>
<h3 align="center">广受欢迎的开源堡垒机</h3>
<p align="center">
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://img.shields.io/github/license/jumpserver/jumpserver" alt="License: GPLv3"></a>
<a href="https://hub.docker.com/u/jumpserver"><img src="https://img.shields.io/docker/pulls/jumpserver/jms_all.svg" alt="Docker pulls"></a>
<a href="https://github.com/jumpserver/jumpserver/releases/latest"><img src="https://img.shields.io/github/v/release/jumpserver/jumpserver" alt="Latest release"></a>
<a href="https://github.com/jumpserver/jumpserver"><img src="https://img.shields.io/github/stars/jumpserver/jumpserver?color=%231890FF&style=flat-square" alt="Stars"></a>
</p>
<p align="center">
10 年时间,倾情投入,用心做好一款开源堡垒机。
</p>
------------------------------
## JumpServer 是什么?
JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运维安全审计系统。JumpServer 堡垒机帮助企业以更安全的方式管控和登录各种类型的资产,包括:
- **SSH**: Linux / Unix / 网络设备 等;
- **Windows**: Web 方式连接 / 原生 RDP 连接;
- **数据库**: MySQL / MariaDB / PostgreSQL / Oracle / SQLServer / ClickHouse 等;
- **NoSQL**: Redis / MongoDB 等;
- **GPT**: ChatGPT 等;
- **云服务**: Kubernetes / VMware vSphere 等;
- **Web 站点**: 各类系统的 Web 管理后台;
- **应用**: 通过 Remote App 连接各类应用。
## 产品特色
- **开源**: 零门槛,线上快速获取和安装;
- **无插件**: 仅需浏览器,极致的 Web Terminal 使用体验;
- **分布式**: 支持分布式部署和横向扩展,轻松支持大规模并发访问;
- **多云支持**: 一套系统,同时管理不同云上面的资产;
- **多租户**: 一套系统,多个子公司或部门同时使用;
- **云端存储**: 审计录像云端存储,永不丢失;
## 快速开始
- [快速入门](https://docs.jumpserver.org/zh/v3/quick_start/)
- [产品文档](https://docs.jumpserver.org)
- [在线学习](https://edu.fit2cloud.com/page/2635362)
- [知识库](https://kb.fit2cloud.com/categories/jumpserver)
## UI 展示
![UI展示](https://docs.jumpserver.org/zh/v3/img/dashboard.png)
## 在线体验
- 环境地址:<https://demo.jumpserver.org/>
| :warning: 注意 |
|:-----------------------------|
| 该环境仅作体验目的使用,我们会定时清理、重置数据! |
| 请勿修改体验环境用户的密码! |
| 请勿在环境中添加业务生产环境地址、用户名密码等敏感信息! |
## 案例研究
- [腾讯音乐娱乐集团基于JumpServer的安全运维审计解决方案](https://blog.fit2cloud.com/?p=a04cdf0d-6704-4d18-9b40-9180baecd0e2)
- [腾讯海外游戏基于JumpServer构建游戏安全运营能力](https://blog.fit2cloud.com/?p=3704)
- [万华化学通过JumpServer管理全球化分布式IT资产并且实现与云管平台的联动](https://blog.fit2cloud.com/?p=3504)
- [雪花啤酒JumpServer堡垒机使用体会](https://blog.fit2cloud.com/?p=3412)
- [顺丰科技JumpServer 堡垒机护航顺丰科技超大规模资产安全运维](https://blog.fit2cloud.com/?p=1147)
- [沐瞳游戏通过JumpServer管控多项目分布式资产](https://blog.fit2cloud.com/?p=3213)
- [携程JumpServer 堡垒机部署与运营实战](https://blog.fit2cloud.com/?p=851)
- [大智慧JumpServer 堡垒机让“大智慧”的混合 IT 运维更智慧](https://blog.fit2cloud.com/?p=882)
- [小红书JumpServer 堡垒机大规模资产跨版本迁移之路](https://blog.fit2cloud.com/?p=516)
- [中手游JumpServer堡垒机助力中手游提升多云环境下安全运维能力](https://blog.fit2cloud.com/?p=732)
- [中通快递JumpServer主机安全运维实践](https://blog.fit2cloud.com/?p=708)
- [东方明珠JumpServer高效管控异构化、分布式云端资产](https://blog.fit2cloud.com/?p=687)
- [江苏农信JumpServer堡垒机助力行业云安全运维](https://blog.fit2cloud.com/?p=666)
## 社区交流
如果您在使用过程中有任何疑问或对建议,欢迎提交 [GitHub Issue](https://github.com/jumpserver/jumpserver/issues/new/choose)。
您也可以到我们的 [社区论坛](https://bbs.fit2cloud.com/c/js/5) 当中进行交流沟通。
## 参与贡献
欢迎提交 PR 参与贡献。 参考 [CONTRIBUTING.md](https://github.com/jumpserver/jumpserver/blob/dev/CONTRIBUTING.md)
## 组件项目
| Project | Status | Description |
|--------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
| [Lina](https://github.com/jumpserver/lina) | <a href="https://github.com/jumpserver/lina/releases"><img alt="Lina release" src="https://img.shields.io/github/release/jumpserver/lina.svg" /></a> | JumpServer Web UI |
| [Luna](https://github.com/jumpserver/luna) | <a href="https://github.com/jumpserver/luna/releases"><img alt="Luna release" src="https://img.shields.io/github/release/jumpserver/luna.svg" /></a> | JumpServer Web Terminal |
| [KoKo](https://github.com/jumpserver/koko) | <a href="https://github.com/jumpserver/koko/releases"><img alt="Koko release" src="https://img.shields.io/github/release/jumpserver/koko.svg" /></a> | JumpServer Character Protocol Connector |
| [Lion](https://github.com/jumpserver/lion) | <a href="https://github.com/jumpserver/lion/releases"><img alt="Lion release" src="https://img.shields.io/github/release/jumpserver/lion.svg" /></a> | JumpServer Graphical Protocol Connector |
| [Chen](https://github.com/jumpserver/chen) | <a href="https://github.com/jumpserver/chen/releases"><img alt="Chen release" src="https://img.shields.io/github/release/jumpserver/chen.svg" /> | JumpServer Web DB |
| [Razor](https://github.com/jumpserver/razor) | <img alt="Chen" src="https://img.shields.io/badge/release-private-red" /> | JumpServer EE RDP Proxy Connector |
| [Tinker](https://github.com/jumpserver/tinker) | <img alt="Tinker" src="https://img.shields.io/badge/release-private-red" /> | JumpServer EE Remote Application Connector (Windows) |
| [Panda](https://github.com/jumpserver/Panda) | <img alt="Panda" src="https://img.shields.io/badge/release-private-red" /> | JumpServer EE Remote Application Connector (Linux) |
| [Magnus](https://github.com/jumpserver/magnus) | <img alt="Magnus" src="https://img.shields.io/badge/release-private-red" /> | JumpServer EE Database Proxy Connector |
## 安全说明
JumpServer是一款安全产品请参考 [基本安全建议](https://docs.jumpserver.org/zh/master/install/install_security/)
进行安装部署。如果您发现安全相关问题,请直接联系我们:
- 邮箱support@fit2cloud.com
- 电话400-052-0755
## License & Copyright
Copyright (c) 2014-2024 飞致云, All rights reserved.
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
https://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "
AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.

View File

@ -1,6 +1,7 @@
import os
from django.utils.translation import gettext_lazy as _, get_language
from django.conf import settings
from django.utils.translation import gettext_lazy as _, get_language
from rest_framework.decorators import action
from rest_framework.response import Response
@ -45,9 +46,9 @@ class IntegrationApplicationViewSet(OrgBulkModelViewSet):
'node': 'js',
'curl': 'sh',
}
sdk_language = request.query_params.get('language','python')
sdk_language = request.query_params.get('language', 'python')
sdk_path = os.path.join(settings.APPS_DIR, 'accounts', 'demos', sdk_language)
readme_path = os.path.join(sdk_path, f'readme.{get_language()}.md')
readme_path = os.path.join(sdk_path, f'README.{get_language()}.md')
demo_path = os.path.join(sdk_path, f'demo.{code_suffix_mapper[sdk_language]}')
readme_content = self.read_file(readme_path)

View File

@ -75,19 +75,17 @@ class ChangeSecretRecordViewSet(mixins.ListModelMixin, OrgGenericViewSet):
date_finished=Subquery(
recent_dates.filter(account=OuterRef('account')).values('max_date_finished')[:1]
)
).filter(Q(status=ChangeSecretRecordStatusChoice.success) | Q(ignore_fail=True))
).filter(Q(status=ChangeSecretRecordStatusChoice.success))
failed_records = queryset.filter(
~Q(account__in=Subquery(recent_success_accounts.values('account'))),
status=ChangeSecretRecordStatusChoice.failed
status=ChangeSecretRecordStatusChoice.failed,
ignore_fail=False
)
return failed_records
def get_queryset(self):
qs = ChangeSecretRecord.get_valid_records()
return qs.filter(
execution__automation__type=self.tp
)
return ChangeSecretRecord.get_valid_records()
@action(methods=['post'], detail=False, url_path='execute')
def execute(self, request, *args, **kwargs):

View File

@ -155,7 +155,7 @@ class ChangeSecretDashboardApi(APIView):
for task in tasks:
_id = task.get('id')
name = task.get('name')
tp = task.kwargs.get('tp')
tp = task.get('kwargs', {}).get('tp')
if name == self.task_name and tp == self.tp:
execution_ids.append(_id)

View File

@ -95,6 +95,7 @@ class GatheredAccountViewSet(OrgBulkModelViewSet):
updated_instances.update(status=new_status)
if new_status == "confirmed":
GatheredAccount.sync_accounts(updated_instances)
updated_instances.update(present=True)
return Response(status=status.HTTP_200_OK)

View File

@ -52,10 +52,7 @@ class PushAccountRecordViewSet(mixins.ListModelMixin, OrgGenericViewSet):
}
def get_queryset(self):
qs = PushSecretRecord.get_valid_records()
return qs.filter(
execution__automation__type=self.tp
)
return PushSecretRecord.get_valid_records()
class PushAccountAssetsListApi(AutomationAssetsListApi):

View File

@ -174,8 +174,9 @@ class AccountBackupHandler:
if not files:
return
recipients = User.objects.filter(id__in=list(recipients))
msg = _("Start sending backup emails")
print(
f'\033[32m>>> {_("Start sending backup emails")}\033[0m'
f'\033[32m>>> {msg}\033[0m'
''
)
name = self.name

View File

@ -1,3 +1,4 @@
import time
from copy import deepcopy
from django.conf import settings
@ -119,12 +120,38 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
for account in accounts:
h = deepcopy(host)
h['name'] += '(' + account.username + ')' # To distinguish different accounts
h = self.gen_account_inventory(account, asset, h, path_dir)
try:
h = self.gen_account_inventory(account, asset, h, path_dir)
except Exception as e:
h['error'] = str(e)
inventory_hosts.append(h)
return inventory_hosts
def wait_and_save_recorder(self, recorder, max_retries=10, retry_interval=2):
recorder_model = type(recorder)
for attempt in range(max_retries):
exist = recorder_model.objects.filter(
account_id=recorder.account_id, execution=self.execution
).exists()
if exist:
print(f"Data inserted, updating recorder status after {attempt + 1}th query")
recorder.save(update_fields=['error', 'status', 'date_finished'])
return True
print(f"Data not ready, waiting {retry_interval} second(s) and retrying ({attempt + 1}/{max_retries})")
time.sleep(retry_interval)
print("\033[31m The data is still not inserted, giving up saving the recorder status.\033[0m")
return False
def save_record(self, recorder):
self.wait_and_save_recorder(recorder)
def on_host_success(self, host, result):
recorder = self.name_recorder_mapper.get(host)
if not recorder:
return
@ -141,10 +168,6 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
account.date_change_secret = timezone.now()
account.change_secret_status = ChangeSecretRecordStatusChoice.success
with safe_db_connection():
recorder.save(update_fields=['status', 'date_finished'])
account.save(update_fields=['secret', 'date_updated', 'date_change_secret', 'change_secret_status'])
self.summary['ok_accounts'] += 1
self.result['ok_accounts'].append(
{
@ -154,6 +177,10 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
)
super().on_host_success(host, result)
with safe_db_connection():
account.save(update_fields=['secret', 'date_updated', 'date_change_secret', 'change_secret_status'])
self.save_record(recorder)
def on_host_error(self, host, error, result):
recorder = self.name_recorder_mapper.get(host)
if not recorder:
@ -161,10 +188,7 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
recorder.status = ChangeSecretRecordStatusChoice.failed.value
recorder.date_finished = timezone.now()
recorder.error = error
try:
recorder.save()
except Exception as e:
print(f"\033[31m Save {host} recorder error: {e} \033[0m\n")
self.summary['fail_accounts'] += 1
self.result['fail_accounts'].append(
{
@ -173,3 +197,6 @@ class BaseChangeSecretPushManager(AccountBasePlaybookManager):
}
)
super().on_host_error(host, error, result)
with safe_db_connection():
self.save_record(recorder)

View File

@ -6,6 +6,7 @@ import uuid
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from accounts.models import Account, AccountRisk, RiskChoice
from assets.automations.base.manager import BaseManager
@ -220,8 +221,6 @@ class CheckAccountManager(BaseManager):
def pre_run(self):
super().pre_run()
self.assets = self.execution.get_all_assets()
self.execution.date_start = timezone.now()
self.execution.save(update_fields=["date_start"])
def batch_check(self, handler):
print("Engine: {}".format(handler.__class__.__name__))
@ -268,17 +267,13 @@ class CheckAccountManager(BaseManager):
return "accounts/check_account_report.html"
def print_summary(self):
tmpl = (
"\n---\nSummary: \nok: %s, weak password: %s, leaked password: %s, "
"repeated password: %s, no secret: %s, using time: %ss"
% (
self.summary["ok"],
self.summary[RiskChoice.weak_password],
self.summary[RiskChoice.leaked_password],
self.summary[RiskChoice.repeated_password],
self.summary["no_secret"],
int(self.duration),
)
tmpl = _("\n---\nSummary: \nok: {}, weak password: {}, leaked password: {}, "
"repeated password: {}, no secret: {}, using time: {}s").format(
self.summary["ok"],
self.summary[RiskChoice.weak_password],
self.summary[RiskChoice.leaked_password],
self.summary[RiskChoice.repeated_password],
self.summary["no_secret"],
int(self.duration)
)
print(tmpl)

View File

@ -378,6 +378,11 @@ class GatherAccountsManager(AccountBasePlaybookManager):
continue
gathered_accounts = GatheredAccount.objects.filter(asset=asset)
GatheredAccount.sync_accounts(gathered_accounts, self.is_sync_account)
GatheredAccount.objects.filter(
asset=asset, username__in=ori_users, present=False
).update(
present=True
)
# 因为有 bulk create, bulk update, 所以这里需要 sleep 一下,等待数据同步
time.sleep(0.5)

View File

@ -25,9 +25,11 @@ class PushAccountManager(BaseChangeSecretPushManager):
return account.secret
def gen_account_inventory(self, account, asset, h, path_dir):
self.get_or_create_record(asset, account, h['name'])
secret = self.get_secret(account)
secret_type = account.secret_type
if not secret:
raise ValueError(_('Secret cannot be empty'))
self.get_or_create_record(asset, account, h['name'])
new_secret, private_key_path = self.handle_ssh_secret(secret_type, secret, path_dir)
h = self.gen_inventory(h, account, new_secret, private_key_path, asset)
return h

View File

@ -83,8 +83,7 @@ class AccountFilterSet(BaseFilterSet):
integrationapplication = IntegrationApplication.objects.filter(pk=value).first()
if not integrationapplication:
return IntegrationApplication.objects.none()
queryset = integrationapplication.get_accounts()
return queryset
return queryset & integrationapplication.get_accounts()
@staticmethod
def filter_latest(queryset, name, value):
@ -150,7 +149,7 @@ class GatheredAccountFilterSet(BaseFilterSet):
fields = ["id", "username"]
class SecretRecordMixin:
class SecretRecordMixin(drf_filters.FilterSet):
asset_name = drf_filters.CharFilter(
field_name="asset__name", lookup_expr="icontains"
)

View File

@ -170,7 +170,7 @@ class Migration(migrations.Migration):
verbose_name="Status",
),
),
("details", models.JSONField(default=list, verbose_name="Details")),
("details", models.JSONField(default=list, verbose_name="Detail")),
],
options={
"verbose_name": "Account risk",

View File

@ -3,6 +3,7 @@ from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from simple_history.models import HistoricalRecords
from assets.models import Asset
from assets.models.base import AbsConnectivity
from common.utils import lazyproperty, get_logger
from labels.mixins import LabeledMixin
@ -59,7 +60,24 @@ class AccountHistoricalRecords(HistoricalRecords):
return super().create_history_model(model, inherited)
class Account(AbsConnectivity, LabeledMixin, BaseAccount):
class JSONFilterMixin:
@staticmethod
def get_json_filter_attr_q(name, value, match):
if name == "asset":
if match == "m2m_all":
asset_id = (
Asset.objects.filter(id__in=value)
.annotate(count=models.Count("id"))
.filter(count=len(value))
.values_list("id", flat=True)
)
else:
asset_id = Asset.objects.filter(id__in=value).values_list("id", flat=True)
return models.Q(asset_id__in=asset_id)
return None
class Account(AbsConnectivity, LabeledMixin, BaseAccount, JSONFilterMixin):
asset = models.ForeignKey(
'assets.Asset', related_name='accounts',
on_delete=models.CASCADE, verbose_name=_('Asset')

View File

@ -7,6 +7,7 @@ from accounts.const import (
)
from common.db import fields
from common.db.models import JMSBaseModel
from orgs.utils import get_current_org
from .base import AccountBaseAutomation, ChangeSecretMixin
__all__ = ['ChangeSecretAutomation', 'ChangeSecretRecord', 'BaseSecretRecord']
@ -57,9 +58,15 @@ class BaseSecretRecord(JMSBaseModel):
@classmethod
def get_valid_records(cls):
org = get_current_org()
if org is None or org.is_root():
kwargs = {}
else:
kwargs = {'execution__org_id': org.id}
return cls.objects.exclude(
Q(execution__isnull=True) | Q(asset__isnull=True) | Q(account__isnull=True)
)
).filter(**kwargs)
class ChangeSecretRecord(BaseSecretRecord):

View File

@ -171,4 +171,8 @@ class RiskHandler:
}
execution.save()
execution.start()
GatheredAccount.objects.filter(asset=self.asset, username=self.username).update(
present=True
)
return execution.summary

View File

@ -86,8 +86,8 @@ class ChangeSecretAutomationSerializer(AuthValidateMixin, BaseAutomationSerializ
msg = _("* Please enter the correct password length")
raise serializers.ValidationError(msg)
if length < 6 or length > 30:
msg = _('* Password length range 6-30 bits')
if length < 8 or length > 36:
msg = _('* Password length range 8-36 bits')
raise serializers.ValidationError(msg)
return password_rules

View File

@ -3,52 +3,71 @@
<div class="report-container">
<header class="header">
{% autoescape off %}
{{ logo }}
{% endautoescape %}
</header>
<section class="basic-info-section">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="basic-info"
></span>
<div class="info-section">
<h2 class="info">
{% trans 'The following is a summary of account backup tasks, please review and handle them' %}
</h2>
<h2>{% trans 'Basic Information' %}</h2>
</div>
<main class="main-section">
<div class="synopsis-section">
<div class="synopsis-item">
<div class="synopsis-item-content">
<p>
<span class="item-label">{% trans 'Task name' %}</span>:
<span>{{ execution.automation.name }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date start' %}</span>:
<span>{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date end' %}</span>:
<span>{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Time using' %}</span>:
<span>{{ execution.duration }}s</span>
</p>
<p>
<span class="item-label">{% trans 'Accounts amount' %}</span>:
<span>{{ summary.total_accounts }}</span>
</p>
<p>
<span class="item-label">{% trans 'Type count' %}</span>:
<span>{{ summary.total_types }}</span>
</p>
</div>
</div>
</div>
</main>
<div class="container-section collapsible-content" id="basic-info-content">
<div class="item">
<span class="item-label">{% trans 'Date start' %}</span>
<span class="item-value">{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Date end' %}</span>
<span class="item-value">{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Accounts amount' %}</span>
<span class="item-value">{{ summary.total_accounts }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Task name' %}</span>
<span class="item-value">{{ execution.automation.name }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Time using' %}</span>
<span class="item-value">{{ execution.duration }}s</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Type count' %}</span>
<span class="item-value">{{ summary.total_types }}</span>
</div>
</div>
</section>
</div>
<style>
{% include './css/report.css' %}
</style>
</style>
<script>
const toggleButtons = document.querySelectorAll('.collapse-toggle')
toggleButtons.forEach((button) => {
button.addEventListener('click', function () {
const targetId = this.getAttribute('data-target')
const targetContent = document.getElementById(`${targetId}-content`)
if (this.classList.contains('triangle-down-icon')) {
this.classList.remove('triangle-down-icon')
this.classList.add('triangle-right-icon')
targetContent.classList.add('collapsed')
} else {
this.classList.remove('triangle-right-icon')
this.classList.add('triangle-down-icon')
targetContent.classList.remove('collapsed')
}
})
})
</script>

View File

@ -4,124 +4,159 @@
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
<div class="report-container">
<header class="header">
{% autoescape off %}
{{ logo }}
{% endautoescape %}
</header>
<section class="basic-info-section">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="basic-info"
></span>
<h2>{% trans 'Basic Information' %}</h2>
</div>
<div class="container-section collapsible-content" id="basic-info-content">
<div class="item">
<span class="item-label">{% trans 'Date start' %}</span>
<span class="item-value">{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Date end' %}</span>
<span class="item-value">{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Assets amount' %}</span>
<span class="item-value">{{ summary.total_assets }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset success count' %}</span>
<span class="item-value">{{ summary.ok_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset failed count' %}</span>
<span class="item-value">{{ summary.fail_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset not support count' %}</span>
<span class="item-value">{{ summary.error_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Task name' %}</span>
<span class="item-value">{{ execution.automation.name }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Time using' %}</span>
<span class="item-value">{{ execution.duration }}s</span>
</div>
</div>
</section>
<div class="info-section">
<h2 class="info">
{% trans 'The following is a summary of account change secret tasks, please read and process' %}
</h2>
</div>
<main class="main-section">
<div class="synopsis-section">
<div class="synopsis-item">
<div class="synopsis-item-content">
<p>
<span class="item-label">{% trans 'Task name' %}</span>:
<span>{{ execution.automation.name }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date start' %}</span>:
<span>{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date end' %}</span>:
<span>{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Time using' %}</span>:
<span>{{ execution.duration }}s</span>
</p>
<p>
<span class="item-label">{% trans 'Assets amount' %}</span>:
<span>{{ summary.total_assets }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset success count' %}</span>:
<span>{{ summary.ok_assets | default:0 }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset failed count' %}</span>:
<span>{{ summary.fail_assets | default:0 }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset not support count' %}</span>:
<span>{{ summary.error_assets | default:0 }}</span>
</p>
</div>
</div>
<section class="success">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="success"
></span>
<h2>
{% trans 'Success accounts' %}:
<span> {{ summary.ok_accounts | default:0 }} </span>
</h2>
</div>
<div class="tabel-section tabel-summery-section">
<div class="new-accounts result-section table-responsive">
<div class="section-header">
<h3>
{% trans 'Success accounts' %}:
<span>{{ summary.ok_accounts | default:0 }}</span>
</h3>
</div>
{% if summary.ok_accounts %}
<table class="custom-table table-striped table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.ok_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
<div class="lost-accounts result-section table-responsive">
<div class="section-header">
<h3>
{% trans 'Failed accounts' %}:
<span>{{ summary.fail_accounts | default:0 }}</span>
</h3>
</div>
{% if summary.fail_accounts %}
<table class="custom-table table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.fail_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
<div class="container-section collapsible-content" id="success-content">
{% if summary.ok_accounts %}
<table class="custom-table table-striped table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.ok_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
</main>
</section>
<section class="failed">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="failed"
></span>
<h2>
{% trans 'Failed accounts' %}:
<span> {{ summary.fail_accounts | default:0 }} </span>
</h2>
</div>
<div class="container-section collapsible-content" id="failed-content">
{% if summary.fail_accounts %}
<table class="custom-table table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.fail_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
</section>
</div>
<style>
{% include './css/report.css' %}
</style>
</style>
<script>
const toggleButtons = document.querySelectorAll('.collapse-toggle')
toggleButtons.forEach((button) => {
button.addEventListener('click', function () {
const targetId = this.getAttribute('data-target')
const targetContent = document.getElementById(`${targetId}-content`)
if (this.classList.contains('triangle-down-icon')) {
this.classList.remove('triangle-down-icon')
this.classList.add('triangle-right-icon')
targetContent.classList.add('collapsed')
} else {
this.classList.remove('triangle-right-icon')
this.classList.add('triangle-down-icon')
targetContent.classList.remove('collapsed')
}
})
})
</script>

View File

@ -3,103 +3,132 @@
<div class="report-container">
<header class="header">
{% autoescape off %}
{{ logo }}
{% endautoescape %}
</header>
<section class="basic-info-section">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="basic-info"
></span>
<div class="info-section">
<h2 class="info">
{% trans 'The following is a summary of the account check tasks. Please review and handle them' %}
</h2>
</div>
<main class="main-section">
<div class="synopsis-section">
<div class="synopsis-item">
<div class="synopsis-item-content">
<p>
<span class="item-label">{% trans 'Task name' %}</span>:
<span>{{ execution.automation.name }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date start' %}</span>:
<span>{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date end' %}</span>:
<span>{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Time using' %}</span>:
<span>{{ execution.duration }}s</span>
</p>
<p>
<span class="item-label">{% trans 'Accounts amount' %}</span>:
<span>{{ summary.accounts }}</span>
</p>
<p>
<span class="item-label">{% trans 'Ok count' %}</span>:
<span>{{ summary.ok }}</span>
</p>
<p>
<span class="item-label">{% trans 'No password count' %}</span>:
<span>{{ summary.no_secret }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset success count' %}</span>:
<span>{{ summary.ok_assets | default:0 }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset failed count' %}</span>:
<span>{{ summary.fail_assets | default:0 }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset not support count' %}</span>:
<span>{{ summary.error_assets | default:0 }}</span>
</p>
</div>
</div>
<h2>{% trans 'Basic Information' %}</h2>
</div>
<div class="tabel-section tabel-summery-section">
<div class="new-accounts result-section table-responsive">
<div class="section-header">
<h3>
{% trans 'Weak password' %}:
<span>{{ summary.weak_password | default:0 }}</span>
</h3>
</div>
{% if summary.ok_accounts %}
<table class="custom-table table-striped table-hover data-table">
<thead>
<div class="container-section collapsible-content" id="basic-info-content">
<div class="item">
<span class="item-label">{% trans 'Date start' %}</span>
<span class="item-value">{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Date end' %}</span>
<span class="item-value">{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Accounts amount' %}</span>
<span class="item-value">{{ summary.accounts }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset success count' %}</span>
<span class="item-value">{{ summary.ok_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset failed count' %}</span>
<span class="item-value">{{ summary.fail_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset not support count' %}</span>
<span class="item-value">{{ summary.error_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Task name' %}</span>
<span class="item-value">{{ execution.automation.name }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Time using' %}</span>
<span class="item-value">{{ execution.duration }}s</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Ok count' %}</span>
<span class="item-value">{{ summary.ok }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'No password count' %}</span>
<span class="item-value">{{ summary.no_secret }}</span>
</div>
</div>
</section>
<section class="success">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="success"
></span>
<h2>
{% trans 'Weak password' %}:
<span> {{ summary.weak_password | default:0 }} </span>
</h2>
</div>
<div class="container-section collapsible-content" id="success-content">
{% if summary.ok_accounts %}
<table class="custom-table table-striped table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
<th>{% trans 'Result' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.weak_password %}
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
<th>{% trans 'Result' %}</th>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
<td style="color: red">{% trans 'Weak password' %}</td>
</tr>
</thead>
<tbody>
{% for account in result.weak_password %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
<td style="color: red">{% trans 'Weak password' %}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No weak password' %}</p>
{% endif %}
</div>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No weak password' %}</p>
{% endif %}
</div>
</main>
</section>
</div>
<style>
{% include './css/report.css' %}
</style>
</style>
<script>
const toggleButtons = document.querySelectorAll('.collapse-toggle')
toggleButtons.forEach((button) => {
button.addEventListener('click', function () {
const targetId = this.getAttribute('data-target')
const targetContent = document.getElementById(`${targetId}-content`)
if (this.classList.contains('triangle-down-icon')) {
this.classList.remove('triangle-down-icon')
this.classList.add('triangle-right-icon')
targetContent.classList.add('collapsed')
} else {
this.classList.remove('triangle-right-icon')
this.classList.add('triangle-down-icon')
targetContent.classList.remove('collapsed')
}
})
})
</script>

View File

@ -11,138 +11,115 @@ p {
.report-container {
display: flex;
flex-direction: column;
row-gap: 16px;
}
.report-container .header {
display: flex;
justify-content: space-between;
align-items: center;
height: 4rem;
padding: 0.3rem 1rem;
background-color: #148f76;
}
.report-container .header svg {
height: 100%
}
.info-section {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #f5f5f5;
height: 4rem;
padding: 0 1rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.info-section .info {
margin: unset;
font-size: 1.6rem;
}
.main-section {
margin-top: 3rem;
padding: 0 1rem;
}
.main-section .synopsis-section {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 2rem;
}
.main-section .synopsis-section .synopsis-item {
.basic-info-section,
.success,
.failed {
display: flex;
flex-direction: column;
flex: 1;
padding: 1rem 2rem;
border: 1px solid #e0e0e0;
border-radius: 8px;
height: 350px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.main-section .synopsis-section .synopsis-item h3 {
font-weight: 500;
font-size: 1.5rem;
}
.main-section .synopsis-section .synopsis-item .synopsis-item-content {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: flex-start;
height: 100%;
cursor: pointer;
padding: 16px 20px;
margin: 0 20px;
border: 1px solid #dee0e3;
border-radius: 6px;
background-color: #fff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
transition: all 0.2s ease;
}
.main-section .synopsis-section .synopsis-item .synopsis-item-content p {
display: inline-flex;
width: 100%;
line-height: 1;
gap: 2rem;
font-size: 14px;
}
.main-section .synopsis-section .synopsis-item .synopsis-item-content p .item-label {
width: 18rem;
}
.main-section .synopsis-section .synopsis-item .synopsis-item-content span {
.header-container {
display: flex;
justify-content: flex-start;
align-items: center;
justify-content: center;
height: 32px;
margin-bottom: 12px;
border-bottom: 1px solid #f0f0f0;
padding-bottom: 8px;
}
.header-container h2 {
color: #1f2329;
font: 500 16px/24px 'PingFang SC';
margin: 0;
display: flex;
align-items: center;
width: 100%;
}
.header-container h2 span {
display: inline-flex;
margin-left: 8px;
font-weight: normal;
}
.main-section .tabel-summery-section {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-items: flex-start;
gap: 2rem;
width: inherit;
margin-top: 2rem;
.triangle-right-icon {
display: inline-block;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 8px solid #1f2329;
margin-right: 10px;
cursor: pointer;
}
.main-section .tabel-summery-section .result-section {
.triangle-down-icon {
display: inline-block;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 8px solid #1f2329;
margin-right: 10px;
cursor: pointer;
}
.container-section {
display: flex;
flex-wrap: wrap;
width: 100%;
padding: 1rem;
background: #fff;
border: 1px solid #e0e0e0;
border-radius: 8px;
height: 100%;
row-gap: 16px;
column-gap: 10px;
}
.main-section .tabel-execution-section h3 {
font-size: 1.5rem;
color: #2c3e50;
.collapsible-content {
overflow: hidden;
max-height: 1000px;
opacity: 1;
transition: max-height 0.3s ease-in-out, opacity 0.3s ease-in-out;
}
.section-header {
padding-bottom: 0.5rem;
margin-bottom: 1rem;
font-size: 1.5rem;
}
.section-header h3 {
display: flex;
align-items: center;
gap: 0.5rem;
.collapsible-content.collapsed {
max-height: 0;
opacity: 0;
margin: 0;
color: #2c3e50;
font-size: inherit;
padding: 0;
}
.section-header span {
background: #e8f5e9;
color: #2e7d32;
padding: 0.2rem 0.8rem;
border-radius: 1rem;
font-size: inherit;
.container-section .item {
display: flex;
flex-basis: calc(33.33% - 10px);
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 4px;
padding: 4px 0;
}
.container-section .item .item-label {
color: #646a73;
font: 400 14px/22px 'PingFang SC';
}
.container-section .item .item-value {
color: #1f2329;
font: 500 14px/22px 'PingFang SC';
}
.custom-table {
margin-bottom: 0;
width: 100%;
@ -151,17 +128,19 @@ p {
}
.custom-table th {
background: #f6f6f6;
color: #495057;
padding: 0.75rem;
font-size: 1.5rem;
border-bottom: 2px solid #e0e0e0;
background-color: #f5f7fa;
color: #646A73;
font: 500 14px/22px 'PingFang SC';
text-align: left;
padding: 12px 8px;
border-bottom: 1px solid #ebeef5;
}
.custom-table td {
padding: 0.75rem;
font-size: 14px;
border-bottom: 1px solid #e0e0e0;
color: #1F2329;
font: 400 14px/22px 'PingFang SC';
padding: 12px 8px;
border-bottom: 1px solid #ebeef5;
}
.custom-table tr:nth-child(even) {
@ -173,13 +152,15 @@ p {
}
.no-data {
color: #909399;
font: 400 14px/22px 'PingFang SC';
text-align: center;
color: #6c757d;
padding: 2rem;
background: #f6f6f6;
border-radius: 8px;
margin: 1rem 0;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
padding: 20px;
font-style: italic;
background-color: #f9f9f9;
border-radius: 4px;
margin: 10px 0;
width: 100%;
}
.new-accounts .section-header span {

View File

@ -1,127 +1,161 @@
{% load i18n %}
{% load static %}
{% load i18n %} {% load static %}
<div class="report-container">
<header class="header">
{% autoescape off %}
{{ logo }}
{% endautoescape %}
</header>
<section class="basic-info-section">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="basic-info"
></span>
<div class="info-section">
<h2 class="info">
{% trans 'The following is a summary of the account check tasks. Please review and handle them' %}
</h2>
<h2>{% trans 'Basic Information' %}</h2>
</div>
<main class="main-section">
<div class="synopsis-section">
<div class="synopsis-item">
<div class="synopsis-item-content">
<p>
<span class="item-label">{% trans 'Task name' %}</span>:
<span>{{ execution.automation.name }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date start' %}</span>:
<span>{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date end' %}</span>:
<span>{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Time using' %}</span>:
<span>{{ execution.duration }}s</span>
</p>
<p>
<span class="item-label">{% trans 'Assets amount' %}</span>:
<span>{{ summary.total_assets }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset success count' %}</span>:
<span>{{ summary.ok_assets | default:0 }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset failed count' %}</span>:
<span>{{ summary.fail_assets | default:0 }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset not support count' %}</span>:
<span>{{ summary.error_assets | default:0 }}</span>
</p>
</div>
</div>
</div>
<div class="container-section collapsible-content" id="basic-info-content">
<div class="item">
<span class="item-label">{% trans 'Date start' %}</span>
<span class="item-value">{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="tabel-section tabel-summery-section">
<div class="new-accounts result-section table-responsive">
<div class="section-header">
<h3>
{% trans 'New found accounts' %}:
<span>{{ summary.new_accounts | default:0 }}</span>
</h3>
</div>
{% if summary.new_accounts %}
<table class="custom-table table-striped table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.new_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
<div class="item">
<span class="item-label">{% trans 'Date end' %}</span>
<span class="item-value">{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="lost-accounts result-section table-responsive">
<div class="section-header">
<h3>
{% trans 'Lost accounts' %}:
<span>{{ summary.lost_accounts | default:0 }}</span>
</h3>
</div>
<div class="item">
<span class="item-label">{% trans 'Assets amount' %}</span>
<span class="item-value">{{ summary.total_assets }}</span>
</div>
{% if summary.lost_accounts %}
<table class="custom-table table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.lost_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
</div>
</main>
<div class="item">
<span class="item-label">{% trans 'Asset success count' %}</span>
<span class="item-value">{{ summary.ok_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset failed count' %}</span>
<span class="item-value">{{ summary.fail_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset not support count' %}</span>
<span class="item-value">{{ summary.error_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Task name' %}</span>
<span class="item-value">{{ execution.automation.name }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Time using' %}</span>
<span class="item-value">{{ execution.duration }}s</span>
</div>
</div>
</section>
<section class="success">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="success"
></span>
<h2>
{% trans 'New found accounts' %}:
<span> {{ summary.new_accounts | default:0 }} </span>
</h2>
</div>
<div class="container-section collapsible-content" id="success-content">
{% if summary.new_accounts %}
<table class="custom-table table-striped table-hover data-table">
<thead>
<tr>
<th width="10%">No.</th>
<th width="45%">{% trans 'Asset' %}</th>
<th width="45%">{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.new_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
</section>
<section class="failed">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="failed"
></span>
<h2>
{% trans 'Lost accounts' %}:
<span> {{ summary.lost_accounts | default:0 }} </span>
</h2>
</div>
<div class="container-section collapsible-content" id="failed-content">
{% if summary.lost_accounts %}
<table class="custom-table table-hover data-table">
<thead>
<tr>
<th width="10%">No.</th>
<th width="45%">{% trans 'Asset' %}</th>
<th width="45%">{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.lost_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
</section>
</div>
<style>
{% include './css/report.css' %}
{% include './css/report.css' %}
</style>
<script>
const toggleButtons = document.querySelectorAll('.collapse-toggle')
toggleButtons.forEach((button) => {
button.addEventListener('click', function () {
const targetId = this.getAttribute('data-target')
const targetContent = document.getElementById(`${targetId}-content`)
if (this.classList.contains('triangle-down-icon')) {
this.classList.remove('triangle-down-icon')
this.classList.add('triangle-right-icon')
targetContent.classList.add('collapsed')
} else {
this.classList.remove('triangle-right-icon')
this.classList.add('triangle-down-icon')
targetContent.classList.remove('collapsed')
}
})
})
</script>

View File

@ -4,125 +4,161 @@
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
<div class="report-container">
<header class="header">
{% autoescape off %}
{{ logo }}
{% endautoescape %}
</header>
<section class="basic-info-section">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="basic-info"
></span>
<h2>{% trans 'Basic Information' %}</h2>
</div>
<div class="container-section collapsible-content" id="basic-info-content">
<div class="item">
<span class="item-label">{% trans 'Date start' %}</span>
<span class="item-value">{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Date end' %}</span>
<span class="item-value">{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Assets amount' %}</span>
<span class="item-value">{{ summary.total_assets }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset success count' %}</span>
<span class="item-value">{{ summary.ok_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset failed count' %}</span>
<span class="item-value">{{ summary.fail_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Asset not support count' %}</span>
<span class="item-value">{{ summary.error_assets | default:0 }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Task name' %}</span>
<span class="item-value">{{ execution.automation.name }}</span>
</div>
<div class="item">
<span class="item-label">{% trans 'Time using' %}</span>
<span class="item-value">{{ execution.duration }}s</span>
</div>
</div>
</section>
<div class="info-section">
<h2 class="info">
{% trans 'The following is a summary of account push tasks, please read and process' %}
</h2>
</div>
<main class="main-section">
<div class="synopsis-section">
<div class="synopsis-item">
<div class="synopsis-item-content">
<p>
<span class="item-label">{% trans 'Task name' %}</span>:
<span>{{ execution.automation.name }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date start' %}</span>:
<span>{{ execution.date_start | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Date end' %}</span>:
<span>{{ execution.date_finished | date:"Y/m/d H:i:s" }}</span>
</p>
<p>
<span class="item-label">{% trans 'Time using' %}</span>:
<span>{{ execution.duration }}s</span>
</p>
<p>
<span class="item-label">{% trans 'Assets amount' %}</span>:
<span>{{ summary.total_assets }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset success count' %}</span>:
<span>{{ summary.ok_assets | default:0 }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset failed count' %}</span>:
<span>{{ summary.fail_assets | default:0 }}</span>
</p>
<p>
<span class="item-label">{% trans 'Asset not support count' %}</span>:
<span>{{ summary.error_assets | default:0 }}</span>
</p>
</div>
</div>
<section class="success">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="success"
></span>
<h2>
{% trans 'Success accounts' %}:
<span> {{ summary.ok_accounts | default:0 }} </span>
</h2>
</div>
<div class="tabel-section tabel-summery-section">
<div class="new-accounts result-section table-responsive">
<div class="section-header">
<h3>
{% trans 'Success accounts' %}:
<span>{{ summary.ok_accounts | default:0 }}</span>
</h3>
</div>
{% if summary.ok_accounts %}
<table class="custom-table table-striped table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.ok_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
<div class="lost-accounts result-section table-responsive">
<div class="section-header">
<h3>
{% trans 'Failed accounts' %}:
<span>{{ summary.fail_accounts | default:0 }}</span>
</h3>
</div>
{% if summary.fail_accounts %}
<table class="custom-table table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.fail_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
<div class="container-section collapsible-content" id="success-content">
{% if summary.ok_accounts %}
<table class="custom-table table-striped table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.ok_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
</main>
</section>
<section class="failed">
<div class="header-container">
<span
class="triangle-down-icon collapse-toggle"
data-target="failed"
></span>
<h2>
{% trans 'Failed accounts' %}:
<span> {{ summary.fail_accounts | default:0 }} </span>
</h2>
</div>
<div class="container-section collapsible-content" id="failed-content">
{% if summary.fail_accounts %}
<table class="custom-table table-hover data-table">
<thead>
<tr>
<th>{% trans 'No' %}</th>
<th>{% trans 'Asset' %}</th>
<th>{% trans 'Username' %}</th>
</tr>
</thead>
<tbody>
{% for account in result.fail_accounts %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ account.asset }}</td>
<td>{{ account.username }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="no-data">{% trans 'No new accounts found' %}</p>
{% endif %}
</div>
</section>
</div>
<style>
{% include './css/report.css' %}
</style>
<script>
const toggleButtons = document.querySelectorAll('.collapse-toggle')
toggleButtons.forEach((button) => {
button.addEventListener('click', function () {
const targetId = this.getAttribute('data-target')
const targetContent = document.getElementById(`${targetId}-content`)
if (this.classList.contains('triangle-down-icon')) {
this.classList.remove('triangle-down-icon')
this.classList.add('triangle-right-icon')
targetContent.classList.add('collapsed')
} else {
this.classList.remove('triangle-right-icon')
this.classList.add('triangle-down-icon')
targetContent.classList.remove('collapsed')
}
})
})
</script>

View File

@ -105,10 +105,16 @@ class BaseManager:
return self.execution.all_assets_group_by_platform()
def pre_run(self):
self.execution.date_start = timezone.now()
date_start = timezone.now()
self.execution.date_start = date_start
self.execution.status = Status.running
self.execution.save(update_fields=["date_start", "status"])
automation = self.execution.automation
if automation:
automation.last_execution_date = date_start
automation.save(update_fields=['last_execution_date'])
def update_execution(self):
self.duration = int(time.time() - self.time_start)
self.execution.date_finished = timezone.now()
@ -340,6 +346,7 @@ class PlaybookPrepareMixin:
if not platform.automation or not platform.automation.ansible_enabled:
print(_(" - Platform {} ansible disabled").format(platform.name))
self.on_assets_not_ansible_enabled(assets)
return False
automation = platform.automation

View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.13 on 2025-03-05 08:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assets', '0012_auto_20241204_1516'),
]
operations = [
migrations.AddField(
model_name='baseautomation',
name='last_execution_date',
field=models.DateTimeField(blank=True, null=True, verbose_name='Last execution date'),
),
]

View File

@ -27,6 +27,9 @@ class BaseAutomation(PeriodTaskModelMixin, JMSOrgBaseModel):
type = models.CharField(max_length=16, verbose_name=_("Type"))
is_active = models.BooleanField(default=True, verbose_name=_("Is active"))
params = models.JSONField(default=dict, verbose_name=_("Parameters"))
last_execution_date = models.DateTimeField(
null=True, blank=True, verbose_name=_('Last execution date')
)
objects = BaseAutomationManager.from_queryset(models.QuerySet)()

View File

@ -23,7 +23,7 @@ class BaseAutomationSerializer(PeriodTaskSerializerMixin, BulkOrgResourceModelSe
class Meta:
read_only_fields = [
'date_created', 'date_updated', 'created_by',
'periodic_display', 'executed_amount', 'type'
'periodic_display', 'executed_amount', 'type', 'last_execution_date'
]
mini_fields = [
'id', 'name', 'type', 'is_periodic', 'interval',
@ -43,6 +43,7 @@ class AutomationExecutionSerializer(serializers.ModelSerializer):
snapshot = serializers.SerializerMethodField(label=_('Automation snapshot'))
trigger = LabeledChoiceField(choices=Trigger.choices, read_only=True, label=_("Trigger mode"))
status = LabeledChoiceField(choices=Status.choices, read_only=True, label=_('Status'))
automation = ObjectRelatedField(required=False, queryset=BaseAutomation.objects, attrs=('id', 'name'))
class Meta:
model = AutomationExecution

View File

@ -25,7 +25,6 @@ from common.storage.ftp_file import FTPFileStorageHandler
from common.utils import is_uuid, get_logger, lazyproperty
from ops.const import Types
from ops.models import Job
from ops.serializers.job import JobSerializer
from orgs.mixins.api import OrgReadonlyModelViewSet, OrgModelViewSet
from orgs.models import Organization
from orgs.utils import current_org, tmp_to_root_org
@ -168,7 +167,7 @@ class UserLoginLogViewSet(UserLoginCommonMixin, OrgReadonlyModelViewSet):
def get_queryset(self):
queryset = super().get_queryset()
if current_org.is_root():
if current_org.is_root() or not settings.XPACK_ENABLED:
return queryset
users = self.get_org_member_usernames()
queryset = queryset.filter(username__in=users)

View File

@ -61,8 +61,7 @@ class UserMixin:
logger.debug(log_prompt.format("user: {}|created: {}".format(user, created)))
logger.debug(log_prompt.format("Send signal => openid create or update user"))
openid_create_or_update_user.send(
sender=self.__class__, request=request, user=user,
created=created, attrs=user_attrs,
sender=self.__class__, user=user, created=created, attrs=user_attrs,
)
return user, created

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-28 18:37+0800\n"
"POT-Creation-Date: 2025-03-07 15:03+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"
@ -24,7 +24,7 @@ msgstr ""
msgid "Account already exists"
msgstr ""
#: accounts/api/account/application.py:77
#: accounts/api/account/application.py:78
#: authentication/api/connection_token.py:449
msgid "Account not found"
msgstr ""
@ -48,8 +48,8 @@ msgstr ""
#: accounts/automations/backup_account/handlers.py:168
#: accounts/automations/backup_account/manager.py:26
#: accounts/automations/change_secret/manager.py:95
#: accounts/automations/push_account/manager.py:59
#: assets/models/automations/base.py:142 ops/serializers/job.py:71
#: accounts/automations/push_account/manager.py:61
#: assets/models/automations/base.py:145 ops/serializers/job.py:71
#: ops/serializers/job.py:95
#: settings/templates/ldap/_msg_import_ldap_user.html:7
#: terminal/serializers/session.py:49
@ -60,23 +60,27 @@ msgstr ""
msgid "Backup file creation completed"
msgstr ""
#: accounts/automations/backup_account/handlers.py:203
#: accounts/automations/backup_account/handlers.py:177
msgid "Start sending backup emails"
msgstr ""
#: accounts/automations/backup_account/handlers.py:204
msgid "Encrypting files using encryption password"
msgstr ""
#: accounts/automations/backup_account/handlers.py:213
#: accounts/automations/backup_account/handlers.py:214
msgid "The backup file will be sent to"
msgstr ""
#: accounts/automations/backup_account/handlers.py:236
#: accounts/automations/backup_account/handlers.py:237
msgid "The backup task has no assigned sftp server"
msgstr ""
#: accounts/automations/backup_account/handlers.py:257
#: accounts/automations/backup_account/handlers.py:258
msgid "The backup task has no assigned recipient"
msgstr ""
#: accounts/automations/backup_account/handlers.py:280
#: accounts/automations/backup_account/handlers.py:281
msgid "Plan start"
msgstr ""
@ -86,11 +90,11 @@ msgstr ""
#: accounts/automations/backup_account/manager.py:24
#: accounts/automations/change_secret/manager.py:93
#: accounts/automations/push_account/manager.py:57
#: accounts/automations/push_account/manager.py:59
msgid "Plan execution end"
msgstr ""
#: accounts/automations/base/manager.py:106
#: accounts/automations/base/manager.py:109
msgid "No pending accounts found"
msgstr ""
@ -99,6 +103,10 @@ msgstr ""
msgid "Success: %s, Failed: %s, Total: %s"
msgstr ""
#: accounts/automations/push_account/manager.py:31
msgid "Secret cannot be empty"
msgstr ""
#: accounts/automations/verify_gateway_account/manager.py:18
msgid ">>> Start executing the task to test gateway account connectivity"
msgstr ""
@ -423,13 +431,13 @@ msgstr ""
#: accounts/serializers/automations/gather_account.py:47
#: accounts/templates/accounts/asset_account_change_info.html:7
#: accounts/templates/accounts/change_secret_failed_info.html:11
#: accounts/templates/accounts/change_secret_report.html:70
#: accounts/templates/accounts/change_secret_report.html:102
#: accounts/templates/accounts/check_account_report.html:78
#: accounts/templates/accounts/change_secret_report.html:72
#: accounts/templates/accounts/change_secret_report.html:104
#: accounts/templates/accounts/check_account_report.html:79
#: accounts/templates/accounts/gather_account_report.html:71
#: accounts/templates/accounts/gather_account_report.html:103
#: accounts/templates/accounts/push_account_report.html:70
#: accounts/templates/accounts/push_account_report.html:102
#: accounts/templates/accounts/push_account_report.html:72
#: accounts/templates/accounts/push_account_report.html:104
#: acls/serializers/base.py:130 assets/models/asset/common.py:102
#: assets/models/asset/common.py:366 assets/models/cmd_filter.py:36
#: audits/models.py:59 audits/models.py:312 audits/serializers.py:228
@ -492,7 +500,7 @@ msgstr ""
#: accounts/models/account.py:85
#: accounts/models/automations/check_account.py:67
#: accounts/serializers/account/service.py:10
#: accounts/serializers/account/service.py:11
#: accounts/serializers/automations/change_secret.py:115
#: accounts/serializers/automations/change_secret.py:146
#: accounts/templates/accounts/change_secret_failed_info.html:12
@ -536,7 +544,7 @@ msgstr ""
#: accounts/models/application.py:16
#: accounts/models/automations/check_account.py:119 accounts/models/base.py:63
#: accounts/serializers/account/service.py:26
#: accounts/serializers/account/service.py:27
#: accounts/serializers/account/virtual.py:20 acls/models/base.py:35
#: acls/models/base.py:96 acls/models/command_acl.py:21
#: acls/serializers/base.py:35 assets/models/asset/common.py:100
@ -704,7 +712,7 @@ msgstr ""
msgid "Check connection after change"
msgstr ""
#: accounts/models/automations/change_secret.py:16
#: accounts/models/automations/change_secret.py:17
#: accounts/models/automations/check_account.py:19
#: accounts/models/automations/gather_account.py:92
#: accounts/serializers/automations/change_secret.py:59
@ -713,22 +721,22 @@ msgstr ""
msgid "Recipient"
msgstr "Recipients"
#: accounts/models/automations/change_secret.py:23
#: accounts/models/automations/change_secret.py:24
msgid "Change secret automation"
msgstr ""
#: accounts/models/automations/change_secret.py:46
#: assets/models/automations/base.py:141 ops/models/base.py:56
#: accounts/models/automations/change_secret.py:47
#: assets/models/automations/base.py:144 ops/models/base.py:56
#: ops/models/celery.py:90 ops/models/job.py:240
#: terminal/models/applet/host.py:142
msgid "Date finished"
msgstr ""
#: accounts/models/automations/change_secret.py:48
#: accounts/models/automations/change_secret.py:49
#: accounts/models/automations/check_account.py:75
#: accounts/models/automations/gather_account.py:25
#: accounts/serializers/automations/check_account.py:39
#: assets/models/automations/base.py:133
#: assets/models/automations/base.py:136
#: assets/serializers/automations/base.py:45 audits/models.py:209
#: audits/serializers.py:78 ops/models/base.py:49 ops/models/job.py:231
#: terminal/models/applet/applet.py:331 terminal/models/applet/host.py:140
@ -742,7 +750,7 @@ msgstr ""
msgid "Status"
msgstr ""
#: accounts/models/automations/change_secret.py:50
#: accounts/models/automations/change_secret.py:51
#: accounts/serializers/account/account.py:276
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
@ -753,19 +761,19 @@ msgstr ""
msgid "Error"
msgstr ""
#: accounts/models/automations/change_secret.py:66
#: accounts/models/automations/change_secret.py:73
msgid "Old secret"
msgstr ""
#: accounts/models/automations/change_secret.py:67
#: accounts/models/automations/change_secret.py:74
msgid "New secret"
msgstr ""
#: accounts/models/automations/change_secret.py:68
#: accounts/models/automations/change_secret.py:75
msgid "Ignore fail"
msgstr ""
#: accounts/models/automations/change_secret.py:71
#: accounts/models/automations/change_secret.py:78
msgid "Change secret record"
msgstr ""
@ -819,8 +827,8 @@ msgid "Long time no change"
msgstr ""
#: accounts/models/automations/check_account.py:52
#: accounts/templates/accounts/check_account_report.html:69
#: accounts/templates/accounts/check_account_report.html:89
#: accounts/templates/accounts/check_account_report.html:70
#: accounts/templates/accounts/check_account_report.html:90
msgid "Weak password"
msgstr ""
@ -847,13 +855,13 @@ msgstr ""
#: accounts/models/automations/check_account.py:64
#: accounts/models/automations/gather_account.py:17 accounts/models/base.py:64
#: accounts/serializers/account/virtual.py:21
#: accounts/templates/accounts/change_secret_report.html:71
#: accounts/templates/accounts/change_secret_report.html:103
#: accounts/templates/accounts/check_account_report.html:79
#: accounts/templates/accounts/change_secret_report.html:73
#: accounts/templates/accounts/change_secret_report.html:105
#: accounts/templates/accounts/check_account_report.html:80
#: accounts/templates/accounts/gather_account_report.html:72
#: accounts/templates/accounts/gather_account_report.html:104
#: accounts/templates/accounts/push_account_report.html:71
#: accounts/templates/accounts/push_account_report.html:103
#: accounts/templates/accounts/push_account_report.html:73
#: accounts/templates/accounts/push_account_report.html:105
#: acls/serializers/base.py:19 acls/serializers/base.py:50 audits/models.py:189
#: authentication/forms.py:21 authentication/forms.py:23
#: authentication/models/temp_token.py:9
@ -1260,12 +1268,12 @@ msgid ""
"accounts, use the format username@domain."
msgstr ""
#: accounts/serializers/account/service.py:12
#: accounts/serializers/account/service.py:13
#: authentication/serializers/token.py:22
msgid "Access IP"
msgstr ""
#: accounts/serializers/account/service.py:25
#: accounts/serializers/account/service.py:26
#: accounts/serializers/account/virtual.py:19 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 common/db/models.py:36 ops/models/adhoc.py:25
#: ops/models/job.py:163 ops/models/playbook.py:31 rbac/models/role.py:37
@ -1280,9 +1288,9 @@ msgstr ""
msgid "Comment"
msgstr "Description"
#: accounts/serializers/account/service.py:27
#: accounts/templates/accounts/backup_account_report.html:38
#: accounts/templates/accounts/check_account_report.html:38
#: accounts/serializers/account/service.py:28
#: accounts/templates/accounts/backup_account_report.html:39
#: accounts/templates/accounts/check_account_report.html:39
#: assets/serializers/asset/common.py:151
msgid "Accounts amount"
msgstr ""
@ -1367,7 +1375,7 @@ msgid "Name already exists"
msgstr ""
#: accounts/serializers/automations/base.py:31
#: assets/models/automations/base.py:144
#: assets/models/automations/base.py:147
#: assets/serializers/automations/base.py:43
msgid "Automation snapshot"
msgstr ""
@ -1395,7 +1403,7 @@ msgid "* Please enter the correct password length"
msgstr ""
#: accounts/serializers/automations/change_secret.py:90
msgid "* Password length range 6-30 bits"
msgid "* Password length range 8-36 bits"
msgstr ""
#: accounts/serializers/automations/change_secret.py:112
@ -1405,7 +1413,7 @@ msgid "Is success"
msgstr "Is success"
#: accounts/serializers/automations/change_secret.py:119
#: assets/models/automations/base.py:160
#: assets/models/automations/base.py:163
msgid "Automation task execution"
msgstr ""
@ -1554,28 +1562,28 @@ msgstr ""
msgid "Deleted account"
msgstr ""
#: accounts/templates/accounts/backup_account_report.html:13
#: accounts/templates/accounts/backup_account_report.html:14
msgid ""
"The following is a summary of account backup tasks, please review and handle "
"them"
msgstr ""
#: accounts/templates/accounts/backup_account_report.html:22
#: accounts/templates/accounts/backup_account_report.html:23
#: accounts/templates/accounts/change_secret_failed_info.html:3
#: accounts/templates/accounts/change_secret_report.html:22
#: accounts/templates/accounts/check_account_report.html:22
#: accounts/templates/accounts/change_secret_report.html:24
#: accounts/templates/accounts/check_account_report.html:23
#: accounts/templates/accounts/gather_account_report.html:23
#: accounts/templates/accounts/push_account_report.html:22
#: accounts/templates/accounts/push_account_report.html:24
#: terminal/serializers/task.py:10
msgid "Task name"
msgstr ""
#: accounts/templates/accounts/backup_account_report.html:26
#: accounts/templates/accounts/change_secret_report.html:26
#: accounts/templates/accounts/check_account_report.html:26
#: accounts/templates/accounts/backup_account_report.html:27
#: accounts/templates/accounts/change_secret_report.html:28
#: accounts/templates/accounts/check_account_report.html:27
#: accounts/templates/accounts/gather_account_report.html:27
#: accounts/templates/accounts/push_account_report.html:26
#: assets/models/automations/base.py:139 audits/models.py:66
#: accounts/templates/accounts/push_account_report.html:28
#: assets/models/automations/base.py:142 audits/models.py:66
#: ops/models/base.py:55 ops/models/celery.py:89 ops/models/job.py:239
#: ops/templates/ops/celery_task_log.html:101
#: perms/models/asset_permission.py:78 settings/serializers/feature.py:27
@ -1586,26 +1594,26 @@ msgstr ""
msgid "Date start"
msgstr ""
#: accounts/templates/accounts/backup_account_report.html:30
#: accounts/templates/accounts/change_secret_report.html:30
#: accounts/templates/accounts/check_account_report.html:30
#: accounts/templates/accounts/backup_account_report.html:31
#: accounts/templates/accounts/change_secret_report.html:32
#: accounts/templates/accounts/check_account_report.html:31
#: accounts/templates/accounts/gather_account_report.html:31
#: accounts/templates/accounts/push_account_report.html:30
#: accounts/templates/accounts/push_account_report.html:32
#: settings/serializers/feature.py:28
#: settings/templates/ldap/_msg_import_ldap_user.html:6
#: terminal/models/session/session.py:48
msgid "Date end"
msgstr ""
#: accounts/templates/accounts/backup_account_report.html:34
#: accounts/templates/accounts/change_secret_report.html:34
#: accounts/templates/accounts/check_account_report.html:34
#: accounts/templates/accounts/backup_account_report.html:35
#: accounts/templates/accounts/change_secret_report.html:36
#: accounts/templates/accounts/check_account_report.html:35
#: accounts/templates/accounts/gather_account_report.html:35
#: accounts/templates/accounts/push_account_report.html:34
#: accounts/templates/accounts/push_account_report.html:36
msgid "Time using"
msgstr ""
#: accounts/templates/accounts/backup_account_report.html:42
#: accounts/templates/accounts/backup_account_report.html:43
msgid "Type count"
msgstr ""
@ -1623,93 +1631,93 @@ msgid ""
"or pushing the account. Please check and handle it in time."
msgstr ""
#: accounts/templates/accounts/change_secret_report.html:13
#: accounts/templates/accounts/change_secret_report.html:15
msgid ""
"The following is a summary of account change secret tasks, please read and "
"process"
msgstr ""
#: accounts/templates/accounts/change_secret_report.html:38
#: accounts/templates/accounts/change_secret_report.html:40
#: accounts/templates/accounts/gather_account_report.html:39
#: accounts/templates/accounts/push_account_report.html:38
#: accounts/templates/accounts/push_account_report.html:40
#: assets/serializers/domain.py:24 assets/serializers/platform.py:182
#: orgs/serializers.py:13 perms/serializers/permission.py:50
msgid "Assets amount"
msgstr ""
#: accounts/templates/accounts/change_secret_report.html:42
#: accounts/templates/accounts/check_account_report.html:50
#: accounts/templates/accounts/change_secret_report.html:44
#: accounts/templates/accounts/check_account_report.html:51
#: accounts/templates/accounts/gather_account_report.html:43
#: accounts/templates/accounts/push_account_report.html:42
#: accounts/templates/accounts/push_account_report.html:44
msgid "Asset success count"
msgstr ""
#: accounts/templates/accounts/change_secret_report.html:46
#: accounts/templates/accounts/check_account_report.html:54
#: accounts/templates/accounts/change_secret_report.html:48
#: accounts/templates/accounts/check_account_report.html:55
#: accounts/templates/accounts/gather_account_report.html:47
#: accounts/templates/accounts/push_account_report.html:46
#: accounts/templates/accounts/push_account_report.html:48
msgid "Asset failed count"
msgstr ""
#: accounts/templates/accounts/change_secret_report.html:50
#: accounts/templates/accounts/check_account_report.html:58
#: accounts/templates/accounts/change_secret_report.html:52
#: accounts/templates/accounts/check_account_report.html:59
#: accounts/templates/accounts/gather_account_report.html:51
#: accounts/templates/accounts/push_account_report.html:50
#: accounts/templates/accounts/push_account_report.html:52
msgid "Asset not support count"
msgstr ""
#: accounts/templates/accounts/change_secret_report.html:61
#: accounts/templates/accounts/push_account_report.html:61
#: accounts/templates/accounts/change_secret_report.html:63
#: accounts/templates/accounts/push_account_report.html:63
msgid "Success accounts"
msgstr ""
#: accounts/templates/accounts/change_secret_report.html:69
#: accounts/templates/accounts/change_secret_report.html:101
#: accounts/templates/accounts/check_account_report.html:77
#: accounts/templates/accounts/change_secret_report.html:71
#: accounts/templates/accounts/change_secret_report.html:103
#: accounts/templates/accounts/check_account_report.html:78
#: accounts/templates/accounts/gather_account_report.html:70
#: accounts/templates/accounts/gather_account_report.html:102
#: accounts/templates/accounts/push_account_report.html:69
#: accounts/templates/accounts/push_account_report.html:101
#: accounts/templates/accounts/push_account_report.html:71
#: accounts/templates/accounts/push_account_report.html:103
#: audits/handler.py:128
msgid "No"
msgstr ""
#: accounts/templates/accounts/change_secret_report.html:85
#: accounts/templates/accounts/change_secret_report.html:117
#: accounts/templates/accounts/change_secret_report.html:87
#: accounts/templates/accounts/change_secret_report.html:119
#: accounts/templates/accounts/gather_account_report.html:86
#: accounts/templates/accounts/gather_account_report.html:118
#: accounts/templates/accounts/push_account_report.html:85
#: accounts/templates/accounts/push_account_report.html:117
#: accounts/templates/accounts/push_account_report.html:87
#: accounts/templates/accounts/push_account_report.html:119
msgid "No new accounts found"
msgstr ""
#: accounts/templates/accounts/change_secret_report.html:92
#: accounts/templates/accounts/push_account_report.html:92
#: accounts/templates/accounts/change_secret_report.html:94
#: accounts/templates/accounts/push_account_report.html:94
msgid "Failed accounts"
msgstr ""
#: accounts/templates/accounts/check_account_report.html:13
#: accounts/templates/accounts/check_account_report.html:14
#: accounts/templates/accounts/gather_account_report.html:14
msgid ""
"The following is a summary of the account check tasks. Please review and "
"handle them"
msgstr ""
#: accounts/templates/accounts/check_account_report.html:42
#: accounts/templates/accounts/check_account_report.html:43
msgid "Ok count"
msgstr ""
#: accounts/templates/accounts/check_account_report.html:46
#: accounts/templates/accounts/check_account_report.html:47
msgid "No password count"
msgstr ""
#: accounts/templates/accounts/check_account_report.html:80
#: assets/models/automations/base.py:153 ops/models/base.py:51
#: accounts/templates/accounts/check_account_report.html:81
#: assets/models/automations/base.py:156 ops/models/base.py:51
#: ops/models/job.py:235 xpack/plugins/cloud/models.py:225
msgid "Result"
msgstr ""
#: accounts/templates/accounts/check_account_report.html:95
#: accounts/templates/accounts/check_account_report.html:96
msgid "No weak password"
msgstr ""
@ -1721,7 +1729,7 @@ msgstr ""
msgid "Lost accounts"
msgstr ""
#: accounts/templates/accounts/push_account_report.html:13
#: accounts/templates/accounts/push_account_report.html:15
msgid ""
"The following is a summary of account push tasks, please read and process"
msgstr ""
@ -2022,28 +2030,28 @@ msgstr ""
msgid "App Assets"
msgstr "Assets"
#: assets/automations/base/manager.py:332
#: assets/automations/base/manager.py:347
msgid " - Platform {} ansible disabled"
msgstr ""
#: assets/automations/base/manager.py:514
#: assets/automations/base/manager.py:530
msgid ">>> Task preparation phase"
msgstr ""
#: assets/automations/base/manager.py:518
#: assets/automations/base/manager.py:534
#, python-brace-format
msgid ">>> Executing tasks in batches, total {runner_count}"
msgstr ""
#: assets/automations/base/manager.py:523
#: assets/automations/base/manager.py:539
msgid ">>> Start executing tasks"
msgstr ""
#: assets/automations/base/manager.py:525
#: assets/automations/base/manager.py:541
msgid ">>> No tasks need to be executed"
msgstr ""
#: assets/automations/base/manager.py:529
#: assets/automations/base/manager.py:545
#, python-brace-format
msgid ">>> Begin executing batch {index} of tasks"
msgstr ""
@ -2468,27 +2476,31 @@ msgstr ""
msgid "Parameters"
msgstr ""
#: assets/models/automations/base.py:41 assets/models/automations/base.py:128
#: assets/models/automations/base.py:31
msgid "Last execution date"
msgstr ""
#: assets/models/automations/base.py:44 assets/models/automations/base.py:131
msgid "Automation task"
msgstr ""
#: assets/models/automations/base.py:119
#: assets/models/automations/base.py:122
msgid "Asset automation task"
msgstr ""
#: assets/models/automations/base.py:136 assets/models/cmd_filter.py:41
#: assets/models/automations/base.py:139 assets/models/cmd_filter.py:41
#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:238
#: users/models/user/__init__.py:322
msgid "Date created"
msgstr ""
#: assets/models/automations/base.py:150
#: assets/models/automations/base.py:153
#: assets/serializers/automations/base.py:44 xpack/plugins/cloud/models.py:242
#: xpack/plugins/cloud/serializers/task.py:249
msgid "Trigger mode"
msgstr ""
#: assets/models/automations/base.py:152 audits/serializers.py:39
#: assets/models/automations/base.py:155 audits/serializers.py:39
#: ops/models/base.py:52 ops/models/job.py:236
#: xpack/plugins/cloud/manager.py:103
msgid "Summary"
@ -6874,7 +6886,7 @@ msgid "User first login update profile done redirect to it"
msgstr ""
#: settings/serializers/basic.py:22
msgid "Global organization"
msgid "Global org display"
msgstr ""
#: settings/serializers/basic.py:23

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-28 18:37+0800\n"
"POT-Creation-Date: 2025-03-07 15:03+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"
@ -24,7 +24,7 @@ msgstr ""
msgid "Account already exists"
msgstr "アカウントはすでに存在しています"
#: accounts/api/account/application.py:77
#: accounts/api/account/application.py:78
#: authentication/api/connection_token.py:449
msgid "Account not found"
msgstr "アカウントが見つかりません"
@ -48,8 +48,8 @@ msgstr "資産関連のバックアップ情報ファイルを生成"
#: accounts/automations/backup_account/handlers.py:168
#: accounts/automations/backup_account/manager.py:26
#: accounts/automations/change_secret/manager.py:95
#: accounts/automations/push_account/manager.py:59
#: assets/models/automations/base.py:142 ops/serializers/job.py:71
#: accounts/automations/push_account/manager.py:61
#: assets/models/automations/base.py:145 ops/serializers/job.py:71
#: ops/serializers/job.py:95
#: settings/templates/ldap/_msg_import_ldap_user.html:7
#: terminal/serializers/session.py:49
@ -60,23 +60,27 @@ msgstr "時を過ごす"
msgid "Backup file creation completed"
msgstr "バックアップファイルの作成が完了しました"
#: accounts/automations/backup_account/handlers.py:203
#: accounts/automations/backup_account/handlers.py:177
msgid "Start sending backup emails"
msgstr "バックアップメールの送信を開始する"
#: accounts/automations/backup_account/handlers.py:204
msgid "Encrypting files using encryption password"
msgstr "暗号化パスワードを使用してファイルを暗号化中"
#: accounts/automations/backup_account/handlers.py:213
#: accounts/automations/backup_account/handlers.py:214
msgid "The backup file will be sent to"
msgstr "バックアップファイルは送信されます"
#: accounts/automations/backup_account/handlers.py:236
#: accounts/automations/backup_account/handlers.py:237
msgid "The backup task has no assigned sftp server"
msgstr "このバックアップタスクはsftpサーバーに割り当てられていません"
#: accounts/automations/backup_account/handlers.py:257
#: accounts/automations/backup_account/handlers.py:258
msgid "The backup task has no assigned recipient"
msgstr "バックアップタスクは受取人を指定していません"
#: accounts/automations/backup_account/handlers.py:280
#: accounts/automations/backup_account/handlers.py:281
msgid "Plan start"
msgstr "計画開始"
@ -86,11 +90,11 @@ msgstr "アカウントのバックアップ計画を実行中です"
#: accounts/automations/backup_account/manager.py:24
#: accounts/automations/change_secret/manager.py:93
#: accounts/automations/push_account/manager.py:57
#: accounts/automations/push_account/manager.py:59
msgid "Plan execution end"
msgstr "計画実行終了"
#: accounts/automations/base/manager.py:106
#: accounts/automations/base/manager.py:109
msgid "No pending accounts found"
msgstr "処理待ちのアカウントが見つかりません"
@ -99,6 +103,12 @@ msgstr "処理待ちのアカウントが見つかりません"
msgid "Success: %s, Failed: %s, Total: %s"
msgstr "成功: %s、失敗: %s、合計: %s"
#: accounts/automations/push_account/manager.py:31
#, fuzzy
#| msgid "The {} cannot be empty"
msgid "Secret cannot be empty"
msgstr "{} 空にしてはならない"
#: accounts/automations/verify_gateway_account/manager.py:18
msgid ">>> Start executing the task to test gateway account connectivity"
msgstr ">>> ゲートウェイ接続のテストタスクを開始する"
@ -425,13 +435,13 @@ msgstr "ユーザー %s がパスワードを閲覧/導き出しました"
#: accounts/serializers/automations/gather_account.py:47
#: accounts/templates/accounts/asset_account_change_info.html:7
#: accounts/templates/accounts/change_secret_failed_info.html:11
#: accounts/templates/accounts/change_secret_report.html:70
#: accounts/templates/accounts/change_secret_report.html:102
#: accounts/templates/accounts/check_account_report.html:78
#: accounts/templates/accounts/change_secret_report.html:72
#: accounts/templates/accounts/change_secret_report.html:104
#: accounts/templates/accounts/check_account_report.html:79
#: accounts/templates/accounts/gather_account_report.html:71
#: accounts/templates/accounts/gather_account_report.html:103
#: accounts/templates/accounts/push_account_report.html:70
#: accounts/templates/accounts/push_account_report.html:102
#: accounts/templates/accounts/push_account_report.html:72
#: accounts/templates/accounts/push_account_report.html:104
#: acls/serializers/base.py:130 assets/models/asset/common.py:102
#: assets/models/asset/common.py:366 assets/models/cmd_filter.py:36
#: audits/models.py:59 audits/models.py:312 audits/serializers.py:228
@ -509,7 +519,7 @@ msgstr "変更状態"
#: accounts/models/account.py:85
#: accounts/models/automations/check_account.py:67
#: accounts/serializers/account/service.py:10
#: accounts/serializers/account/service.py:11
#: accounts/serializers/automations/change_secret.py:115
#: accounts/serializers/automations/change_secret.py:146
#: accounts/templates/accounts/change_secret_failed_info.html:12
@ -553,7 +563,7 @@ msgstr "アカウントを削除できます"
#: accounts/models/application.py:16
#: accounts/models/automations/check_account.py:119 accounts/models/base.py:63
#: accounts/serializers/account/service.py:26
#: accounts/serializers/account/service.py:27
#: accounts/serializers/account/virtual.py:20 acls/models/base.py:35
#: acls/models/base.py:96 acls/models/command_acl.py:21
#: acls/serializers/base.py:35 assets/models/asset/common.py:100
@ -721,7 +731,7 @@ msgstr "SSHキープッシュ方式"
msgid "Check connection after change"
msgstr "変更後に接続を確認"
#: accounts/models/automations/change_secret.py:16
#: accounts/models/automations/change_secret.py:17
#: accounts/models/automations/check_account.py:19
#: accounts/models/automations/gather_account.py:92
#: accounts/serializers/automations/change_secret.py:59
@ -730,22 +740,22 @@ msgstr "変更後に接続を確認"
msgid "Recipient"
msgstr "受信者"
#: accounts/models/automations/change_secret.py:23
#: accounts/models/automations/change_secret.py:24
msgid "Change secret automation"
msgstr "自動暗号化"
#: accounts/models/automations/change_secret.py:46
#: assets/models/automations/base.py:141 ops/models/base.py:56
#: accounts/models/automations/change_secret.py:47
#: assets/models/automations/base.py:144 ops/models/base.py:56
#: ops/models/celery.py:90 ops/models/job.py:240
#: terminal/models/applet/host.py:142
msgid "Date finished"
msgstr "終了日"
#: accounts/models/automations/change_secret.py:48
#: accounts/models/automations/change_secret.py:49
#: accounts/models/automations/check_account.py:75
#: accounts/models/automations/gather_account.py:25
#: accounts/serializers/automations/check_account.py:39
#: assets/models/automations/base.py:133
#: assets/models/automations/base.py:136
#: assets/serializers/automations/base.py:45 audits/models.py:209
#: audits/serializers.py:78 ops/models/base.py:49 ops/models/job.py:231
#: terminal/models/applet/applet.py:331 terminal/models/applet/host.py:140
@ -759,7 +769,7 @@ msgstr "終了日"
msgid "Status"
msgstr "ステータス"
#: accounts/models/automations/change_secret.py:50
#: accounts/models/automations/change_secret.py:51
#: accounts/serializers/account/account.py:276
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
@ -770,19 +780,19 @@ msgstr "ステータス"
msgid "Error"
msgstr "間違い"
#: accounts/models/automations/change_secret.py:66
#: accounts/models/automations/change_secret.py:73
msgid "Old secret"
msgstr "オリジナルキー"
#: accounts/models/automations/change_secret.py:67
#: accounts/models/automations/change_secret.py:74
msgid "New secret"
msgstr "新しい鍵"
#: accounts/models/automations/change_secret.py:68
#: accounts/models/automations/change_secret.py:75
msgid "Ignore fail"
msgstr "失敗を無視"
#: accounts/models/automations/change_secret.py:71
#: accounts/models/automations/change_secret.py:78
msgid "Change secret record"
msgstr "パスワード レコードの変更"
@ -836,8 +846,8 @@ msgid "Long time no change"
msgstr "長期間パスワードが変更されていません"
#: accounts/models/automations/check_account.py:52
#: accounts/templates/accounts/check_account_report.html:69
#: accounts/templates/accounts/check_account_report.html:89
#: accounts/templates/accounts/check_account_report.html:70
#: accounts/templates/accounts/check_account_report.html:90
msgid "Weak password"
msgstr "弱いパスワード"
@ -864,13 +874,13 @@ msgstr "その他"
#: accounts/models/automations/check_account.py:64
#: accounts/models/automations/gather_account.py:17 accounts/models/base.py:64
#: accounts/serializers/account/virtual.py:21
#: accounts/templates/accounts/change_secret_report.html:71
#: accounts/templates/accounts/change_secret_report.html:103
#: accounts/templates/accounts/check_account_report.html:79
#: accounts/templates/accounts/change_secret_report.html:73
#: accounts/templates/accounts/change_secret_report.html:105
#: accounts/templates/accounts/check_account_report.html:80
#: accounts/templates/accounts/gather_account_report.html:72
#: accounts/templates/accounts/gather_account_report.html:104
#: accounts/templates/accounts/push_account_report.html:71
#: accounts/templates/accounts/push_account_report.html:103
#: accounts/templates/accounts/push_account_report.html:73
#: accounts/templates/accounts/push_account_report.html:105
#: acls/serializers/base.py:19 acls/serializers/base.py:50 audits/models.py:189
#: authentication/forms.py:21 authentication/forms.py:23
#: authentication/models/temp_token.py:9
@ -1294,12 +1304,12 @@ msgstr ""
"ヒント: 認証にユーザー名が必要ない場合は、`null`を入力します。ADアカウントの"
"場合は、`username@domain`のようになります。"
#: accounts/serializers/account/service.py:12
#: accounts/serializers/account/service.py:13
#: authentication/serializers/token.py:22
msgid "Access IP"
msgstr "Access IP"
#: accounts/serializers/account/service.py:25
#: accounts/serializers/account/service.py:26
#: accounts/serializers/account/virtual.py:19 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 common/db/models.py:36 ops/models/adhoc.py:25
#: ops/models/job.py:163 ops/models/playbook.py:31 rbac/models/role.py:37
@ -1314,9 +1324,9 @@ msgstr "Access IP"
msgid "Comment"
msgstr "コメント"
#: accounts/serializers/account/service.py:27
#: accounts/templates/accounts/backup_account_report.html:38
#: accounts/templates/accounts/check_account_report.html:38
#: accounts/serializers/account/service.py:28
#: accounts/templates/accounts/backup_account_report.html:39
#: accounts/templates/accounts/check_account_report.html:39
#: assets/serializers/asset/common.py:151
msgid "Accounts amount"
msgstr "アカウント数"
@ -1412,7 +1422,7 @@ msgid "Name already exists"
msgstr "名前は既に存在します。"
#: accounts/serializers/automations/base.py:31
#: assets/models/automations/base.py:144
#: assets/models/automations/base.py:147
#: assets/serializers/automations/base.py:43
msgid "Automation snapshot"
msgstr "自動スナップショット"
@ -1441,8 +1451,8 @@ msgid "* Please enter the correct password length"
msgstr "* 正しいパスワードの長さを入力してください"
#: accounts/serializers/automations/change_secret.py:90
msgid "* Password length range 6-30 bits"
msgstr "* パスワードの長さ範囲は6-30文字です"
msgid "* Password length range 8-36 bits"
msgstr "* パスワードの長さ範囲は8-36文字です"
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:147
@ -1451,7 +1461,7 @@ msgid "Is success"
msgstr "成功は"
#: accounts/serializers/automations/change_secret.py:119
#: assets/models/automations/base.py:160
#: assets/models/automations/base.py:163
msgid "Automation task execution"
msgstr "自動タスク実行履歴"
@ -1625,29 +1635,29 @@ msgstr "アカウント接続のテスト"
msgid "Deleted account"
msgstr "アカウントの削除"
#: accounts/templates/accounts/backup_account_report.html:13
#: accounts/templates/accounts/backup_account_report.html:14
msgid ""
"The following is a summary of account backup tasks, please review and handle "
"them"
msgstr ""
"以下はアカウントバックアップタスクの概要です。ご確認と処理をお願いします。"
#: accounts/templates/accounts/backup_account_report.html:22
#: accounts/templates/accounts/backup_account_report.html:23
#: accounts/templates/accounts/change_secret_failed_info.html:3
#: accounts/templates/accounts/change_secret_report.html:22
#: accounts/templates/accounts/check_account_report.html:22
#: accounts/templates/accounts/change_secret_report.html:24
#: accounts/templates/accounts/check_account_report.html:23
#: accounts/templates/accounts/gather_account_report.html:23
#: accounts/templates/accounts/push_account_report.html:22
#: accounts/templates/accounts/push_account_report.html:24
#: terminal/serializers/task.py:10
msgid "Task name"
msgstr "タスク名"
#: accounts/templates/accounts/backup_account_report.html:26
#: accounts/templates/accounts/change_secret_report.html:26
#: accounts/templates/accounts/check_account_report.html:26
#: accounts/templates/accounts/backup_account_report.html:27
#: accounts/templates/accounts/change_secret_report.html:28
#: accounts/templates/accounts/check_account_report.html:27
#: accounts/templates/accounts/gather_account_report.html:27
#: accounts/templates/accounts/push_account_report.html:26
#: assets/models/automations/base.py:139 audits/models.py:66
#: accounts/templates/accounts/push_account_report.html:28
#: assets/models/automations/base.py:142 audits/models.py:66
#: ops/models/base.py:55 ops/models/celery.py:89 ops/models/job.py:239
#: ops/templates/ops/celery_task_log.html:101
#: perms/models/asset_permission.py:78 settings/serializers/feature.py:27
@ -1658,26 +1668,26 @@ msgstr "タスク名"
msgid "Date start"
msgstr "開始日"
#: accounts/templates/accounts/backup_account_report.html:30
#: accounts/templates/accounts/change_secret_report.html:30
#: accounts/templates/accounts/check_account_report.html:30
#: accounts/templates/accounts/backup_account_report.html:31
#: accounts/templates/accounts/change_secret_report.html:32
#: accounts/templates/accounts/check_account_report.html:31
#: accounts/templates/accounts/gather_account_report.html:31
#: accounts/templates/accounts/push_account_report.html:30
#: accounts/templates/accounts/push_account_report.html:32
#: settings/serializers/feature.py:28
#: settings/templates/ldap/_msg_import_ldap_user.html:6
#: terminal/models/session/session.py:48
msgid "Date end"
msgstr "終了日"
#: accounts/templates/accounts/backup_account_report.html:34
#: accounts/templates/accounts/change_secret_report.html:34
#: accounts/templates/accounts/check_account_report.html:34
#: accounts/templates/accounts/backup_account_report.html:35
#: accounts/templates/accounts/change_secret_report.html:36
#: accounts/templates/accounts/check_account_report.html:35
#: accounts/templates/accounts/gather_account_report.html:35
#: accounts/templates/accounts/push_account_report.html:34
#: accounts/templates/accounts/push_account_report.html:36
msgid "Time using"
msgstr "時間を要する"
#: accounts/templates/accounts/backup_account_report.html:42
#: accounts/templates/accounts/backup_account_report.html:43
msgid "Type count"
msgstr "タイプ数"
@ -1697,7 +1707,7 @@ msgstr ""
"こんにちは! アセットの変更またはアカウントのプッシュが失敗する状況は次のとお"
"りです。 時間内に確認して対処してください。"
#: accounts/templates/accounts/change_secret_report.html:13
#: accounts/templates/accounts/change_secret_report.html:15
msgid ""
"The following is a summary of account change secret tasks, please read and "
"process"
@ -1705,66 +1715,66 @@ msgstr ""
"以下はアカウント変更の秘密の任務の概要です。お読みいただき、処理してくださ"
"い。"
#: accounts/templates/accounts/change_secret_report.html:38
#: accounts/templates/accounts/change_secret_report.html:40
#: accounts/templates/accounts/gather_account_report.html:39
#: accounts/templates/accounts/push_account_report.html:38
#: accounts/templates/accounts/push_account_report.html:40
#: assets/serializers/domain.py:24 assets/serializers/platform.py:182
#: orgs/serializers.py:13 perms/serializers/permission.py:50
msgid "Assets amount"
msgstr "資産数量"
#: accounts/templates/accounts/change_secret_report.html:42
#: accounts/templates/accounts/check_account_report.html:50
#: accounts/templates/accounts/change_secret_report.html:44
#: accounts/templates/accounts/check_account_report.html:51
#: accounts/templates/accounts/gather_account_report.html:43
#: accounts/templates/accounts/push_account_report.html:42
#: accounts/templates/accounts/push_account_report.html:44
msgid "Asset success count"
msgstr "成功した資産数"
#: accounts/templates/accounts/change_secret_report.html:46
#: accounts/templates/accounts/check_account_report.html:54
#: accounts/templates/accounts/change_secret_report.html:48
#: accounts/templates/accounts/check_account_report.html:55
#: accounts/templates/accounts/gather_account_report.html:47
#: accounts/templates/accounts/push_account_report.html:46
#: accounts/templates/accounts/push_account_report.html:48
msgid "Asset failed count"
msgstr "失敗した資産数"
#: accounts/templates/accounts/change_secret_report.html:50
#: accounts/templates/accounts/check_account_report.html:58
#: accounts/templates/accounts/change_secret_report.html:52
#: accounts/templates/accounts/check_account_report.html:59
#: accounts/templates/accounts/gather_account_report.html:51
#: accounts/templates/accounts/push_account_report.html:50
#: accounts/templates/accounts/push_account_report.html:52
msgid "Asset not support count"
msgstr "サポートされていない資産数"
#: accounts/templates/accounts/change_secret_report.html:61
#: accounts/templates/accounts/push_account_report.html:61
#: accounts/templates/accounts/change_secret_report.html:63
#: accounts/templates/accounts/push_account_report.html:63
msgid "Success accounts"
msgstr "成功したアカウント"
#: accounts/templates/accounts/change_secret_report.html:69
#: accounts/templates/accounts/change_secret_report.html:101
#: accounts/templates/accounts/check_account_report.html:77
#: accounts/templates/accounts/change_secret_report.html:71
#: accounts/templates/accounts/change_secret_report.html:103
#: accounts/templates/accounts/check_account_report.html:78
#: accounts/templates/accounts/gather_account_report.html:70
#: accounts/templates/accounts/gather_account_report.html:102
#: accounts/templates/accounts/push_account_report.html:69
#: accounts/templates/accounts/push_account_report.html:101
#: accounts/templates/accounts/push_account_report.html:71
#: accounts/templates/accounts/push_account_report.html:103
#: audits/handler.py:128
msgid "No"
msgstr "否"
#: accounts/templates/accounts/change_secret_report.html:85
#: accounts/templates/accounts/change_secret_report.html:117
#: accounts/templates/accounts/change_secret_report.html:87
#: accounts/templates/accounts/change_secret_report.html:119
#: accounts/templates/accounts/gather_account_report.html:86
#: accounts/templates/accounts/gather_account_report.html:118
#: accounts/templates/accounts/push_account_report.html:85
#: accounts/templates/accounts/push_account_report.html:117
#: accounts/templates/accounts/push_account_report.html:87
#: accounts/templates/accounts/push_account_report.html:119
msgid "No new accounts found"
msgstr "新しいアカウントが見つかりません"
#: accounts/templates/accounts/change_secret_report.html:92
#: accounts/templates/accounts/push_account_report.html:92
#: accounts/templates/accounts/change_secret_report.html:94
#: accounts/templates/accounts/push_account_report.html:94
msgid "Failed accounts"
msgstr "失敗したアカウント"
#: accounts/templates/accounts/check_account_report.html:13
#: accounts/templates/accounts/check_account_report.html:14
#: accounts/templates/accounts/gather_account_report.html:14
msgid ""
"The following is a summary of the account check tasks. Please review and "
@ -1772,21 +1782,21 @@ msgid ""
msgstr ""
"以下はアカウントチェックタスクのまとめですので、ご確認の上、処理してください"
#: accounts/templates/accounts/check_account_report.html:42
#: accounts/templates/accounts/check_account_report.html:43
msgid "Ok count"
msgstr "成功した数"
#: accounts/templates/accounts/check_account_report.html:46
#: accounts/templates/accounts/check_account_report.html:47
msgid "No password count"
msgstr "パスワードなしの数"
#: accounts/templates/accounts/check_account_report.html:80
#: assets/models/automations/base.py:153 ops/models/base.py:51
#: accounts/templates/accounts/check_account_report.html:81
#: assets/models/automations/base.py:156 ops/models/base.py:51
#: ops/models/job.py:235 xpack/plugins/cloud/models.py:225
msgid "Result"
msgstr "結果"
#: accounts/templates/accounts/check_account_report.html:95
#: accounts/templates/accounts/check_account_report.html:96
msgid "No weak password"
msgstr "弱いパスワードなし"
@ -1798,7 +1808,7 @@ msgstr "新たに発見されたアカウント"
msgid "Lost accounts"
msgstr "失われたアカウント"
#: accounts/templates/accounts/push_account_report.html:13
#: accounts/templates/accounts/push_account_report.html:15
msgid ""
"The following is a summary of account push tasks, please read and process"
msgstr ""
@ -2112,28 +2122,28 @@ msgstr "同じレベルのノード名を同じにすることはできません
msgid "App Assets"
msgstr "アプリ資産"
#: assets/automations/base/manager.py:332
#: assets/automations/base/manager.py:347
msgid " - Platform {} ansible disabled"
msgstr " - プラットフォーム {} ansible 無効"
#: assets/automations/base/manager.py:514
#: assets/automations/base/manager.py:530
msgid ">>> Task preparation phase"
msgstr "タスク準備段階"
#: assets/automations/base/manager.py:518
#: assets/automations/base/manager.py:534
#, python-brace-format
msgid ">>> Executing tasks in batches, total {runner_count}"
msgstr ">>> バッチでタスクを実行、合計 {runner_count}"
#: assets/automations/base/manager.py:523
#: assets/automations/base/manager.py:539
msgid ">>> Start executing tasks"
msgstr ">>> タスクの実行を開始"
#: assets/automations/base/manager.py:525
#: assets/automations/base/manager.py:541
msgid ">>> No tasks need to be executed"
msgstr ">>> 実行する必要があるタスクはありません"
#: assets/automations/base/manager.py:529
#: assets/automations/base/manager.py:545
#, python-brace-format
msgid ">>> Begin executing batch {index} of tasks"
msgstr ">>> 第 {index} バッチのタスクの実行を開始"
@ -2568,27 +2578,33 @@ msgstr "ノード"
msgid "Parameters"
msgstr "パラメータ"
#: assets/models/automations/base.py:41 assets/models/automations/base.py:128
#: assets/models/automations/base.py:31
#, fuzzy
#| msgid "Last execution"
msgid "Last execution date"
msgstr "最後の実行"
#: assets/models/automations/base.py:44 assets/models/automations/base.py:131
msgid "Automation task"
msgstr "自動化されたタスク"
#: assets/models/automations/base.py:119
#: assets/models/automations/base.py:122
msgid "Asset automation task"
msgstr "アセットの自動化タスク"
#: assets/models/automations/base.py:136 assets/models/cmd_filter.py:41
#: assets/models/automations/base.py:139 assets/models/cmd_filter.py:41
#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:238
#: users/models/user/__init__.py:322
msgid "Date created"
msgstr "作成された日付"
#: assets/models/automations/base.py:150
#: assets/models/automations/base.py:153
#: assets/serializers/automations/base.py:44 xpack/plugins/cloud/models.py:242
#: xpack/plugins/cloud/serializers/task.py:249
msgid "Trigger mode"
msgstr "トリガーモード"
#: assets/models/automations/base.py:152 audits/serializers.py:39
#: assets/models/automations/base.py:155 audits/serializers.py:39
#: ops/models/base.py:52 ops/models/job.py:236
#: xpack/plugins/cloud/manager.py:103
msgid "Summary"
@ -7180,7 +7196,9 @@ msgid "User first login update profile done redirect to it"
msgstr "ユーザーの最初のログイン更新プロファイルがリダイレクトされました"
#: settings/serializers/basic.py:22
msgid "Global organization"
#, fuzzy
#| msgid "Global organization"
msgid "Global org display"
msgstr "グローバル組織名"
#: settings/serializers/basic.py:23

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-28 18:37+0800\n"
"POT-Creation-Date: 2025-03-07 15:03+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"
@ -24,7 +24,7 @@ msgstr ""
msgid "Account already exists"
msgstr "Conta já existente"
#: accounts/api/account/application.py:77
#: accounts/api/account/application.py:78
#: authentication/api/connection_token.py:449
msgid "Account not found"
msgstr "Conta não encontrada"
@ -48,8 +48,8 @@ msgstr "Gerar arquivo de informações de backup relacionado ao ativo"
#: accounts/automations/backup_account/handlers.py:168
#: accounts/automations/backup_account/manager.py:26
#: accounts/automations/change_secret/manager.py:95
#: accounts/automations/push_account/manager.py:59
#: assets/models/automations/base.py:142 ops/serializers/job.py:71
#: accounts/automations/push_account/manager.py:61
#: assets/models/automations/base.py:145 ops/serializers/job.py:71
#: ops/serializers/job.py:95
#: settings/templates/ldap/_msg_import_ldap_user.html:7
#: terminal/serializers/session.py:49
@ -60,23 +60,27 @@ msgstr "Duração"
msgid "Backup file creation completed"
msgstr "Criação de arquivo de backup concluída"
#: accounts/automations/backup_account/handlers.py:203
#: accounts/automations/backup_account/handlers.py:177
msgid "Start sending backup emails"
msgstr "Comece a enviar e-mails de backup"
#: accounts/automations/backup_account/handlers.py:204
msgid "Encrypting files using encryption password"
msgstr "Usando senha criptografada para criptografar o arquivo"
#: accounts/automations/backup_account/handlers.py:213
#: accounts/automations/backup_account/handlers.py:214
msgid "The backup file will be sent to"
msgstr "O arquivo de backup será enviado para"
#: accounts/automations/backup_account/handlers.py:236
#: accounts/automations/backup_account/handlers.py:237
msgid "The backup task has no assigned sftp server"
msgstr "A tarefa de backup não foi atribuída a um servidor sftp"
#: accounts/automations/backup_account/handlers.py:257
#: accounts/automations/backup_account/handlers.py:258
msgid "The backup task has no assigned recipient"
msgstr "A tarefa de backup não possui destinatário especificado"
#: accounts/automations/backup_account/handlers.py:280
#: accounts/automations/backup_account/handlers.py:281
msgid "Plan start"
msgstr "Tarefa iniciada"
@ -86,11 +90,11 @@ msgstr "Plano de backup de contas está em execução"
#: accounts/automations/backup_account/manager.py:24
#: accounts/automations/change_secret/manager.py:93
#: accounts/automations/push_account/manager.py:57
#: accounts/automations/push_account/manager.py:59
msgid "Plan execution end"
msgstr "Execução do plano concluída"
#: accounts/automations/base/manager.py:106
#: accounts/automations/base/manager.py:109
msgid "No pending accounts found"
msgstr "Conta pendente não encontrada"
@ -99,6 +103,12 @@ msgstr "Conta pendente não encontrada"
msgid "Success: %s, Failed: %s, Total: %s"
msgstr "Sucesso: %s, Falha: %s, Total: %s"
#: accounts/automations/push_account/manager.py:31
#, fuzzy
#| msgid "The {} cannot be empty"
msgid "Secret cannot be empty"
msgstr "{} não pode estar vazio"
#: accounts/automations/verify_gateway_account/manager.py:18
msgid ">>> Start executing the task to test gateway account connectivity"
msgstr ">>> Iniciando teste de conectividade da conta do gateway"
@ -426,13 +436,13 @@ msgstr "Usuário %s visualizou/exportou a senha"
#: accounts/serializers/automations/gather_account.py:47
#: accounts/templates/accounts/asset_account_change_info.html:7
#: accounts/templates/accounts/change_secret_failed_info.html:11
#: accounts/templates/accounts/change_secret_report.html:70
#: accounts/templates/accounts/change_secret_report.html:102
#: accounts/templates/accounts/check_account_report.html:78
#: accounts/templates/accounts/change_secret_report.html:72
#: accounts/templates/accounts/change_secret_report.html:104
#: accounts/templates/accounts/check_account_report.html:79
#: accounts/templates/accounts/gather_account_report.html:71
#: accounts/templates/accounts/gather_account_report.html:103
#: accounts/templates/accounts/push_account_report.html:70
#: accounts/templates/accounts/push_account_report.html:102
#: accounts/templates/accounts/push_account_report.html:72
#: accounts/templates/accounts/push_account_report.html:104
#: acls/serializers/base.py:130 assets/models/asset/common.py:102
#: assets/models/asset/common.py:366 assets/models/cmd_filter.py:36
#: audits/models.py:59 audits/models.py:312 audits/serializers.py:228
@ -495,7 +505,7 @@ msgstr "Status da Alteração de Senha"
#: accounts/models/account.py:85
#: accounts/models/automations/check_account.py:67
#: accounts/serializers/account/service.py:10
#: accounts/serializers/account/service.py:11
#: accounts/serializers/automations/change_secret.py:115
#: accounts/serializers/automations/change_secret.py:146
#: accounts/templates/accounts/change_secret_failed_info.html:12
@ -539,7 +549,7 @@ msgstr "É possível remover a conta"
#: accounts/models/application.py:16
#: accounts/models/automations/check_account.py:119 accounts/models/base.py:63
#: accounts/serializers/account/service.py:26
#: accounts/serializers/account/service.py:27
#: accounts/serializers/account/virtual.py:20 acls/models/base.py:35
#: acls/models/base.py:96 acls/models/command_acl.py:21
#: acls/serializers/base.py:35 assets/models/asset/common.py:100
@ -707,7 +717,7 @@ msgstr "Método de lançamento da chave SSH"
msgid "Check connection after change"
msgstr "Verifique a conexão após a alteração"
#: accounts/models/automations/change_secret.py:16
#: accounts/models/automations/change_secret.py:17
#: accounts/models/automations/check_account.py:19
#: accounts/models/automations/gather_account.py:92
#: accounts/serializers/automations/change_secret.py:59
@ -716,22 +726,22 @@ msgstr "Verifique a conexão após a alteração"
msgid "Recipient"
msgstr "Destinatário"
#: accounts/models/automations/change_secret.py:23
#: accounts/models/automations/change_secret.py:24
msgid "Change secret automation"
msgstr "Automação da alteração de senha"
#: accounts/models/automations/change_secret.py:46
#: assets/models/automations/base.py:141 ops/models/base.py:56
#: accounts/models/automations/change_secret.py:47
#: assets/models/automations/base.py:144 ops/models/base.py:56
#: ops/models/celery.py:90 ops/models/job.py:240
#: terminal/models/applet/host.py:142
msgid "Date finished"
msgstr "Data de fim"
#: accounts/models/automations/change_secret.py:48
#: accounts/models/automations/change_secret.py:49
#: accounts/models/automations/check_account.py:75
#: accounts/models/automations/gather_account.py:25
#: accounts/serializers/automations/check_account.py:39
#: assets/models/automations/base.py:133
#: assets/models/automations/base.py:136
#: assets/serializers/automations/base.py:45 audits/models.py:209
#: audits/serializers.py:78 ops/models/base.py:49 ops/models/job.py:231
#: terminal/models/applet/applet.py:331 terminal/models/applet/host.py:140
@ -745,7 +755,7 @@ msgstr "Data de fim"
msgid "Status"
msgstr "Status"
#: accounts/models/automations/change_secret.py:50
#: accounts/models/automations/change_secret.py:51
#: accounts/serializers/account/account.py:276
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
@ -756,19 +766,19 @@ msgstr "Status"
msgid "Error"
msgstr "Erro"
#: accounts/models/automations/change_secret.py:66
#: accounts/models/automations/change_secret.py:73
msgid "Old secret"
msgstr "Senha antiga"
#: accounts/models/automations/change_secret.py:67
#: accounts/models/automations/change_secret.py:74
msgid "New secret"
msgstr "Nova senha"
#: accounts/models/automations/change_secret.py:68
#: accounts/models/automations/change_secret.py:75
msgid "Ignore fail"
msgstr "Ignorar falhas"
#: accounts/models/automations/change_secret.py:71
#: accounts/models/automations/change_secret.py:78
msgid "Change secret record"
msgstr "Registro de alteração de senha"
@ -837,8 +847,8 @@ msgstr ""
"- Remover remoto"
#: accounts/models/automations/check_account.py:52
#: accounts/templates/accounts/check_account_report.html:69
#: accounts/templates/accounts/check_account_report.html:89
#: accounts/templates/accounts/check_account_report.html:70
#: accounts/templates/accounts/check_account_report.html:90
msgid "Weak password"
msgstr "Senha fraca"
@ -865,13 +875,13 @@ msgstr "Outro"
#: accounts/models/automations/check_account.py:64
#: accounts/models/automations/gather_account.py:17 accounts/models/base.py:64
#: accounts/serializers/account/virtual.py:21
#: accounts/templates/accounts/change_secret_report.html:71
#: accounts/templates/accounts/change_secret_report.html:103
#: accounts/templates/accounts/check_account_report.html:79
#: accounts/templates/accounts/change_secret_report.html:73
#: accounts/templates/accounts/change_secret_report.html:105
#: accounts/templates/accounts/check_account_report.html:80
#: accounts/templates/accounts/gather_account_report.html:72
#: accounts/templates/accounts/gather_account_report.html:104
#: accounts/templates/accounts/push_account_report.html:71
#: accounts/templates/accounts/push_account_report.html:103
#: accounts/templates/accounts/push_account_report.html:73
#: accounts/templates/accounts/push_account_report.html:105
#: acls/serializers/base.py:19 acls/serializers/base.py:50 audits/models.py:189
#: authentication/forms.py:21 authentication/forms.py:23
#: authentication/models/temp_token.py:9
@ -1299,12 +1309,12 @@ msgstr ""
"Aviso: Se a identificação não necessitar de um nome de usuário, insira "
"'null'. Se for uma conta AD, o formato é username@domain."
#: accounts/serializers/account/service.py:12
#: accounts/serializers/account/service.py:13
#: authentication/serializers/token.py:22
msgid "Access IP"
msgstr "Lista branca de IP"
#: accounts/serializers/account/service.py:25
#: accounts/serializers/account/service.py:26
#: accounts/serializers/account/virtual.py:19 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 common/db/models.py:36 ops/models/adhoc.py:25
#: ops/models/job.py:163 ops/models/playbook.py:31 rbac/models/role.py:37
@ -1319,9 +1329,9 @@ msgstr "Lista branca de IP"
msgid "Comment"
msgstr "Observação"
#: accounts/serializers/account/service.py:27
#: accounts/templates/accounts/backup_account_report.html:38
#: accounts/templates/accounts/check_account_report.html:38
#: accounts/serializers/account/service.py:28
#: accounts/templates/accounts/backup_account_report.html:39
#: accounts/templates/accounts/check_account_report.html:39
#: assets/serializers/asset/common.py:151
msgid "Accounts amount"
msgstr "Quantidade de contas"
@ -1424,7 +1434,7 @@ msgid "Name already exists"
msgstr "O nome já existe"
#: accounts/serializers/automations/base.py:31
#: assets/models/automations/base.py:144
#: assets/models/automations/base.py:147
#: assets/serializers/automations/base.py:43
msgid "Automation snapshot"
msgstr "Snapshot automático"
@ -1454,8 +1464,8 @@ msgid "* Please enter the correct password length"
msgstr "* Por favor, insira um comprimento de senha correto"
#: accounts/serializers/automations/change_secret.py:90
msgid "* Password length range 6-30 bits"
msgstr "* O comprimento da senha deve estar entre 6 e 30 caracteres"
msgid "* Password length range 8-36 bits"
msgstr "* O comprimento da senha deve estar entre 8 e 36 caracteres"
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:147
@ -1464,7 +1474,7 @@ msgid "Is success"
msgstr "Foi Bem-sucedido?"
#: accounts/serializers/automations/change_secret.py:119
#: assets/models/automations/base.py:160
#: assets/models/automations/base.py:163
msgid "Automation task execution"
msgstr "Histórico de execução de tarefas automáticas"
@ -1644,7 +1654,7 @@ msgstr "Testar a conectividade da conta"
msgid "Deleted account"
msgstr "Excluir conta"
#: accounts/templates/accounts/backup_account_report.html:13
#: accounts/templates/accounts/backup_account_report.html:14
msgid ""
"The following is a summary of account backup tasks, please review and handle "
"them"
@ -1652,22 +1662,22 @@ msgstr ""
"Abaixo estão os resumos das tarefas de backup de contas, por favor, revise e "
"trate."
#: accounts/templates/accounts/backup_account_report.html:22
#: accounts/templates/accounts/backup_account_report.html:23
#: accounts/templates/accounts/change_secret_failed_info.html:3
#: accounts/templates/accounts/change_secret_report.html:22
#: accounts/templates/accounts/check_account_report.html:22
#: accounts/templates/accounts/change_secret_report.html:24
#: accounts/templates/accounts/check_account_report.html:23
#: accounts/templates/accounts/gather_account_report.html:23
#: accounts/templates/accounts/push_account_report.html:22
#: accounts/templates/accounts/push_account_report.html:24
#: terminal/serializers/task.py:10
msgid "Task name"
msgstr "Nome da tarefa"
#: accounts/templates/accounts/backup_account_report.html:26
#: accounts/templates/accounts/change_secret_report.html:26
#: accounts/templates/accounts/check_account_report.html:26
#: accounts/templates/accounts/backup_account_report.html:27
#: accounts/templates/accounts/change_secret_report.html:28
#: accounts/templates/accounts/check_account_report.html:27
#: accounts/templates/accounts/gather_account_report.html:27
#: accounts/templates/accounts/push_account_report.html:26
#: assets/models/automations/base.py:139 audits/models.py:66
#: accounts/templates/accounts/push_account_report.html:28
#: assets/models/automations/base.py:142 audits/models.py:66
#: ops/models/base.py:55 ops/models/celery.py:89 ops/models/job.py:239
#: ops/templates/ops/celery_task_log.html:101
#: perms/models/asset_permission.py:78 settings/serializers/feature.py:27
@ -1678,26 +1688,26 @@ msgstr "Nome da tarefa"
msgid "Date start"
msgstr "Data de Início"
#: accounts/templates/accounts/backup_account_report.html:30
#: accounts/templates/accounts/change_secret_report.html:30
#: accounts/templates/accounts/check_account_report.html:30
#: accounts/templates/accounts/backup_account_report.html:31
#: accounts/templates/accounts/change_secret_report.html:32
#: accounts/templates/accounts/check_account_report.html:31
#: accounts/templates/accounts/gather_account_report.html:31
#: accounts/templates/accounts/push_account_report.html:30
#: accounts/templates/accounts/push_account_report.html:32
#: settings/serializers/feature.py:28
#: settings/templates/ldap/_msg_import_ldap_user.html:6
#: terminal/models/session/session.py:48
msgid "Date end"
msgstr "Data de Encerramento"
#: accounts/templates/accounts/backup_account_report.html:34
#: accounts/templates/accounts/change_secret_report.html:34
#: accounts/templates/accounts/check_account_report.html:34
#: accounts/templates/accounts/backup_account_report.html:35
#: accounts/templates/accounts/change_secret_report.html:36
#: accounts/templates/accounts/check_account_report.html:35
#: accounts/templates/accounts/gather_account_report.html:35
#: accounts/templates/accounts/push_account_report.html:34
#: accounts/templates/accounts/push_account_report.html:36
msgid "Time using"
msgstr "Duração."
#: accounts/templates/accounts/backup_account_report.html:42
#: accounts/templates/accounts/backup_account_report.html:43
msgid "Type count"
msgstr "Número de tipos"
@ -1717,7 +1727,7 @@ msgstr ""
"Olá! Aqui estão os casos de falha ao alterar ou enviar a senha do ativo. Por "
"favor, verifique e corrija o mais rápido possível."
#: accounts/templates/accounts/change_secret_report.html:13
#: accounts/templates/accounts/change_secret_report.html:15
msgid ""
"The following is a summary of account change secret tasks, please read and "
"process"
@ -1725,66 +1735,66 @@ msgstr ""
"Aqui está um resumo da missão secreta de alteração de conta, por favor, leia "
"e processe."
#: accounts/templates/accounts/change_secret_report.html:38
#: accounts/templates/accounts/change_secret_report.html:40
#: accounts/templates/accounts/gather_account_report.html:39
#: accounts/templates/accounts/push_account_report.html:38
#: accounts/templates/accounts/push_account_report.html:40
#: assets/serializers/domain.py:24 assets/serializers/platform.py:182
#: orgs/serializers.py:13 perms/serializers/permission.py:50
msgid "Assets amount"
msgstr "Número de ativos"
#: accounts/templates/accounts/change_secret_report.html:42
#: accounts/templates/accounts/check_account_report.html:50
#: accounts/templates/accounts/change_secret_report.html:44
#: accounts/templates/accounts/check_account_report.html:51
#: accounts/templates/accounts/gather_account_report.html:43
#: accounts/templates/accounts/push_account_report.html:42
#: accounts/templates/accounts/push_account_report.html:44
msgid "Asset success count"
msgstr "Número de ativos bem-sucedidos"
#: accounts/templates/accounts/change_secret_report.html:46
#: accounts/templates/accounts/check_account_report.html:54
#: accounts/templates/accounts/change_secret_report.html:48
#: accounts/templates/accounts/check_account_report.html:55
#: accounts/templates/accounts/gather_account_report.html:47
#: accounts/templates/accounts/push_account_report.html:46
#: accounts/templates/accounts/push_account_report.html:48
msgid "Asset failed count"
msgstr "Número de ativos com falha"
#: accounts/templates/accounts/change_secret_report.html:50
#: accounts/templates/accounts/check_account_report.html:58
#: accounts/templates/accounts/change_secret_report.html:52
#: accounts/templates/accounts/check_account_report.html:59
#: accounts/templates/accounts/gather_account_report.html:51
#: accounts/templates/accounts/push_account_report.html:50
#: accounts/templates/accounts/push_account_report.html:52
msgid "Asset not support count"
msgstr "Número de ativos não suportados"
#: accounts/templates/accounts/change_secret_report.html:61
#: accounts/templates/accounts/push_account_report.html:61
#: accounts/templates/accounts/change_secret_report.html:63
#: accounts/templates/accounts/push_account_report.html:63
msgid "Success accounts"
msgstr "Contas bem-sucedidas"
#: accounts/templates/accounts/change_secret_report.html:69
#: accounts/templates/accounts/change_secret_report.html:101
#: accounts/templates/accounts/check_account_report.html:77
#: accounts/templates/accounts/change_secret_report.html:71
#: accounts/templates/accounts/change_secret_report.html:103
#: accounts/templates/accounts/check_account_report.html:78
#: accounts/templates/accounts/gather_account_report.html:70
#: accounts/templates/accounts/gather_account_report.html:102
#: accounts/templates/accounts/push_account_report.html:69
#: accounts/templates/accounts/push_account_report.html:101
#: accounts/templates/accounts/push_account_report.html:71
#: accounts/templates/accounts/push_account_report.html:103
#: audits/handler.py:128
msgid "No"
msgstr "Não"
#: accounts/templates/accounts/change_secret_report.html:85
#: accounts/templates/accounts/change_secret_report.html:117
#: accounts/templates/accounts/change_secret_report.html:87
#: accounts/templates/accounts/change_secret_report.html:119
#: accounts/templates/accounts/gather_account_report.html:86
#: accounts/templates/accounts/gather_account_report.html:118
#: accounts/templates/accounts/push_account_report.html:85
#: accounts/templates/accounts/push_account_report.html:117
#: accounts/templates/accounts/push_account_report.html:87
#: accounts/templates/accounts/push_account_report.html:119
msgid "No new accounts found"
msgstr "Conta nova não encontrada"
#: accounts/templates/accounts/change_secret_report.html:92
#: accounts/templates/accounts/push_account_report.html:92
#: accounts/templates/accounts/change_secret_report.html:94
#: accounts/templates/accounts/push_account_report.html:94
msgid "Failed accounts"
msgstr "Contas com falha"
#: accounts/templates/accounts/check_account_report.html:13
#: accounts/templates/accounts/check_account_report.html:14
#: accounts/templates/accounts/gather_account_report.html:14
msgid ""
"The following is a summary of the account check tasks. Please review and "
@ -1793,21 +1803,21 @@ msgstr ""
"A seguir, está o resumo das tarefas de verificação de conta, por favor, "
"consulte e trate"
#: accounts/templates/accounts/check_account_report.html:42
#: accounts/templates/accounts/check_account_report.html:43
msgid "Ok count"
msgstr "Número de sucessos"
#: accounts/templates/accounts/check_account_report.html:46
#: accounts/templates/accounts/check_account_report.html:47
msgid "No password count"
msgstr "SemSenhaNum"
#: accounts/templates/accounts/check_account_report.html:80
#: assets/models/automations/base.py:153 ops/models/base.py:51
#: accounts/templates/accounts/check_account_report.html:81
#: assets/models/automations/base.py:156 ops/models/base.py:51
#: ops/models/job.py:235 xpack/plugins/cloud/models.py:225
msgid "Result"
msgstr "Resultado"
#: accounts/templates/accounts/check_account_report.html:95
#: accounts/templates/accounts/check_account_report.html:96
msgid "No weak password"
msgstr "SemSenhaFraca"
@ -1819,7 +1829,7 @@ msgstr "ContaNovaDescoberta"
msgid "Lost accounts"
msgstr "ContaPerdida"
#: accounts/templates/accounts/push_account_report.html:13
#: accounts/templates/accounts/push_account_report.html:15
msgid ""
"The following is a summary of account push tasks, please read and process"
msgstr ""
@ -2137,28 +2147,28 @@ msgstr "O nome do nó no mesmo nível não pode ser repetido"
msgid "App Assets"
msgstr "Gestão de ativos"
#: assets/automations/base/manager.py:332
#: assets/automations/base/manager.py:347
msgid " - Platform {} ansible disabled"
msgstr " - Plataforma {} Ansible foi desabilitada, impossível executar tarefas"
#: assets/automations/base/manager.py:514
#: assets/automations/base/manager.py:530
msgid ">>> Task preparation phase"
msgstr ">>> Preparando para executar tarefas"
#: assets/automations/base/manager.py:518
#: assets/automations/base/manager.py:534
#, python-brace-format
msgid ">>> Executing tasks in batches, total {runner_count}"
msgstr ">>> Executando tarefas em partes, total de {runner_count}"
#: assets/automations/base/manager.py:523
#: assets/automations/base/manager.py:539
msgid ">>> Start executing tasks"
msgstr ">>> Começando a executar tarefas"
#: assets/automations/base/manager.py:525
#: assets/automations/base/manager.py:541
msgid ">>> No tasks need to be executed"
msgstr ">>> Não há tarefas para executar"
#: assets/automations/base/manager.py:529
#: assets/automations/base/manager.py:545
#, python-brace-format
msgid ">>> Begin executing batch {index} of tasks"
msgstr ">>> Começando a executar o lote {index} de tarefas"
@ -2596,27 +2606,33 @@ msgstr "Nó"
msgid "Parameters"
msgstr "Parâmetros"
#: assets/models/automations/base.py:41 assets/models/automations/base.py:128
#: assets/models/automations/base.py:31
#, fuzzy
#| msgid "Last execution"
msgid "Last execution date"
msgstr "Última Ação"
#: assets/models/automations/base.py:44 assets/models/automations/base.py:131
msgid "Automation task"
msgstr "Tarefas de automação"
#: assets/models/automations/base.py:119
#: assets/models/automations/base.py:122
msgid "Asset automation task"
msgstr "Tarefas de Automação de Ativos"
#: assets/models/automations/base.py:136 assets/models/cmd_filter.py:41
#: assets/models/automations/base.py:139 assets/models/cmd_filter.py:41
#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:238
#: users/models/user/__init__.py:322
msgid "Date created"
msgstr "Data de criação"
#: assets/models/automations/base.py:150
#: assets/models/automations/base.py:153
#: assets/serializers/automations/base.py:44 xpack/plugins/cloud/models.py:242
#: xpack/plugins/cloud/serializers/task.py:249
msgid "Trigger mode"
msgstr "Modo de Trigger"
#: assets/models/automations/base.py:152 audits/serializers.py:39
#: assets/models/automations/base.py:155 audits/serializers.py:39
#: ops/models/base.py:52 ops/models/job.py:236
#: xpack/plugins/cloud/manager.py:103
msgid "Summary"
@ -7262,7 +7278,9 @@ msgstr ""
"após modificar o perfil, pode ser um wiki ou outros documentos de instrução"
#: settings/serializers/basic.py:22
msgid "Global organization"
#, fuzzy
#| msgid "Global organization"
msgid "Global org display"
msgstr "Nome da organização global"
#: settings/serializers/basic.py:23

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-28 18:37+0800\n"
"POT-Creation-Date: 2025-03-07 15:03+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"
@ -25,7 +25,7 @@ msgstr ""
msgid "Account already exists"
msgstr "帳號已存在"
#: accounts/api/account/application.py:77
#: accounts/api/account/application.py:78
#: authentication/api/connection_token.py:449
msgid "Account not found"
msgstr "帳號未找到"
@ -49,8 +49,8 @@ msgstr "生成資產相關備份信息文件"
#: accounts/automations/backup_account/handlers.py:168
#: accounts/automations/backup_account/manager.py:26
#: accounts/automations/change_secret/manager.py:95
#: accounts/automations/push_account/manager.py:59
#: assets/models/automations/base.py:142 ops/serializers/job.py:71
#: accounts/automations/push_account/manager.py:61
#: assets/models/automations/base.py:145 ops/serializers/job.py:71
#: ops/serializers/job.py:95
#: settings/templates/ldap/_msg_import_ldap_user.html:7
#: terminal/serializers/session.py:49
@ -61,23 +61,27 @@ msgstr "花費時間"
msgid "Backup file creation completed"
msgstr "建立備份檔案完成"
#: accounts/automations/backup_account/handlers.py:203
#: accounts/automations/backup_account/handlers.py:177
msgid "Start sending backup emails"
msgstr "開始發送備份電子郵件"
#: accounts/automations/backup_account/handlers.py:204
msgid "Encrypting files using encryption password"
msgstr "使用加密密碼對檔案進行加密中"
#: accounts/automations/backup_account/handlers.py:213
#: accounts/automations/backup_account/handlers.py:214
msgid "The backup file will be sent to"
msgstr "備份檔案將被傳送至"
#: accounts/automations/backup_account/handlers.py:236
#: accounts/automations/backup_account/handlers.py:237
msgid "The backup task has no assigned sftp server"
msgstr "該備份任務未分配sftp伺服器"
#: accounts/automations/backup_account/handlers.py:257
#: accounts/automations/backup_account/handlers.py:258
msgid "The backup task has no assigned recipient"
msgstr "備份任務沒有指定收件人"
#: accounts/automations/backup_account/handlers.py:280
#: accounts/automations/backup_account/handlers.py:281
msgid "Plan start"
msgstr "Action開始"
@ -87,11 +91,11 @@ msgstr "帳號備份計劃正在執行"
#: accounts/automations/backup_account/manager.py:24
#: accounts/automations/change_secret/manager.py:93
#: accounts/automations/push_account/manager.py:57
#: accounts/automations/push_account/manager.py:59
msgid "Plan execution end"
msgstr "計劃執行結束"
#: accounts/automations/base/manager.py:106
#: accounts/automations/base/manager.py:109
msgid "No pending accounts found"
msgstr "未找到待處理帳戶"
@ -100,6 +104,12 @@ msgstr "未找到待處理帳戶"
msgid "Success: %s, Failed: %s, Total: %s"
msgstr "成功: %s, 失敗: %s, 總數: %s"
#: accounts/automations/push_account/manager.py:31
#, fuzzy
#| msgid "The {} cannot be empty"
msgid "Secret cannot be empty"
msgstr "{} 不能為空"
#: accounts/automations/verify_gateway_account/manager.py:18
msgid ">>> Start executing the task to test gateway account connectivity"
msgstr ">>> 開始執行測試閘道器帳號可連結性的任務"
@ -424,13 +434,13 @@ msgstr "用戶 %s 查看/匯出 了密碼"
#: accounts/serializers/automations/gather_account.py:47
#: accounts/templates/accounts/asset_account_change_info.html:7
#: accounts/templates/accounts/change_secret_failed_info.html:11
#: accounts/templates/accounts/change_secret_report.html:70
#: accounts/templates/accounts/change_secret_report.html:102
#: accounts/templates/accounts/check_account_report.html:78
#: accounts/templates/accounts/change_secret_report.html:72
#: accounts/templates/accounts/change_secret_report.html:104
#: accounts/templates/accounts/check_account_report.html:79
#: accounts/templates/accounts/gather_account_report.html:71
#: accounts/templates/accounts/gather_account_report.html:103
#: accounts/templates/accounts/push_account_report.html:70
#: accounts/templates/accounts/push_account_report.html:102
#: accounts/templates/accounts/push_account_report.html:72
#: accounts/templates/accounts/push_account_report.html:104
#: acls/serializers/base.py:130 assets/models/asset/common.py:102
#: assets/models/asset/common.py:366 assets/models/cmd_filter.py:36
#: audits/models.py:59 audits/models.py:312 audits/serializers.py:228
@ -493,7 +503,7 @@ msgstr "改密狀態"
#: accounts/models/account.py:85
#: accounts/models/automations/check_account.py:67
#: accounts/serializers/account/service.py:10
#: accounts/serializers/account/service.py:11
#: accounts/serializers/automations/change_secret.py:115
#: accounts/serializers/automations/change_secret.py:146
#: accounts/templates/accounts/change_secret_failed_info.html:12
@ -537,7 +547,7 @@ msgstr "可以移除帳號"
#: accounts/models/application.py:16
#: accounts/models/automations/check_account.py:119 accounts/models/base.py:63
#: accounts/serializers/account/service.py:26
#: accounts/serializers/account/service.py:27
#: accounts/serializers/account/virtual.py:20 acls/models/base.py:35
#: acls/models/base.py:96 acls/models/command_acl.py:21
#: acls/serializers/base.py:35 assets/models/asset/common.py:100
@ -705,7 +715,7 @@ msgstr "SSH 金鑰推送方式"
msgid "Check connection after change"
msgstr "更改後檢查連接"
#: accounts/models/automations/change_secret.py:16
#: accounts/models/automations/change_secret.py:17
#: accounts/models/automations/check_account.py:19
#: accounts/models/automations/gather_account.py:92
#: accounts/serializers/automations/change_secret.py:59
@ -714,22 +724,22 @@ msgstr "更改後檢查連接"
msgid "Recipient"
msgstr "收件人"
#: accounts/models/automations/change_secret.py:23
#: accounts/models/automations/change_secret.py:24
msgid "Change secret automation"
msgstr "自動化改密"
#: accounts/models/automations/change_secret.py:46
#: assets/models/automations/base.py:141 ops/models/base.py:56
#: accounts/models/automations/change_secret.py:47
#: assets/models/automations/base.py:144 ops/models/base.py:56
#: ops/models/celery.py:90 ops/models/job.py:240
#: terminal/models/applet/host.py:142
msgid "Date finished"
msgstr "結束日期"
#: accounts/models/automations/change_secret.py:48
#: accounts/models/automations/change_secret.py:49
#: accounts/models/automations/check_account.py:75
#: accounts/models/automations/gather_account.py:25
#: accounts/serializers/automations/check_account.py:39
#: assets/models/automations/base.py:133
#: assets/models/automations/base.py:136
#: assets/serializers/automations/base.py:45 audits/models.py:209
#: audits/serializers.py:78 ops/models/base.py:49 ops/models/job.py:231
#: terminal/models/applet/applet.py:331 terminal/models/applet/host.py:140
@ -743,7 +753,7 @@ msgstr "結束日期"
msgid "Status"
msgstr "狀態"
#: accounts/models/automations/change_secret.py:50
#: accounts/models/automations/change_secret.py:51
#: accounts/serializers/account/account.py:276
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
@ -754,19 +764,19 @@ msgstr "狀態"
msgid "Error"
msgstr "錯誤"
#: accounts/models/automations/change_secret.py:66
#: accounts/models/automations/change_secret.py:73
msgid "Old secret"
msgstr "原金鑰"
#: accounts/models/automations/change_secret.py:67
#: accounts/models/automations/change_secret.py:74
msgid "New secret"
msgstr "新金鑰"
#: accounts/models/automations/change_secret.py:68
#: accounts/models/automations/change_secret.py:75
msgid "Ignore fail"
msgstr "忽略失敗"
#: accounts/models/automations/change_secret.py:71
#: accounts/models/automations/change_secret.py:78
msgid "Change secret record"
msgstr "改密記錄"
@ -820,8 +830,8 @@ msgid "Long time no change"
msgstr "長時間未改密"
#: accounts/models/automations/check_account.py:52
#: accounts/templates/accounts/check_account_report.html:69
#: accounts/templates/accounts/check_account_report.html:89
#: accounts/templates/accounts/check_account_report.html:70
#: accounts/templates/accounts/check_account_report.html:90
msgid "Weak password"
msgstr "弱密碼"
@ -848,13 +858,13 @@ msgstr "其它"
#: accounts/models/automations/check_account.py:64
#: accounts/models/automations/gather_account.py:17 accounts/models/base.py:64
#: accounts/serializers/account/virtual.py:21
#: accounts/templates/accounts/change_secret_report.html:71
#: accounts/templates/accounts/change_secret_report.html:103
#: accounts/templates/accounts/check_account_report.html:79
#: accounts/templates/accounts/change_secret_report.html:73
#: accounts/templates/accounts/change_secret_report.html:105
#: accounts/templates/accounts/check_account_report.html:80
#: accounts/templates/accounts/gather_account_report.html:72
#: accounts/templates/accounts/gather_account_report.html:104
#: accounts/templates/accounts/push_account_report.html:71
#: accounts/templates/accounts/push_account_report.html:103
#: accounts/templates/accounts/push_account_report.html:73
#: accounts/templates/accounts/push_account_report.html:105
#: acls/serializers/base.py:19 acls/serializers/base.py:50 audits/models.py:189
#: authentication/forms.py:21 authentication/forms.py:23
#: authentication/models/temp_token.py:9
@ -1272,12 +1282,12 @@ msgstr ""
"提示:如果認證時不需要使用者名稱,可填寫為 null如果是 AD 帳號,格式為 "
"username@domain"
#: accounts/serializers/account/service.py:12
#: accounts/serializers/account/service.py:13
#: authentication/serializers/token.py:22
msgid "Access IP"
msgstr "IP 白名單"
#: accounts/serializers/account/service.py:25
#: accounts/serializers/account/service.py:26
#: accounts/serializers/account/virtual.py:19 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 common/db/models.py:36 ops/models/adhoc.py:25
#: ops/models/job.py:163 ops/models/playbook.py:31 rbac/models/role.py:37
@ -1292,9 +1302,9 @@ msgstr "IP 白名單"
msgid "Comment"
msgstr "備註"
#: accounts/serializers/account/service.py:27
#: accounts/templates/accounts/backup_account_report.html:38
#: accounts/templates/accounts/check_account_report.html:38
#: accounts/serializers/account/service.py:28
#: accounts/templates/accounts/backup_account_report.html:39
#: accounts/templates/accounts/check_account_report.html:39
#: assets/serializers/asset/common.py:151
msgid "Accounts amount"
msgstr "帳號數量"
@ -1388,7 +1398,7 @@ msgid "Name already exists"
msgstr "名稱已存在"
#: accounts/serializers/automations/base.py:31
#: assets/models/automations/base.py:144
#: assets/models/automations/base.py:147
#: assets/serializers/automations/base.py:43
msgid "Automation snapshot"
msgstr "自動化快照"
@ -1416,8 +1426,8 @@ msgid "* Please enter the correct password length"
msgstr "* 請輸入正確的密碼長度"
#: accounts/serializers/automations/change_secret.py:90
msgid "* Password length range 6-30 bits"
msgstr "* 密碼長度範圍 6-30 位"
msgid "* Password length range 8-36 bits"
msgstr "* 密碼長度範圍 8-36 位"
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:147
@ -1426,7 +1436,7 @@ msgid "Is success"
msgstr "是否成功"
#: accounts/serializers/automations/change_secret.py:119
#: assets/models/automations/base.py:160
#: assets/models/automations/base.py:163
msgid "Automation task execution"
msgstr "自動化任務執行歷史"
@ -1583,28 +1593,28 @@ msgstr "測試帳號可連接性"
msgid "Deleted account"
msgstr "刪除帳號"
#: accounts/templates/accounts/backup_account_report.html:13
#: accounts/templates/accounts/backup_account_report.html:14
msgid ""
"The following is a summary of account backup tasks, please review and handle "
"them"
msgstr "以下是帳戶備份任務的概要,請查閱並處理。"
#: accounts/templates/accounts/backup_account_report.html:22
#: accounts/templates/accounts/backup_account_report.html:23
#: accounts/templates/accounts/change_secret_failed_info.html:3
#: accounts/templates/accounts/change_secret_report.html:22
#: accounts/templates/accounts/check_account_report.html:22
#: accounts/templates/accounts/change_secret_report.html:24
#: accounts/templates/accounts/check_account_report.html:23
#: accounts/templates/accounts/gather_account_report.html:23
#: accounts/templates/accounts/push_account_report.html:22
#: accounts/templates/accounts/push_account_report.html:24
#: terminal/serializers/task.py:10
msgid "Task name"
msgstr "任務名稱"
#: accounts/templates/accounts/backup_account_report.html:26
#: accounts/templates/accounts/change_secret_report.html:26
#: accounts/templates/accounts/check_account_report.html:26
#: accounts/templates/accounts/backup_account_report.html:27
#: accounts/templates/accounts/change_secret_report.html:28
#: accounts/templates/accounts/check_account_report.html:27
#: accounts/templates/accounts/gather_account_report.html:27
#: accounts/templates/accounts/push_account_report.html:26
#: assets/models/automations/base.py:139 audits/models.py:66
#: accounts/templates/accounts/push_account_report.html:28
#: assets/models/automations/base.py:142 audits/models.py:66
#: ops/models/base.py:55 ops/models/celery.py:89 ops/models/job.py:239
#: ops/templates/ops/celery_task_log.html:101
#: perms/models/asset_permission.py:78 settings/serializers/feature.py:27
@ -1615,26 +1625,26 @@ msgstr "任務名稱"
msgid "Date start"
msgstr "開始日期"
#: accounts/templates/accounts/backup_account_report.html:30
#: accounts/templates/accounts/change_secret_report.html:30
#: accounts/templates/accounts/check_account_report.html:30
#: accounts/templates/accounts/backup_account_report.html:31
#: accounts/templates/accounts/change_secret_report.html:32
#: accounts/templates/accounts/check_account_report.html:31
#: accounts/templates/accounts/gather_account_report.html:31
#: accounts/templates/accounts/push_account_report.html:30
#: accounts/templates/accounts/push_account_report.html:32
#: settings/serializers/feature.py:28
#: settings/templates/ldap/_msg_import_ldap_user.html:6
#: terminal/models/session/session.py:48
msgid "Date end"
msgstr "結束日期"
#: accounts/templates/accounts/backup_account_report.html:34
#: accounts/templates/accounts/change_secret_report.html:34
#: accounts/templates/accounts/check_account_report.html:34
#: accounts/templates/accounts/backup_account_report.html:35
#: accounts/templates/accounts/change_secret_report.html:36
#: accounts/templates/accounts/check_account_report.html:35
#: accounts/templates/accounts/gather_account_report.html:35
#: accounts/templates/accounts/push_account_report.html:34
#: accounts/templates/accounts/push_account_report.html:36
msgid "Time using"
msgstr "耗時"
#: accounts/templates/accounts/backup_account_report.html:42
#: accounts/templates/accounts/backup_account_report.html:43
msgid "Type count"
msgstr "類型數"
@ -1652,93 +1662,93 @@ msgid ""
"or pushing the account. Please check and handle it in time."
msgstr "你好! 以下是資產改密或推送帳戶失敗的情況。 請及時檢查並處理。"
#: accounts/templates/accounts/change_secret_report.html:13
#: accounts/templates/accounts/change_secret_report.html:15
msgid ""
"The following is a summary of account change secret tasks, please read and "
"process"
msgstr "以下是帳號更改秘密任務的摘要,請閱讀並處理"
#: accounts/templates/accounts/change_secret_report.html:38
#: accounts/templates/accounts/change_secret_report.html:40
#: accounts/templates/accounts/gather_account_report.html:39
#: accounts/templates/accounts/push_account_report.html:38
#: accounts/templates/accounts/push_account_report.html:40
#: assets/serializers/domain.py:24 assets/serializers/platform.py:182
#: orgs/serializers.py:13 perms/serializers/permission.py:50
msgid "Assets amount"
msgstr "資產數量"
#: accounts/templates/accounts/change_secret_report.html:42
#: accounts/templates/accounts/check_account_report.html:50
#: accounts/templates/accounts/change_secret_report.html:44
#: accounts/templates/accounts/check_account_report.html:51
#: accounts/templates/accounts/gather_account_report.html:43
#: accounts/templates/accounts/push_account_report.html:42
#: accounts/templates/accounts/push_account_report.html:44
msgid "Asset success count"
msgstr "資產成功數"
#: accounts/templates/accounts/change_secret_report.html:46
#: accounts/templates/accounts/check_account_report.html:54
#: accounts/templates/accounts/change_secret_report.html:48
#: accounts/templates/accounts/check_account_report.html:55
#: accounts/templates/accounts/gather_account_report.html:47
#: accounts/templates/accounts/push_account_report.html:46
#: accounts/templates/accounts/push_account_report.html:48
msgid "Asset failed count"
msgstr "資產失敗數"
#: accounts/templates/accounts/change_secret_report.html:50
#: accounts/templates/accounts/check_account_report.html:58
#: accounts/templates/accounts/change_secret_report.html:52
#: accounts/templates/accounts/check_account_report.html:59
#: accounts/templates/accounts/gather_account_report.html:51
#: accounts/templates/accounts/push_account_report.html:50
#: accounts/templates/accounts/push_account_report.html:52
msgid "Asset not support count"
msgstr "資產不支援數"
#: accounts/templates/accounts/change_secret_report.html:61
#: accounts/templates/accounts/push_account_report.html:61
#: accounts/templates/accounts/change_secret_report.html:63
#: accounts/templates/accounts/push_account_report.html:63
msgid "Success accounts"
msgstr "成功帳號"
#: accounts/templates/accounts/change_secret_report.html:69
#: accounts/templates/accounts/change_secret_report.html:101
#: accounts/templates/accounts/check_account_report.html:77
#: accounts/templates/accounts/change_secret_report.html:71
#: accounts/templates/accounts/change_secret_report.html:103
#: accounts/templates/accounts/check_account_report.html:78
#: accounts/templates/accounts/gather_account_report.html:70
#: accounts/templates/accounts/gather_account_report.html:102
#: accounts/templates/accounts/push_account_report.html:69
#: accounts/templates/accounts/push_account_report.html:101
#: accounts/templates/accounts/push_account_report.html:71
#: accounts/templates/accounts/push_account_report.html:103
#: audits/handler.py:128
msgid "No"
msgstr "否"
#: accounts/templates/accounts/change_secret_report.html:85
#: accounts/templates/accounts/change_secret_report.html:117
#: accounts/templates/accounts/change_secret_report.html:87
#: accounts/templates/accounts/change_secret_report.html:119
#: accounts/templates/accounts/gather_account_report.html:86
#: accounts/templates/accounts/gather_account_report.html:118
#: accounts/templates/accounts/push_account_report.html:85
#: accounts/templates/accounts/push_account_report.html:117
#: accounts/templates/accounts/push_account_report.html:87
#: accounts/templates/accounts/push_account_report.html:119
msgid "No new accounts found"
msgstr "未找到新帳戶"
#: accounts/templates/accounts/change_secret_report.html:92
#: accounts/templates/accounts/push_account_report.html:92
#: accounts/templates/accounts/change_secret_report.html:94
#: accounts/templates/accounts/push_account_report.html:94
msgid "Failed accounts"
msgstr "失敗帳號"
#: accounts/templates/accounts/check_account_report.html:13
#: accounts/templates/accounts/check_account_report.html:14
#: accounts/templates/accounts/gather_account_report.html:14
msgid ""
"The following is a summary of the account check tasks. Please review and "
"handle them"
msgstr "以下為帳號檢查任務的彙總,請查閱並處理"
#: accounts/templates/accounts/check_account_report.html:42
#: accounts/templates/accounts/check_account_report.html:43
msgid "Ok count"
msgstr "成功數"
#: accounts/templates/accounts/check_account_report.html:46
#: accounts/templates/accounts/check_account_report.html:47
msgid "No password count"
msgstr "無密碼數"
#: accounts/templates/accounts/check_account_report.html:80
#: assets/models/automations/base.py:153 ops/models/base.py:51
#: accounts/templates/accounts/check_account_report.html:81
#: assets/models/automations/base.py:156 ops/models/base.py:51
#: ops/models/job.py:235 xpack/plugins/cloud/models.py:225
msgid "Result"
msgstr "結果"
#: accounts/templates/accounts/check_account_report.html:95
#: accounts/templates/accounts/check_account_report.html:96
msgid "No weak password"
msgstr "無弱密碼"
@ -1750,7 +1760,7 @@ msgstr "新發現的帳戶"
msgid "Lost accounts"
msgstr "遺失的帳號"
#: accounts/templates/accounts/push_account_report.html:13
#: accounts/templates/accounts/push_account_report.html:15
msgid ""
"The following is a summary of account push tasks, please read and process"
msgstr "以下是帳號推送任務的彙總,請閱讀並處理"
@ -2057,28 +2067,28 @@ msgstr "同級別節點名字不能重複"
msgid "App Assets"
msgstr "資產管理"
#: assets/automations/base/manager.py:332
#: assets/automations/base/manager.py:347
msgid " - Platform {} ansible disabled"
msgstr " - 平台 {} Ansible 已禁用, 無法執行任務"
#: assets/automations/base/manager.py:514
#: assets/automations/base/manager.py:530
msgid ">>> Task preparation phase"
msgstr ">>> 任務準備階段"
#: assets/automations/base/manager.py:518
#: assets/automations/base/manager.py:534
#, python-brace-format
msgid ">>> Executing tasks in batches, total {runner_count}"
msgstr ">>> 分次執行任務,總共 {runner_count}"
#: assets/automations/base/manager.py:523
#: assets/automations/base/manager.py:539
msgid ">>> Start executing tasks"
msgstr ">>> 開始執行任務"
#: assets/automations/base/manager.py:525
#: assets/automations/base/manager.py:541
msgid ">>> No tasks need to be executed"
msgstr ">>> 沒有需要執行的任務"
#: assets/automations/base/manager.py:529
#: assets/automations/base/manager.py:545
#, python-brace-format
msgid ">>> Begin executing batch {index} of tasks"
msgstr ">>> 開始執行第 {index} 批任務"
@ -2508,29 +2518,35 @@ msgstr "節點"
msgid "Parameters"
msgstr "參數"
#: assets/models/automations/base.py:41 assets/models/automations/base.py:128
#: assets/models/automations/base.py:31
#, fuzzy
#| msgid "Last execution"
msgid "Last execution date"
msgstr "最後執行"
#: assets/models/automations/base.py:44 assets/models/automations/base.py:131
msgid "Automation task"
msgstr "自動化任務"
#: assets/models/automations/base.py:119
#: assets/models/automations/base.py:122
msgid "Asset automation task"
msgstr "資產自動化任務"
# msgid "Comment"
# msgstr "備註"
#: assets/models/automations/base.py:136 assets/models/cmd_filter.py:41
#: assets/models/automations/base.py:139 assets/models/cmd_filter.py:41
#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:238
#: users/models/user/__init__.py:322
msgid "Date created"
msgstr "創建日期"
#: assets/models/automations/base.py:150
#: assets/models/automations/base.py:153
#: assets/serializers/automations/base.py:44 xpack/plugins/cloud/models.py:242
#: xpack/plugins/cloud/serializers/task.py:249
msgid "Trigger mode"
msgstr "觸發模式"
#: assets/models/automations/base.py:152 audits/serializers.py:39
#: assets/models/automations/base.py:155 audits/serializers.py:39
#: ops/models/base.py:52 ops/models/job.py:236
#: xpack/plugins/cloud/manager.py:103
msgid "Summary"
@ -7008,7 +7024,9 @@ msgid "User first login update profile done redirect to it"
msgstr "用戶第一次登錄修改profile後重定向到地址, 可以是 wiki 或 其他說明文件"
#: settings/serializers/basic.py:22
msgid "Global organization"
#, fuzzy
#| msgid "Global organization"
msgid "Global org display"
msgstr "全球組織名稱"
#: settings/serializers/basic.py:23

View File

@ -16,6 +16,7 @@
"AccountBackupTask": "Account backup task | Account backup tasks",
"AccountBackupUpdate": "Update account backup",
"AccountChangeSecretDetail": "Change account secret details",
"AccountChangeSecret": "Account change secret",
"AccountData": "Account data",
"AccountDeleteConfirmMsg": "Delete account, continue?",
"AccountDeleted": "Account deleted",
@ -270,7 +271,8 @@
"ChangeField": "Change field",
"ChangeOrganization": "Change organization",
"ChangePassword": "Change password",
"ChangeSecret": "Change secrets",
"ChangeSecret": "Change secret",
"MenuChangeSecret": "Change secrets",
"ChangeSecretAccountHelpText": "For accounts in the same asset, if there is a switch-from relationship, the password change should not be performed in the same task, but should be divided into two tasks for execution separately.",
"ChangeSecretFailAccounts": "Secret change failed Accounts",
"ChangeSecretParams": "Change secret parameters",
@ -308,7 +310,7 @@
"CloudCreate": "Create asset - cloud",
"CloudRegionTip": "The region was not obtained, please check the account",
"CloudSource": "Sync source",
"CloudSync": "Cloud provider",
"CloudSync": "Cloud sync",
"CloudSyncConfig": "Cloud sync settings",
"CloudUpdate": "Update the asset - cloud",
"Cluster": "Cluster",
@ -474,6 +476,7 @@
"DisableSuccessMsg": "Successfully disabled",
"DiscoverAccountTask": "Account discovery task | Account discovery tasks",
"DiscoverAccounts": "Discover accounts",
"DiscoverAccountDetail": "Discover account details",
"DiscoverAccountsHelpText": "Collect account information on assets. the collected account information can be imported into the system for centralized management.",
"DiscoveredAccountList": "Discovered accounts",
"DisplayName": "Name",
@ -1093,7 +1096,7 @@
"Rule": "Condition",
"RuleCount": "Condition quantity",
"RuleDetail": "Rule details",
"RuleRelation": "Relationship conditions",
"RuleRelation": "Rule relation",
"RuleRelationHelpTip": "And: the action will be executed only when all conditions are met; or: the action will be executed as long as one condition is met",
"RuleSetting": "Condition settings",
"Rules": "Rules",
@ -1358,8 +1361,8 @@
"TotalJobFailed": "Failed execution actions",
"TotalJobLog": "Total job executions",
"TotalJobRunning": "Running jobs",
"TotalSyncAsset": "Assets",
"TotalSyncRegion": "Regions",
"TotalSyncAsset": "Synced Assets",
"TotalSyncRegion": "Sync Regions",
"TotalSyncStrategy": "Number of strategies",
"Transfer": "Transfer",
"TriggerMode": "Trigger mode",
@ -1503,5 +1506,14 @@
"forceEnableMFAHelpText": "If force enable, user can not disable by themselves",
"removeWarningMsg": "Are you sure you want to remove",
"setVariable": "Set variable",
"IgnoreAlert": "Ignore alert"
"IgnoreAlert": "Ignore alert",
"DeleteGatherAccountTitle": "Delete gather account",
"DeleteRemoteAccount": "Delete remote account",
"AddAccountAfterChangingPassword": "Add account after changing password",
"ExecutionID": "Execution ID",
"Invalid": "Invalid",
"Disabled": "Disabled",
"IgnoreFail": "Ignore fail",
"RiskDetectionDetail": "Risk detection detail",
"ApplicationDetail": "Application detail"
}

View File

@ -473,6 +473,7 @@
"DisableSuccessMsg": "禁用成功",
"DiscoverAccountTask": "账号发现任务",
"DiscoverAccounts": "帐号发现",
"DiscoverAccountDetail": "帐号发现详情",
"DiscoverAccountsHelpText": "采集资产的账务信息,可将采集到的账务信息导入系统进行集中管理。",
"DiscoveredAccountList": "发现账号",
"DisplayName": "名称",
@ -580,7 +581,7 @@
"Footer": "页脚",
"ForgotPasswordURL": "忘记密码链接",
"FormatError": "格式错误",
"FoundAccountInAssetDeleteMsg": "删除从系统资产中发现的找好",
"FoundAccountInAssetDeleteMsg": "删除从系统资产中发现的账号",
"Friday": "周五",
"From": "从",
"FromTicket": "来自工单",
@ -785,6 +786,7 @@
"MenuMore": "其它",
"MenuPermissions": "授权管理",
"MenuUsers": "用户管理",
"MenuChangeSecret": "账号改密",
"Message": "消息",
"MessageType": "消息类型",
"MfaLevel": "多因子认证",
@ -1025,7 +1027,7 @@
"RelevantCommand": "命令",
"RelevantSystemUser": "系统用户",
"RemoteAddr": "远端地址",
"RemoteAssetFoundAccountDeleteMsg": "删除从远端资产中发现的找好",
"RemoteAssetFoundAccountDeleteMsg": "删除从远端资产中发现的账号",
"Remove": "移除",
"RemoveAssetFromNode": "从节点移除资产",
"RemoveSelected": "移除所选",
@ -1503,5 +1505,14 @@
"forceEnableMFAHelpText": "如果强制启用,用户无法自行禁用",
"removeWarningMsg": "你确定要移除",
"setVariable": "设置参数",
"IgnoreAlert": "忽略警报"
"IgnoreAlert": "忽略警报",
"DeleteGatherAccountTitle": "删除发现的账号",
"DeleteRemoteAccount": "删除远端账号",
"AddAccountAfterChangingPassword": "修改密码后添加账号",
"ExecutionID": "执行 ID",
"Invalid": "无效",
"Disabled": "已禁用",
"IgnoreFail": "忽略失败",
"RiskDetectionDetail": "风险检测详情",
"ApplicationDetail": "应用详情"
}

View File

@ -19,7 +19,7 @@ class BasicSettingSerializer(serializers.Serializer):
help_text=_('User first login update profile done redirect to it')
)
GLOBAL_ORG_DISPLAY_NAME = serializers.CharField(
required=False, max_length=1024, allow_blank=True, allow_null=True, label=_("Global organization"),
required=False, max_length=1024, allow_blank=True, allow_null=True, label=_("Global org display"),
help_text=_('The name of global organization to display')
)
HELP_DOCUMENT_URL = serializers.URLField(

View File

@ -1,14 +1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import base64
import struct
import uuid
import math
from django.conf import settings
from django.contrib.auth.models import AbstractUser, UserManager as _UserManager
from django.core.exceptions import ValidationError
from django.db import models
from django.shortcuts import reverse
from django.utils import timezone
@ -17,17 +13,16 @@ from rest_framework.exceptions import PermissionDenied
from common.db import fields, models as jms_models
from common.utils import (
date_expired_default,
get_logger,
date_expired_default, get_logger, lazyproperty
)
from labels.mixins import LabeledMixin
from orgs.utils import current_org
from ._auth import AuthMixin, MFAMixin
from ._face import FaceMixin
from ._json import JSONFilterMixin
from ._role import RoleMixin, SystemRoleManager, OrgRoleManager
from ._source import SourceMixin, Source
from ._token import TokenMixin
from ._face import FaceMixin
logger = get_logger(__file__)
__all__ = [
@ -272,7 +267,7 @@ class User(
LoginBlockUtil.unblock_user(self.username)
MFABlockUtils.unblock_user(self.username)
@property
@lazyproperty
def login_blocked(self):
from users.utils import LoginBlockUtil, MFABlockUtils

View File

@ -168,60 +168,43 @@ class UserSerializer(
# mini 是指能识别对象的最小单元
fields_mini = ["id", "name", "username"]
# 只能写的字段, 这个虽然无法在框架上生效,但是更多对我们是提醒
fields_write_only = [
"password",
"public_key",
]
fields_write_only = ["password", "public_key", ]
# xpack 包含的字段
fields_xpack = ["wecom_id", "dingtalk_id", "feishu_id", "lark_id", "slack_id", "is_org_admin", "orgs_roles",
"org_roles"]
fields_xpack = [
"wecom_id", "dingtalk_id", "feishu_id", "lark_id", "slack_id",
"is_org_admin", "orgs_roles", "org_roles"
]
# small 指的是 不需要计算的直接能从一张表中获取到的数据
fields_small = (
fields_mini
+ fields_write_only
+ [
"email",
"wechat",
"phone",
"mfa_level",
"source",
*fields_xpack,
"created_by",
"updated_by",
"comment", # 通用字段
]
fields_mini
+ fields_write_only
+ [
"email", "wechat", "phone", "mfa_level",
"source", *fields_xpack,
"created_by", "updated_by", "comment", # 通用字段
]
)
fields_date = [
"date_expired",
"date_joined",
"last_login",
"date_updated",
"date_api_key_last_used",
"date_expired", "date_joined", "last_login",
"date_updated", "date_api_key_last_used",
]
fields_bool = [
"is_superuser",
"is_org_admin",
"is_service_account",
"is_valid",
"is_expired",
"is_active", # 布尔字段
"is_otp_secret_key_bound",
"can_public_key_auth",
"mfa_enabled",
"need_update_password",
"is_face_code_set",
"is_superuser", "is_org_admin", "is_service_account",
"is_valid", "is_expired", "is_active", # 布尔字段
"is_otp_secret_key_bound", "can_public_key_auth",
"mfa_enabled", "need_update_password", "is_face_code_set",
]
# 包含不太常用的字段,可以没有
fields_verbose = (
fields_small
+ fields_date
+ fields_bool
+ [
"mfa_force_enabled",
"is_first_login",
"date_password_last_updated",
"avatar_url",
]
fields_small
+ fields_date
+ fields_bool
+ [
"mfa_force_enabled",
"is_first_login",
"date_password_last_updated",
"avatar_url",
]
)
# 外键的字段
fields_fk = []

View File

@ -50,6 +50,7 @@ def user_authenticated_handle(user, created, source, attrs=None, **kwargs):
return
if created:
logger.debug(f'Receive user created signal: {user}, Set user source is: {source}')
user.source = source
user.save()
@ -64,7 +65,7 @@ def user_authenticated_handle(user, created, source, attrs=None, **kwargs):
always_update = getattr(settings, 'AUTH_%s_ALWAYS_UPDATE_USER' % source.upper(), False)
if not created and always_update:
attr_whitelist = ('user', 'username', 'email', 'phone', 'comment')
attr_whitelist = ('name', 'username', 'email', 'phone', 'comment')
logger.debug(
"Receive {} user updated signal: {}, "
"Update user info: {},"
@ -129,19 +130,19 @@ def on_user_create(sender, user=None, **kwargs):
@receiver(cas_user_authenticated)
def on_cas_user_authenticated(sender, user, created, **kwargs):
source = user.Source.cas.value
source = User.Source.cas.value
user_authenticated_handle(user, created, source)
@receiver(saml2_create_or_update_user)
def on_saml2_create_or_update_user(sender, user, created, attrs, **kwargs):
source = user.Source.saml2.value
source = User.Source.saml2.value
user_authenticated_handle(user, created, source, attrs, **kwargs)
@receiver(oauth2_create_or_update_user)
def on_oauth2_create_or_update_user(sender, user, created, attrs, **kwargs):
source = user.Source.oauth2.value
source = User.Source.oauth2.value
user_authenticated_handle(user, created, source, attrs, **kwargs)
@ -153,35 +154,14 @@ def radius_create_user(sender, user, **kwargs):
@receiver(openid_create_or_update_user)
def on_openid_create_or_update_user(sender, request, user, created, attrs, **kwargs):
if not check_only_allow_exist_user_auth(created):
return
def on_openid_create_or_update_user(sender, user, created, attrs, **kwargs):
if created:
logger.debug(
"Receive OpenID user created signal: {}, "
"Set user source is: {}".format(user, User.Source.openid.value)
)
user.source = User.Source.openid.value
user.save()
org_ids = bind_user_to_org_role(user)
group_names = attrs.get('groups')
bind_user_to_group(org_ids, group_names, user)
name = attrs.get('name')
username = attrs.get('username')
email = attrs.get('email')
if not created and settings.AUTH_OPENID_ALWAYS_UPDATE_USER:
logger.debug(
"Receive OpenID user updated signal: {}, "
"Update user info: {}"
"".format(user, "name: {}|username: {}|email: {}".format(name, username, email))
)
user.name = name
user.username = username
user.email = email
user.save()
source = User.Source.openid.value
user_authenticated_handle(user, created, source, attrs, **kwargs)
@receiver(populate_user)

View File

@ -96,7 +96,7 @@ REDIS_PORT: 6379
# 仅允许已存在的用户登录,不允许第三方认证后,自动创建用户
# ONLY_ALLOW_EXIST_USER_AUTH: False
# 开启人脸识别
# 开启人脸识别 XPACK 功能
#FACE_RECOGNITION_ENABLED: true
#FACE_RECOGNITION_DISTANCE_THRESHOLD': 0.35
#FACE_RECOGNITION_COSINE_THRESHOLD': 0.95
#FACE_RECOGNITION_COSINE_THRESHOLD': 0.95