mirror of https://github.com/jumpserver/jumpserver
perf: 账号备份优化 (#7503)
* perf: 账号备份优化 * feat: 优化账号备份获取有序备份字段列表 Co-authored-by: feng626 <1304903146@qq.com> Co-authored-by: Michael Bai <baijiangjie@gmail.com>pull/7498/head
parent
d2b3edffca
commit
def9bedd30
|
@ -44,11 +44,7 @@ class ApplicationAccountViewSet(JMSBulkModelViewSet):
|
||||||
permission_classes = (IsOrgAdmin,)
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = Account.objects.all() \
|
queryset = Account.get_queryset()
|
||||||
.annotate(type=F('app__type')) \
|
|
||||||
.annotate(app_display=F('app__name')) \
|
|
||||||
.annotate(systemuser_display=F('systemuser__name')) \
|
|
||||||
.annotate(category=F('app__category'))
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from simple_history.models import HistoricalRecords
|
from simple_history.models import HistoricalRecords
|
||||||
|
from django.db.models import F
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common.utils import lazyproperty
|
from common.utils import lazyproperty
|
||||||
|
@ -7,8 +8,12 @@ from assets.models.base import BaseUser
|
||||||
|
|
||||||
|
|
||||||
class Account(BaseUser):
|
class Account(BaseUser):
|
||||||
app = models.ForeignKey('applications.Application', on_delete=models.CASCADE, null=True, verbose_name=_('Database'))
|
app = models.ForeignKey(
|
||||||
systemuser = models.ForeignKey('assets.SystemUser', on_delete=models.CASCADE, null=True, verbose_name=_("System user"))
|
'applications.Application', on_delete=models.CASCADE, null=True, verbose_name=_('Database')
|
||||||
|
)
|
||||||
|
systemuser = models.ForeignKey(
|
||||||
|
'assets.SystemUser', on_delete=models.CASCADE, null=True, verbose_name=_("System user")
|
||||||
|
)
|
||||||
version = models.IntegerField(default=1, verbose_name=_('Version'))
|
version = models.IntegerField(default=1, verbose_name=_('Version'))
|
||||||
history = HistoricalRecords()
|
history = HistoricalRecords()
|
||||||
|
|
||||||
|
@ -60,6 +65,10 @@ class Account(BaseUser):
|
||||||
def type(self):
|
def type(self):
|
||||||
return self.app.type
|
return self.app.type
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def attrs(self):
|
||||||
|
return self.app.attrs
|
||||||
|
|
||||||
@lazyproperty
|
@lazyproperty
|
||||||
def app_display(self):
|
def app_display(self):
|
||||||
return self.systemuser.name
|
return self.systemuser.name
|
||||||
|
@ -84,5 +93,14 @@ class Account(BaseUser):
|
||||||
app = '*'
|
app = '*'
|
||||||
return '{}@{}'.format(username, app)
|
return '{}@{}'.format(username, app)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_queryset(cls):
|
||||||
|
queryset = cls.objects.all() \
|
||||||
|
.annotate(type=F('app__type')) \
|
||||||
|
.annotate(app_display=F('app__name')) \
|
||||||
|
.annotate(systemuser_display=F('systemuser__name')) \
|
||||||
|
.annotate(category=F('app__category'))
|
||||||
|
return queryset
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.smart_name
|
return self.smart_name
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
#
|
#
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
@ -9,7 +8,8 @@ from assets.serializers.base import AuthSerializerMixin
|
||||||
from common.drf.serializers import MethodSerializer
|
from common.drf.serializers import MethodSerializer
|
||||||
from .attrs import (
|
from .attrs import (
|
||||||
category_serializer_classes_mapping,
|
category_serializer_classes_mapping,
|
||||||
type_serializer_classes_mapping
|
type_serializer_classes_mapping,
|
||||||
|
type_secret_serializer_classes_mapping
|
||||||
)
|
)
|
||||||
from .. import models
|
from .. import models
|
||||||
from .. import const
|
from .. import const
|
||||||
|
@ -23,17 +23,28 @@ __all__ = [
|
||||||
class AppSerializerMixin(serializers.Serializer):
|
class AppSerializerMixin(serializers.Serializer):
|
||||||
attrs = MethodSerializer()
|
attrs = MethodSerializer()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def app(self):
|
||||||
|
if isinstance(self.instance, models.Application):
|
||||||
|
instance = self.instance
|
||||||
|
else:
|
||||||
|
instance = None
|
||||||
|
return instance
|
||||||
|
|
||||||
def get_attrs_serializer(self):
|
def get_attrs_serializer(self):
|
||||||
default_serializer = serializers.Serializer(read_only=True)
|
default_serializer = serializers.Serializer(read_only=True)
|
||||||
if isinstance(self.instance, models.Application):
|
instance = self.app
|
||||||
_type = self.instance.type
|
if instance:
|
||||||
_category = self.instance.category
|
_type = instance.type
|
||||||
|
_category = instance.category
|
||||||
else:
|
else:
|
||||||
_type = self.context['request'].query_params.get('type')
|
_type = self.context['request'].query_params.get('type')
|
||||||
_category = self.context['request'].query_params.get('category')
|
_category = self.context['request'].query_params.get('category')
|
||||||
|
|
||||||
if _type:
|
if _type:
|
||||||
serializer_class = type_serializer_classes_mapping.get(_type)
|
if isinstance(self, AppAccountSecretSerializer):
|
||||||
|
serializer_class = type_secret_serializer_classes_mapping.get(_type)
|
||||||
|
else:
|
||||||
|
serializer_class = type_serializer_classes_mapping.get(_type)
|
||||||
elif _category:
|
elif _category:
|
||||||
serializer_class = category_serializer_classes_mapping.get(_category)
|
serializer_class = category_serializer_classes_mapping.get(_category)
|
||||||
else:
|
else:
|
||||||
|
@ -84,11 +95,13 @@ class MiniAppSerializer(serializers.ModelSerializer):
|
||||||
fields = AppSerializer.Meta.fields_mini
|
fields = AppSerializer.Meta.fields_mini
|
||||||
|
|
||||||
|
|
||||||
class AppAccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
class AppAccountSerializer(AppSerializerMixin, AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
category = serializers.ChoiceField(label=_('Category'), choices=const.AppCategory.choices, read_only=True)
|
category = serializers.ChoiceField(label=_('Category'), choices=const.AppCategory.choices, read_only=True)
|
||||||
category_display = serializers.SerializerMethodField(label=_('Category display'))
|
category_display = serializers.SerializerMethodField(label=_('Category display'))
|
||||||
type = serializers.ChoiceField(label=_('Type'), choices=const.AppType.choices, read_only=True)
|
type = serializers.ChoiceField(label=_('Type'), choices=const.AppType.choices, read_only=True)
|
||||||
type_display = serializers.SerializerMethodField(label=_('Type display'))
|
type_display = serializers.SerializerMethodField(label=_('Type display'))
|
||||||
|
date_created = serializers.DateTimeField(label=_('Date created'), format="%Y/%m/%d %H:%M:%S", read_only=True)
|
||||||
|
date_updated = serializers.DateTimeField(label=_('Date updated'), format="%Y/%m/%d %H:%M:%S", read_only=True)
|
||||||
|
|
||||||
category_mapper = dict(const.AppCategory.choices)
|
category_mapper = dict(const.AppCategory.choices)
|
||||||
type_mapper = dict(const.AppType.choices)
|
type_mapper = dict(const.AppType.choices)
|
||||||
|
@ -96,10 +109,11 @@ class AppAccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Account
|
model = models.Account
|
||||||
fields_mini = ['id', 'username', 'version']
|
fields_mini = ['id', 'username', 'version']
|
||||||
fields_write_only = ['password', 'private_key', 'passphrase']
|
fields_write_only = ['password', 'private_key', 'public_key', 'passphrase']
|
||||||
|
fields_other = ['date_created', 'date_updated']
|
||||||
fields_fk = ['systemuser', 'systemuser_display', 'app', 'app_display']
|
fields_fk = ['systemuser', 'systemuser_display', 'app', 'app_display']
|
||||||
fields = fields_mini + fields_fk + fields_write_only + [
|
fields = fields_mini + fields_fk + fields_write_only + fields_other + [
|
||||||
'type', 'type_display', 'category', 'category_display',
|
'type', 'type_display', 'category', 'category_display', 'attrs'
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'username': {'default': '', 'required': False},
|
'username': {'default': '', 'required': False},
|
||||||
|
@ -112,6 +126,14 @@ class AppAccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
'ignore_conflicts': True
|
'ignore_conflicts': True
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def app(self):
|
||||||
|
if isinstance(self.instance, models.Account):
|
||||||
|
instance = self.instance.app
|
||||||
|
else:
|
||||||
|
instance = None
|
||||||
|
return instance
|
||||||
|
|
||||||
def get_category_display(self, obj):
|
def get_category_display(self, obj):
|
||||||
return self.category_mapper.get(obj.category)
|
return self.category_mapper.get(obj.category)
|
||||||
|
|
||||||
|
@ -131,6 +153,10 @@ class AppAccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
|
|
||||||
class AppAccountSecretSerializer(AppAccountSerializer):
|
class AppAccountSecretSerializer(AppAccountSerializer):
|
||||||
class Meta(AppAccountSerializer.Meta):
|
class Meta(AppAccountSerializer.Meta):
|
||||||
|
fields_backup = [
|
||||||
|
'id', 'app_display', 'attrs', 'username', 'password', 'private_key',
|
||||||
|
'public_key', 'date_created', 'date_updated', 'version'
|
||||||
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'password': {'write_only': False},
|
'password': {'write_only': False},
|
||||||
'private_key': {'write_only': False},
|
'private_key': {'write_only': False},
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['CloudSerializer']
|
__all__ = ['CloudSerializer']
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ from assets.models import Asset
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['RemoteAppSerializer']
|
__all__ = ['RemoteAppSerializer']
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from ..application_category import RemoteAppSerializer
|
from ..application_category import RemoteAppSerializer
|
||||||
|
|
||||||
|
__all__ = ['ChromeSerializer', 'ChromeSecretSerializer']
|
||||||
__all__ = ['ChromeSerializer']
|
|
||||||
|
|
||||||
|
|
||||||
class ChromeSerializer(RemoteAppSerializer):
|
class ChromeSerializer(RemoteAppSerializer):
|
||||||
|
@ -17,10 +16,16 @@ class ChromeSerializer(RemoteAppSerializer):
|
||||||
max_length=128, allow_blank=True, required=False, label=_('Target URL'), allow_null=True,
|
max_length=128, allow_blank=True, required=False, label=_('Target URL'), allow_null=True,
|
||||||
)
|
)
|
||||||
chrome_username = serializers.CharField(
|
chrome_username = serializers.CharField(
|
||||||
max_length=128, allow_blank=True, required=False, label=_('Username'), allow_null=True,
|
max_length=128, allow_blank=True, required=False, label=_('Chrome username'), allow_null=True,
|
||||||
)
|
)
|
||||||
chrome_password = serializers.CharField(
|
chrome_password = serializers.CharField(
|
||||||
max_length=128, allow_blank=True, required=False, write_only=True, label=_('Password'),
|
max_length=128, allow_blank=True, required=False, write_only=True, label=_('Chrome password'),
|
||||||
allow_null=True
|
allow_null=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ChromeSecretSerializer(ChromeSerializer):
|
||||||
|
chrome_password = serializers.CharField(
|
||||||
|
max_length=128, allow_blank=True, required=False, read_only=True, label=_('Chrome password'),
|
||||||
|
allow_null=True
|
||||||
|
)
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from ..application_category import RemoteAppSerializer
|
from ..application_category import RemoteAppSerializer
|
||||||
|
|
||||||
|
__all__ = ['CustomSerializer', 'CustomSecretSerializer']
|
||||||
__all__ = ['CustomSerializer']
|
|
||||||
|
|
||||||
|
|
||||||
class CustomSerializer(RemoteAppSerializer):
|
class CustomSerializer(RemoteAppSerializer):
|
||||||
|
@ -18,10 +16,17 @@ class CustomSerializer(RemoteAppSerializer):
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
)
|
)
|
||||||
custom_username = serializers.CharField(
|
custom_username = serializers.CharField(
|
||||||
max_length=128, allow_blank=True, required=False, label=_('Username'),
|
max_length=128, allow_blank=True, required=False, label=_('Custom Username'),
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
)
|
)
|
||||||
custom_password = serializers.CharField(
|
custom_password = serializers.CharField(
|
||||||
max_length=128, allow_blank=True, required=False, write_only=True, label=_('Password'),
|
max_length=128, allow_blank=True, required=False, write_only=True, label=_('Custom password'),
|
||||||
|
allow_null=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomSecretSerializer(RemoteAppSerializer):
|
||||||
|
custom_password = serializers.CharField(
|
||||||
|
max_length=128, allow_blank=True, required=False, read_only=True, label=_('Custom password'),
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from ..application_category import CloudSerializer
|
from ..application_category import CloudSerializer
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['K8SSerializer']
|
__all__ = ['K8SSerializer']
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from .mysql import MySQLSerializer
|
from .mysql import MySQLSerializer
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['MariaDBSerializer']
|
__all__ = ['MariaDBSerializer']
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,9 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from ..application_category import DBSerializer
|
from ..application_category import DBSerializer
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['MySQLSerializer']
|
__all__ = ['MySQLSerializer']
|
||||||
|
|
||||||
|
|
||||||
class MySQLSerializer(DBSerializer):
|
class MySQLSerializer(DBSerializer):
|
||||||
port = serializers.IntegerField(default=3306, label=_('Port'), allow_null=True)
|
port = serializers.IntegerField(default=3306, label=_('Port'), allow_null=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from ..application_category import RemoteAppSerializer
|
from ..application_category import RemoteAppSerializer
|
||||||
|
|
||||||
|
__all__ = ['MySQLWorkbenchSerializer', 'MySQLWorkbenchSecretSerializer']
|
||||||
__all__ = ['MySQLWorkbenchSerializer']
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLWorkbenchSerializer(RemoteAppSerializer):
|
class MySQLWorkbenchSerializer(RemoteAppSerializer):
|
||||||
|
@ -27,10 +26,17 @@ class MySQLWorkbenchSerializer(RemoteAppSerializer):
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
)
|
)
|
||||||
mysql_workbench_username = serializers.CharField(
|
mysql_workbench_username = serializers.CharField(
|
||||||
max_length=128, allow_blank=True, required=False, label=_('Username'),
|
max_length=128, allow_blank=True, required=False, label=_('Mysql workbench username'),
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
)
|
)
|
||||||
mysql_workbench_password = serializers.CharField(
|
mysql_workbench_password = serializers.CharField(
|
||||||
max_length=128, allow_blank=True, required=False, write_only=True, label=_('Password'),
|
max_length=128, allow_blank=True, required=False, write_only=True, label=_('Mysql workbench password'),
|
||||||
|
allow_null=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MySQLWorkbenchSecretSerializer(RemoteAppSerializer):
|
||||||
|
mysql_workbench_password = serializers.CharField(
|
||||||
|
max_length=128, allow_blank=True, required=False, read_only=True, label=_('Mysql workbench password'),
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,10 +3,8 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from ..application_category import DBSerializer
|
from ..application_category import DBSerializer
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['OracleSerializer']
|
__all__ = ['OracleSerializer']
|
||||||
|
|
||||||
|
|
||||||
class OracleSerializer(DBSerializer):
|
class OracleSerializer(DBSerializer):
|
||||||
port = serializers.IntegerField(default=1521, label=_('Port'), allow_null=True)
|
port = serializers.IntegerField(default=1521, label=_('Port'), allow_null=True)
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,8 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from ..application_category import DBSerializer
|
from ..application_category import DBSerializer
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['PostgreSerializer']
|
__all__ = ['PostgreSerializer']
|
||||||
|
|
||||||
|
|
||||||
class PostgreSerializer(DBSerializer):
|
class PostgreSerializer(DBSerializer):
|
||||||
port = serializers.IntegerField(default=5432, label=_('Port'), allow_null=True)
|
port = serializers.IntegerField(default=5432, label=_('Port'), allow_null=True)
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,9 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from ..application_category import DBSerializer
|
from ..application_category import DBSerializer
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['RedisSerializer']
|
__all__ = ['RedisSerializer']
|
||||||
|
|
||||||
|
|
||||||
class RedisSerializer(DBSerializer):
|
class RedisSerializer(DBSerializer):
|
||||||
port = serializers.IntegerField(default=6379, label=_('Port'), allow_null=True)
|
port = serializers.IntegerField(default=6379, label=_('Port'), allow_null=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from ..application_category import DBSerializer
|
from ..application_category import DBSerializer
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['SQLServerSerializer']
|
__all__ = ['SQLServerSerializer']
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from ..application_category import RemoteAppSerializer
|
from ..application_category import RemoteAppSerializer
|
||||||
|
|
||||||
|
__all__ = ['VMwareClientSerializer', 'VMwareClientSecretSerializer']
|
||||||
__all__ = ['VMwareClientSerializer']
|
|
||||||
|
|
||||||
|
|
||||||
class VMwareClientSerializer(RemoteAppSerializer):
|
class VMwareClientSerializer(RemoteAppSerializer):
|
||||||
|
@ -23,10 +22,17 @@ class VMwareClientSerializer(RemoteAppSerializer):
|
||||||
allow_null=True
|
allow_null=True
|
||||||
)
|
)
|
||||||
vmware_username = serializers.CharField(
|
vmware_username = serializers.CharField(
|
||||||
max_length=128, allow_blank=True, required=False, label=_('Username'),
|
max_length=128, allow_blank=True, required=False, label=_('Vmware username'),
|
||||||
allow_null=True
|
allow_null=True
|
||||||
)
|
)
|
||||||
vmware_password = serializers.CharField(
|
vmware_password = serializers.CharField(
|
||||||
max_length=128, allow_blank=True, required=False, write_only=True, label=_('Password'),
|
max_length=128, allow_blank=True, required=False, write_only=True, label=_('Vmware password'),
|
||||||
|
allow_null=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VMwareClientSecretSerializer(RemoteAppSerializer):
|
||||||
|
vmware_password = serializers.CharField(
|
||||||
|
max_length=128, allow_blank=True, required=False, read_only=True, label=_('Vmware password'),
|
||||||
allow_null=True
|
allow_null=True
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
from rest_framework import serializers
|
import copy
|
||||||
|
|
||||||
from applications import const
|
from applications import const
|
||||||
from . import application_category, application_type
|
from . import application_category, application_type
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'category_serializer_classes_mapping',
|
'category_serializer_classes_mapping',
|
||||||
'type_serializer_classes_mapping',
|
'type_serializer_classes_mapping',
|
||||||
'get_serializer_class_by_application_type',
|
'get_serializer_class_by_application_type',
|
||||||
|
'type_secret_serializer_classes_mapping'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# define `attrs` field `category serializers mapping`
|
# define `attrs` field `category serializers mapping`
|
||||||
# ---------------------------------------------------
|
# ---------------------------------------------------
|
||||||
|
|
||||||
|
@ -30,15 +30,32 @@ type_serializer_classes_mapping = {
|
||||||
const.AppType.oracle.value: application_type.OracleSerializer,
|
const.AppType.oracle.value: application_type.OracleSerializer,
|
||||||
const.AppType.pgsql.value: application_type.PostgreSerializer,
|
const.AppType.pgsql.value: application_type.PostgreSerializer,
|
||||||
const.AppType.sqlserver.value: application_type.SQLServerSerializer,
|
const.AppType.sqlserver.value: application_type.SQLServerSerializer,
|
||||||
# remote-app
|
|
||||||
const.AppType.chrome.value: application_type.ChromeSerializer,
|
|
||||||
const.AppType.mysql_workbench.value: application_type.MySQLWorkbenchSerializer,
|
|
||||||
const.AppType.vmware_client.value: application_type.VMwareClientSerializer,
|
|
||||||
const.AppType.custom.value: application_type.CustomSerializer,
|
|
||||||
# cloud
|
# cloud
|
||||||
const.AppType.k8s.value: application_type.K8SSerializer
|
const.AppType.k8s.value: application_type.K8SSerializer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remote_app_serializer_classes_mapping = {
|
||||||
|
# remote-app
|
||||||
|
const.AppType.chrome.value: application_type.ChromeSerializer,
|
||||||
|
const.AppType.mysql_workbench.value: application_type.MySQLWorkbenchSerializer,
|
||||||
|
const.AppType.vmware_client.value: application_type.VMwareClientSerializer,
|
||||||
|
const.AppType.custom.value: application_type.CustomSerializer
|
||||||
|
}
|
||||||
|
|
||||||
|
type_serializer_classes_mapping.update(remote_app_serializer_classes_mapping)
|
||||||
|
|
||||||
|
remote_app_secret_serializer_classes_mapping = {
|
||||||
|
# remote-app
|
||||||
|
const.AppType.chrome.value: application_type.ChromeSecretSerializer,
|
||||||
|
const.AppType.mysql_workbench.value: application_type.MySQLWorkbenchSecretSerializer,
|
||||||
|
const.AppType.vmware_client.value: application_type.VMwareClientSecretSerializer,
|
||||||
|
const.AppType.custom.value: application_type.CustomSecretSerializer
|
||||||
|
}
|
||||||
|
|
||||||
|
type_secret_serializer_classes_mapping = copy.deepcopy(type_serializer_classes_mapping)
|
||||||
|
|
||||||
|
type_secret_serializer_classes_mapping.update(remote_app_secret_serializer_classes_mapping)
|
||||||
|
|
||||||
|
|
||||||
def get_serializer_class_by_application_type(_application_type):
|
def get_serializer_class_by_application_type(_application_type):
|
||||||
return type_serializer_classes_mapping.get(_application_type)
|
return type_serializer_classes_mapping.get(_application_type)
|
||||||
|
|
|
@ -64,9 +64,7 @@ class AccountViewSet(OrgBulkModelViewSet):
|
||||||
permission_classes = (IsOrgAdmin,)
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = super().get_queryset() \
|
queryset = AuthBook.get_queryset()
|
||||||
.annotate(ip=F('asset__ip')) \
|
|
||||||
.annotate(hostname=F('asset__hostname'))
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, url_path='verify')
|
@action(methods=['post'], detail=True, url_path='verify')
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models import F
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from simple_history.models import HistoricalRecords
|
from simple_history.models import HistoricalRecords
|
||||||
|
|
||||||
|
@ -116,6 +117,15 @@ class AuthBook(BaseUser, AbsConnectivity):
|
||||||
self.asset.save()
|
self.asset.save()
|
||||||
logger.debug('Update asset admin user: {} {}'.format(self.asset, self.systemuser))
|
logger.debug('Update asset admin user: {} {}'.format(self.asset, self.systemuser))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_queryset(cls):
|
||||||
|
queryset = cls.objects.all() \
|
||||||
|
.annotate(ip=F('asset__ip')) \
|
||||||
|
.annotate(hostname=F('asset__hostname')) \
|
||||||
|
.annotate(platform=F('asset__platform__name')) \
|
||||||
|
.annotate(protocols=F('asset__protocols'))
|
||||||
|
return queryset
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.smart_name
|
return self.smart_name
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,18 @@ from .utils import validate_password_contains_left_double_curly_bracket
|
||||||
class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
ip = serializers.ReadOnlyField(label=_("IP"))
|
ip = serializers.ReadOnlyField(label=_("IP"))
|
||||||
hostname = serializers.ReadOnlyField(label=_("Hostname"))
|
hostname = serializers.ReadOnlyField(label=_("Hostname"))
|
||||||
|
platform = serializers.ReadOnlyField(label=_("Platform"))
|
||||||
|
protocols = serializers.SerializerMethodField(label=_("Protocols"))
|
||||||
|
date_created = serializers.DateTimeField(
|
||||||
|
label=_('Date created'), format="%Y/%m/%d %H:%M:%S", read_only=True
|
||||||
|
)
|
||||||
|
date_updated = serializers.DateTimeField(
|
||||||
|
label=_('Date updated'), format="%Y/%m/%d %H:%M:%S", read_only=True
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AuthBook
|
model = AuthBook
|
||||||
fields_mini = ['id', 'username', 'ip', 'hostname', 'version']
|
fields_mini = ['id', 'username', 'ip', 'hostname', 'platform', 'protocols', 'version']
|
||||||
fields_write_only = ['password', 'private_key', "public_key", 'passphrase']
|
fields_write_only = ['password', 'private_key', "public_key", 'passphrase']
|
||||||
fields_other = ['date_created', 'date_updated', 'connectivity', 'date_verified', 'comment']
|
fields_other = ['date_created', 'date_updated', 'connectivity', 'date_verified', 'comment']
|
||||||
fields_small = fields_mini + fields_write_only + fields_other
|
fields_small = fields_mini + fields_write_only + fields_other
|
||||||
|
@ -32,6 +40,9 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
}
|
}
|
||||||
ref_name = 'AssetAccountSerializer'
|
ref_name = 'AssetAccountSerializer'
|
||||||
|
|
||||||
|
def get_protocols(self, v):
|
||||||
|
return v.protocols.replace(' ', ', ')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_eager_loading(cls, queryset):
|
def setup_eager_loading(cls, queryset):
|
||||||
""" Perform necessary eager loading of data. """
|
""" Perform necessary eager loading of data. """
|
||||||
|
@ -45,6 +56,10 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
|
|
||||||
class AccountSecretSerializer(AccountSerializer):
|
class AccountSecretSerializer(AccountSerializer):
|
||||||
class Meta(AccountSerializer.Meta):
|
class Meta(AccountSerializer.Meta):
|
||||||
|
fields_backup = [
|
||||||
|
'hostname', 'ip', 'platform', 'protocols', 'username', 'password',
|
||||||
|
'private_key', 'public_key', 'date_created', 'date_updated', 'version'
|
||||||
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'password': {'write_only': False},
|
'password': {'write_only': False},
|
||||||
'private_key': {'write_only': False},
|
'private_key': {'write_only': False},
|
||||||
|
|
|
@ -5,8 +5,6 @@ from django.core.validators import RegexValidator
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
from users.models import User, UserGroup
|
|
||||||
from perms.models import AssetPermission
|
|
||||||
from ..models import Asset, Node, Platform, SystemUser
|
from ..models import Asset, Node, Platform, SystemUser
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from collections import defaultdict
|
from collections import defaultdict, OrderedDict
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
from assets.models import AuthBook, Asset, BaseUser, ProtocolsMixin
|
from assets.models import AuthBook
|
||||||
|
from assets.serializers import AccountSecretSerializer
|
||||||
from assets.notifications import AccountBackupExecutionTaskMsg
|
from assets.notifications import AccountBackupExecutionTaskMsg
|
||||||
from applications.models import Account, Application
|
from applications.models import Account
|
||||||
from applications.const import AppType
|
from applications.const import AppType
|
||||||
|
from applications.serializers import AppAccountSecretSerializer
|
||||||
from users.models import User
|
from users.models import User
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from common.utils.timezone import local_now_display
|
from common.utils.timezone import local_now_display
|
||||||
|
@ -20,7 +23,46 @@ logger = get_logger(__file__)
|
||||||
PATH = os.path.join(os.path.dirname(settings.BASE_DIR), 'tmp')
|
PATH = os.path.join(os.path.dirname(settings.BASE_DIR), 'tmp')
|
||||||
|
|
||||||
|
|
||||||
class AssetAccountHandler:
|
class BaseAccountHandler:
|
||||||
|
@classmethod
|
||||||
|
def unpack_data(cls, serializer_data, data=None):
|
||||||
|
if data is None:
|
||||||
|
data = {}
|
||||||
|
for k, v in serializer_data.items():
|
||||||
|
if isinstance(v, OrderedDict):
|
||||||
|
cls.unpack_data(v, data)
|
||||||
|
else:
|
||||||
|
data[k] = v
|
||||||
|
return data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_header_fields(cls, serializer: serializers.Serializer):
|
||||||
|
try:
|
||||||
|
backup_fields = getattr(serializer, 'Meta').fields_backup
|
||||||
|
except AttributeError:
|
||||||
|
backup_fields = serializer.fields.keys()
|
||||||
|
header_fields = {}
|
||||||
|
for field in backup_fields:
|
||||||
|
v = serializer.fields[field]
|
||||||
|
if isinstance(v, serializers.Serializer):
|
||||||
|
_fields = cls.get_header_fields(v)
|
||||||
|
header_fields.update(_fields)
|
||||||
|
else:
|
||||||
|
header_fields[field] = v.label
|
||||||
|
return header_fields
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_row(cls, account, serializer_cls):
|
||||||
|
serializer = serializer_cls(account)
|
||||||
|
data = cls.unpack_data(serializer.data)
|
||||||
|
header_fields = cls.get_header_fields(serializer)
|
||||||
|
row_dict = {}
|
||||||
|
for field, header_name in header_fields.items():
|
||||||
|
row_dict[header_name] = data[field]
|
||||||
|
return row_dict
|
||||||
|
|
||||||
|
|
||||||
|
class AssetAccountHandler(BaseAccountHandler):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_filename(plan_name):
|
def get_filename(plan_name):
|
||||||
filename = os.path.join(
|
filename = os.path.join(
|
||||||
|
@ -28,32 +70,24 @@ class AssetAccountHandler:
|
||||||
)
|
)
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
@staticmethod
|
@classmethod
|
||||||
def create_df():
|
def create_df(cls):
|
||||||
df_dict = defaultdict(list)
|
df_dict = defaultdict(list)
|
||||||
label_key = AuthBook._meta.verbose_name
|
sheet_name = AuthBook._meta.verbose_name
|
||||||
accounts = AuthBook.objects.all().prefetch_related('systemuser', 'asset')
|
accounts = AuthBook.get_queryset()
|
||||||
for account in accounts:
|
for account in accounts:
|
||||||
account.load_auth()
|
account.load_auth()
|
||||||
protocol = account.asset.protocol
|
row = cls.create_row(account, AccountSecretSerializer)
|
||||||
protocol_label = getattr(ProtocolsMixin.Protocol, protocol).label
|
df_dict[sheet_name].append(row)
|
||||||
row = {
|
|
||||||
getattr(Asset, 'hostname').field.verbose_name: account.asset.hostname,
|
|
||||||
getattr(Asset, 'ip').field.verbose_name: account.asset.ip,
|
|
||||||
}
|
|
||||||
secret_row = AccountBackupHandler.create_secret_row(account)
|
|
||||||
row.update(secret_row)
|
|
||||||
row.update({
|
|
||||||
getattr(Asset, 'protocol').field.verbose_name: protocol_label,
|
|
||||||
getattr(AuthBook, 'version').field.verbose_name: account.version
|
|
||||||
})
|
|
||||||
df_dict[label_key].append(row)
|
|
||||||
for k, v in df_dict.items():
|
for k, v in df_dict.items():
|
||||||
df_dict[k] = pd.DataFrame(v)
|
df_dict[k] = pd.DataFrame(v)
|
||||||
|
|
||||||
|
logger.info('\n\033[33m- 共收集{}条资产账号\033[0m'.format(accounts.count()))
|
||||||
return df_dict
|
return df_dict
|
||||||
|
|
||||||
|
|
||||||
class AppAccountHandler:
|
class AppAccountHandler(BaseAccountHandler):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_filename(plan_name):
|
def get_filename(plan_name):
|
||||||
filename = os.path.join(
|
filename = os.path.join(
|
||||||
|
@ -61,33 +95,23 @@ class AppAccountHandler:
|
||||||
)
|
)
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
@staticmethod
|
@classmethod
|
||||||
def create_df():
|
def create_df(cls):
|
||||||
df_dict = defaultdict(list)
|
df_dict = defaultdict(list)
|
||||||
accounts = Account.objects.all().prefetch_related('systemuser', 'app')
|
accounts = Account.get_queryset()
|
||||||
for account in accounts:
|
for account in accounts:
|
||||||
account.load_auth()
|
account.load_auth()
|
||||||
app_type = account.app.type
|
app_type = account.type
|
||||||
if app_type == 'postgresql':
|
sheet_name = AppType.get_label(app_type)
|
||||||
label_key = getattr(AppType, 'pgsql').label
|
row = cls.create_row(account, AppAccountSecretSerializer)
|
||||||
else:
|
df_dict[sheet_name].append(row)
|
||||||
label_key = getattr(AppType, app_type).label
|
|
||||||
row = {
|
|
||||||
getattr(Application, 'name').field.verbose_name: account.app.name,
|
|
||||||
getattr(Application, 'attrs').field.verbose_name: account.app.attrs
|
|
||||||
}
|
|
||||||
secret_row = AccountBackupHandler.create_secret_row(account)
|
|
||||||
row.update(secret_row)
|
|
||||||
row.update({
|
|
||||||
getattr(Account, 'version').field.verbose_name: account.version
|
|
||||||
})
|
|
||||||
df_dict[label_key].append(row)
|
|
||||||
for k, v in df_dict.items():
|
for k, v in df_dict.items():
|
||||||
df_dict[k] = pd.DataFrame(v)
|
df_dict[k] = pd.DataFrame(v)
|
||||||
|
logger.info('\n\033[33m- 共收集{}条应用账号\033[0m'.format(accounts.count()))
|
||||||
return df_dict
|
return df_dict
|
||||||
|
|
||||||
|
|
||||||
HANDLER_MAP = {
|
handler_map = {
|
||||||
'asset': AssetAccountHandler,
|
'asset': AssetAccountHandler,
|
||||||
'application': AppAccountHandler
|
'application': AppAccountHandler
|
||||||
}
|
}
|
||||||
|
@ -102,31 +126,37 @@ class AccountBackupHandler:
|
||||||
def create_excel(self):
|
def create_excel(self):
|
||||||
logger.info(
|
logger.info(
|
||||||
'\n'
|
'\n'
|
||||||
'\033[32m>>> 正在生成资产及应用相关备份信息文件\033[0m'
|
'\033[32m>>> 正在生成资产或应用相关备份信息文件\033[0m'
|
||||||
''
|
''
|
||||||
)
|
)
|
||||||
# Print task start date
|
# Print task start date
|
||||||
time_start = time.time()
|
time_start = time.time()
|
||||||
info = {}
|
files = []
|
||||||
for account_type in self.execution.types:
|
for account_type in self.execution.types:
|
||||||
if account_type in HANDLER_MAP:
|
handler = handler_map.get(account_type)
|
||||||
account_handler = HANDLER_MAP[account_type]
|
if not handler:
|
||||||
df = account_handler.create_df()
|
continue
|
||||||
filename = account_handler.get_filename(self.plan_name)
|
|
||||||
info[filename] = df
|
df_dict = handler.create_df()
|
||||||
for filename, df_dict in info.items():
|
if not df_dict:
|
||||||
|
continue
|
||||||
|
|
||||||
|
filename = handler.get_filename(self.plan_name)
|
||||||
with pd.ExcelWriter(filename) as w:
|
with pd.ExcelWriter(filename) as w:
|
||||||
for sheet, df in df_dict.items():
|
for sheet, df in df_dict.items():
|
||||||
sheet = sheet.replace(' ', '-')
|
sheet = sheet.replace(' ', '-')
|
||||||
getattr(df, 'to_excel')(w, sheet_name=sheet, index=False)
|
getattr(df, 'to_excel')(w, sheet_name=sheet, index=False)
|
||||||
|
files.append(filename)
|
||||||
timedelta = round((time.time() - time_start), 2)
|
timedelta = round((time.time() - time_start), 2)
|
||||||
logger.info('步骤完成: 用时 {}s'.format(timedelta))
|
logger.info('步骤完成: 用时 {}s'.format(timedelta))
|
||||||
return list(info.keys())
|
return files
|
||||||
|
|
||||||
def send_backup_mail(self, files):
|
def send_backup_mail(self, files):
|
||||||
recipients = self.execution.plan_snapshot.get('recipients')
|
recipients = self.execution.plan_snapshot.get('recipients')
|
||||||
if not recipients:
|
if not recipients:
|
||||||
return
|
return
|
||||||
|
if not files:
|
||||||
|
return
|
||||||
recipients = User.objects.filter(id__in=list(recipients))
|
recipients = User.objects.filter(id__in=list(recipients))
|
||||||
logger.info(
|
logger.info(
|
||||||
'\n'
|
'\n'
|
||||||
|
@ -191,13 +221,3 @@ class AccountBackupHandler:
|
||||||
logger.info('\n任务结束: {}'.format(local_now_display()))
|
logger.info('\n任务结束: {}'.format(local_now_display()))
|
||||||
timedelta = round((time.time() - time_start), 2)
|
timedelta = round((time.time() - time_start), 2)
|
||||||
logger.info('用时: {}'.format(timedelta))
|
logger.info('用时: {}'.format(timedelta))
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def create_secret_row(instance):
|
|
||||||
row = {
|
|
||||||
getattr(BaseUser, 'username').field.verbose_name: instance.username,
|
|
||||||
getattr(BaseUser, 'password').field.verbose_name: instance.password,
|
|
||||||
getattr(BaseUser, 'private_key').field.verbose_name: instance.private_key,
|
|
||||||
getattr(BaseUser, 'public_key').field.verbose_name: instance.public_key
|
|
||||||
}
|
|
||||||
return row
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:65ae747dcbddab2bbf9238b0ee589037805c9cf04a6c3a2e312d4c6c5e486b2d
|
oid sha256:041711683ed0cfbf9ffd58f402f0acb98f77a1edde5f4582314a2568d539212c
|
||||||
size 96320
|
size 96641
|
||||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2022-01-13 16:57+0800\n"
|
"POT-Creation-Date: 2022-01-15 22:47+0800\n"
|
||||||
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
||||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||||
|
@ -123,14 +123,14 @@ msgid "Login acl"
|
||||||
msgstr "登录访问控制"
|
msgstr "登录访问控制"
|
||||||
|
|
||||||
#: acls/models/login_asset_acl.py:21
|
#: acls/models/login_asset_acl.py:21
|
||||||
#: applications/serializers/application.py:108
|
#: applications/serializers/application.py:122
|
||||||
#: applications/serializers/application.py:139
|
#: applications/serializers/application.py:165
|
||||||
msgid "System User"
|
msgid "System User"
|
||||||
msgstr "系统用户"
|
msgstr "系统用户"
|
||||||
|
|
||||||
#: acls/models/login_asset_acl.py:22
|
#: acls/models/login_asset_acl.py:22
|
||||||
#: applications/serializers/attrs/application_category/remote_app.py:37
|
#: applications/serializers/attrs/application_category/remote_app.py:36
|
||||||
#: assets/models/asset.py:356 assets/models/authbook.py:18
|
#: assets/models/asset.py:356 assets/models/authbook.py:19
|
||||||
#: assets/models/backup.py:31 assets/models/cmd_filter.py:34
|
#: assets/models/backup.py:31 assets/models/cmd_filter.py:34
|
||||||
#: assets/models/gathered_user.py:14 assets/serializers/system_user.py:264
|
#: assets/models/gathered_user.py:14 assets/serializers/system_user.py:264
|
||||||
#: audits/models.py:38 perms/models/asset_permission.py:24
|
#: audits/models.py:38 perms/models/asset_permission.py:24
|
||||||
|
@ -157,13 +157,9 @@ msgid "Format for comma-delimited string, with * indicating a match all. "
|
||||||
msgstr "格式为逗号分隔的字符串, * 表示匹配所有. "
|
msgstr "格式为逗号分隔的字符串, * 表示匹配所有. "
|
||||||
|
|
||||||
#: acls/serializers/login_acl.py:15 acls/serializers/login_asset_acl.py:17
|
#: acls/serializers/login_acl.py:15 acls/serializers/login_asset_acl.py:17
|
||||||
#: acls/serializers/login_asset_acl.py:51
|
#: acls/serializers/login_asset_acl.py:51 assets/models/base.py:176
|
||||||
#: applications/serializers/attrs/application_type/chrome.py:20
|
#: assets/models/gathered_user.py:15 audits/models.py:105
|
||||||
#: applications/serializers/attrs/application_type/custom.py:21
|
#: authentication/forms.py:15 authentication/forms.py:17
|
||||||
#: applications/serializers/attrs/application_type/mysql_workbench.py:30
|
|
||||||
#: applications/serializers/attrs/application_type/vmware_client.py:26
|
|
||||||
#: assets/models/base.py:176 assets/models/gathered_user.py:15
|
|
||||||
#: audits/models.py:105 authentication/forms.py:15 authentication/forms.py:17
|
|
||||||
#: authentication/templates/authentication/_msg_different_city.html:9
|
#: authentication/templates/authentication/_msg_different_city.html:9
|
||||||
#: authentication/templates/authentication/_msg_oauth_bind.html:9
|
#: authentication/templates/authentication/_msg_oauth_bind.html:9
|
||||||
#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:547
|
#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:547
|
||||||
|
@ -185,7 +181,7 @@ msgstr ""
|
||||||
"10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 (支持网域)"
|
"10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 (支持网域)"
|
||||||
|
|
||||||
#: acls/serializers/login_asset_acl.py:31 acls/serializers/rules/rules.py:33
|
#: acls/serializers/login_asset_acl.py:31 acls/serializers/rules/rules.py:33
|
||||||
#: applications/serializers/attrs/application_type/mysql_workbench.py:18
|
#: applications/serializers/attrs/application_type/mysql_workbench.py:17
|
||||||
#: assets/models/asset.py:211 assets/models/domain.py:61
|
#: assets/models/asset.py:211 assets/models/domain.py:61
|
||||||
#: assets/serializers/account.py:12
|
#: assets/serializers/account.py:12
|
||||||
#: authentication/templates/authentication/_msg_oauth_bind.html:12
|
#: authentication/templates/authentication/_msg_oauth_bind.html:12
|
||||||
|
@ -252,9 +248,9 @@ msgstr "时段"
|
||||||
msgid "My applications"
|
msgid "My applications"
|
||||||
msgstr "我的应用"
|
msgstr "我的应用"
|
||||||
|
|
||||||
#: applications/const.py:8 applications/models/account.py:10
|
#: applications/const.py:8 applications/models/account.py:12
|
||||||
#: applications/serializers/attrs/application_category/db.py:14
|
#: applications/serializers/attrs/application_category/db.py:14
|
||||||
#: applications/serializers/attrs/application_type/mysql_workbench.py:26
|
#: applications/serializers/attrs/application_type/mysql_workbench.py:25
|
||||||
#: xpack/plugins/change_auth_plan/models/app.py:32
|
#: xpack/plugins/change_auth_plan/models/app.py:32
|
||||||
msgid "Database"
|
msgid "Database"
|
||||||
msgstr "数据库"
|
msgstr "数据库"
|
||||||
|
@ -267,7 +263,7 @@ msgstr "远程应用"
|
||||||
msgid "Custom"
|
msgid "Custom"
|
||||||
msgstr "自定义"
|
msgstr "自定义"
|
||||||
|
|
||||||
#: applications/models/account.py:11 assets/models/authbook.py:19
|
#: applications/models/account.py:15 assets/models/authbook.py:20
|
||||||
#: assets/models/cmd_filter.py:38 assets/models/user.py:302 audits/models.py:39
|
#: assets/models/cmd_filter.py:38 assets/models/user.py:302 audits/models.py:39
|
||||||
#: perms/models/application_permission.py:32
|
#: perms/models/application_permission.py:32
|
||||||
#: perms/models/asset_permission.py:26 templates/_nav.html:45
|
#: perms/models/asset_permission.py:26 templates/_nav.html:45
|
||||||
|
@ -284,12 +280,12 @@ msgstr "自定义"
|
||||||
msgid "System user"
|
msgid "System user"
|
||||||
msgstr "系统用户"
|
msgstr "系统用户"
|
||||||
|
|
||||||
#: applications/models/account.py:12 assets/models/authbook.py:20
|
#: applications/models/account.py:17 assets/models/authbook.py:21
|
||||||
#: settings/serializers/auth/cas.py:15
|
#: settings/serializers/auth/cas.py:15
|
||||||
msgid "Version"
|
msgid "Version"
|
||||||
msgstr "版本"
|
msgstr "版本"
|
||||||
|
|
||||||
#: applications/models/account.py:18 xpack/plugins/cloud/models.py:82
|
#: applications/models/account.py:23 xpack/plugins/cloud/models.py:82
|
||||||
#: xpack/plugins/cloud/serializers/task.py:66
|
#: xpack/plugins/cloud/serializers/task.py:66
|
||||||
msgid "Account"
|
msgid "Account"
|
||||||
msgstr "账户"
|
msgstr "账户"
|
||||||
|
@ -299,7 +295,7 @@ msgid "Applications"
|
||||||
msgstr "应用管理"
|
msgstr "应用管理"
|
||||||
|
|
||||||
#: applications/models/application.py:204
|
#: applications/models/application.py:204
|
||||||
#: applications/serializers/application.py:88 assets/models/label.py:21
|
#: applications/serializers/application.py:99 assets/models/label.py:21
|
||||||
#: perms/models/application_permission.py:20
|
#: perms/models/application_permission.py:20
|
||||||
#: perms/serializers/application/user_permission.py:33
|
#: perms/serializers/application/user_permission.py:33
|
||||||
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:22
|
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:22
|
||||||
|
@ -308,7 +304,7 @@ msgid "Category"
|
||||||
msgstr "类别"
|
msgstr "类别"
|
||||||
|
|
||||||
#: applications/models/application.py:207
|
#: applications/models/application.py:207
|
||||||
#: applications/serializers/application.py:90 assets/models/backup.py:49
|
#: applications/serializers/application.py:101 assets/models/backup.py:49
|
||||||
#: assets/models/cmd_filter.py:76 assets/models/user.py:210
|
#: assets/models/cmd_filter.py:76 assets/models/user.py:210
|
||||||
#: perms/models/application_permission.py:23
|
#: perms/models/application_permission.py:23
|
||||||
#: perms/serializers/application/user_permission.py:34
|
#: perms/serializers/application/user_permission.py:34
|
||||||
|
@ -335,15 +331,15 @@ msgstr "属性"
|
||||||
msgid "Application"
|
msgid "Application"
|
||||||
msgstr "应用程序"
|
msgstr "应用程序"
|
||||||
|
|
||||||
#: applications/serializers/application.py:59
|
#: applications/serializers/application.py:70
|
||||||
#: applications/serializers/application.py:89 assets/serializers/label.py:13
|
#: applications/serializers/application.py:100 assets/serializers/label.py:13
|
||||||
#: perms/serializers/application/permission.py:18
|
#: perms/serializers/application/permission.py:18
|
||||||
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:26
|
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:26
|
||||||
msgid "Category display"
|
msgid "Category display"
|
||||||
msgstr "类别名称"
|
msgstr "类别名称"
|
||||||
|
|
||||||
#: applications/serializers/application.py:60
|
#: applications/serializers/application.py:71
|
||||||
#: applications/serializers/application.py:91
|
#: applications/serializers/application.py:102
|
||||||
#: assets/serializers/system_user.py:27 audits/serializers.py:29
|
#: assets/serializers/system_user.py:27 audits/serializers.py:29
|
||||||
#: perms/serializers/application/permission.py:19
|
#: perms/serializers/application/permission.py:19
|
||||||
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:33
|
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:33
|
||||||
|
@ -352,12 +348,31 @@ msgstr "类别名称"
|
||||||
msgid "Type display"
|
msgid "Type display"
|
||||||
msgstr "类型名称"
|
msgstr "类型名称"
|
||||||
|
|
||||||
#: applications/serializers/application.py:107
|
#: applications/serializers/application.py:103 assets/models/asset.py:231
|
||||||
#: applications/serializers/application.py:138
|
#: assets/models/base.py:181 assets/models/cluster.py:26
|
||||||
|
#: assets/models/domain.py:27 assets/models/gathered_user.py:19
|
||||||
|
#: assets/models/group.py:22 assets/models/label.py:25
|
||||||
|
#: assets/serializers/account.py:17 common/db/models.py:113
|
||||||
|
#: common/mixins/models.py:50 ops/models/adhoc.py:38 ops/models/command.py:29
|
||||||
|
#: orgs/models.py:26 orgs/models.py:435 perms/models/base.py:92
|
||||||
|
#: users/models/group.py:18 users/models/user.py:783
|
||||||
|
#: xpack/plugins/cloud/models.py:122
|
||||||
|
msgid "Date created"
|
||||||
|
msgstr "创建日期"
|
||||||
|
|
||||||
|
#: applications/serializers/application.py:104 assets/models/base.py:182
|
||||||
|
#: assets/models/gathered_user.py:20 assets/serializers/account.py:20
|
||||||
|
#: common/db/models.py:114 common/mixins/models.py:51 ops/models/adhoc.py:39
|
||||||
|
#: orgs/models.py:436
|
||||||
|
msgid "Date updated"
|
||||||
|
msgstr "更新日期"
|
||||||
|
|
||||||
|
#: applications/serializers/application.py:121
|
||||||
|
#: applications/serializers/application.py:164
|
||||||
msgid "Application display"
|
msgid "Application display"
|
||||||
msgstr "应用名称"
|
msgstr "应用名称"
|
||||||
|
|
||||||
#: applications/serializers/attrs/application_category/cloud.py:9
|
#: applications/serializers/attrs/application_category/cloud.py:8
|
||||||
#: assets/models/cluster.py:40
|
#: assets/models/cluster.py:40
|
||||||
msgid "Cluster"
|
msgid "Cluster"
|
||||||
msgstr "集群"
|
msgstr "集群"
|
||||||
|
@ -369,26 +384,26 @@ msgid "Host"
|
||||||
msgstr "主机"
|
msgstr "主机"
|
||||||
|
|
||||||
#: applications/serializers/attrs/application_category/db.py:12
|
#: applications/serializers/attrs/application_category/db.py:12
|
||||||
#: applications/serializers/attrs/application_type/mysql.py:11
|
#: applications/serializers/attrs/application_type/mysql.py:10
|
||||||
#: applications/serializers/attrs/application_type/mysql_workbench.py:22
|
#: applications/serializers/attrs/application_type/mysql_workbench.py:21
|
||||||
#: applications/serializers/attrs/application_type/oracle.py:11
|
#: applications/serializers/attrs/application_type/oracle.py:10
|
||||||
#: applications/serializers/attrs/application_type/pgsql.py:11
|
#: applications/serializers/attrs/application_type/pgsql.py:10
|
||||||
#: applications/serializers/attrs/application_type/redis.py:11
|
#: applications/serializers/attrs/application_type/redis.py:10
|
||||||
#: applications/serializers/attrs/application_type/sqlserver.py:11
|
#: applications/serializers/attrs/application_type/sqlserver.py:10
|
||||||
#: assets/models/asset.py:215 assets/models/domain.py:62
|
#: assets/models/asset.py:215 assets/models/domain.py:62
|
||||||
#: settings/serializers/auth/radius.py:15
|
#: settings/serializers/auth/radius.py:15
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:69
|
#: xpack/plugins/cloud/serializers/account_attrs.py:69
|
||||||
msgid "Port"
|
msgid "Port"
|
||||||
msgstr "端口"
|
msgstr "端口"
|
||||||
|
|
||||||
#: applications/serializers/attrs/application_category/remote_app.py:40
|
#: applications/serializers/attrs/application_category/remote_app.py:39
|
||||||
#: applications/serializers/attrs/application_type/chrome.py:14
|
#: applications/serializers/attrs/application_type/chrome.py:13
|
||||||
#: applications/serializers/attrs/application_type/mysql_workbench.py:14
|
#: applications/serializers/attrs/application_type/mysql_workbench.py:13
|
||||||
#: applications/serializers/attrs/application_type/vmware_client.py:18
|
#: applications/serializers/attrs/application_type/vmware_client.py:17
|
||||||
msgid "Application path"
|
msgid "Application path"
|
||||||
msgstr "应用路径"
|
msgstr "应用路径"
|
||||||
|
|
||||||
#: applications/serializers/attrs/application_category/remote_app.py:45
|
#: applications/serializers/attrs/application_category/remote_app.py:44
|
||||||
#: assets/serializers/system_user.py:163
|
#: assets/serializers/system_user.py:163
|
||||||
#: xpack/plugins/change_auth_plan/serializers/asset.py:65
|
#: xpack/plugins/change_auth_plan/serializers/asset.py:65
|
||||||
#: xpack/plugins/change_auth_plan/serializers/asset.py:68
|
#: xpack/plugins/change_auth_plan/serializers/asset.py:68
|
||||||
|
@ -398,37 +413,58 @@ msgstr "应用路径"
|
||||||
msgid "This field is required."
|
msgid "This field is required."
|
||||||
msgstr "该字段是必填项。"
|
msgstr "该字段是必填项。"
|
||||||
|
|
||||||
#: applications/serializers/attrs/application_type/chrome.py:17
|
#: applications/serializers/attrs/application_type/chrome.py:16
|
||||||
#: applications/serializers/attrs/application_type/vmware_client.py:22
|
#: applications/serializers/attrs/application_type/vmware_client.py:21
|
||||||
msgid "Target URL"
|
msgid "Target URL"
|
||||||
msgstr "目标URL"
|
msgstr "目标URL"
|
||||||
|
|
||||||
#: applications/serializers/attrs/application_type/chrome.py:23
|
#: applications/serializers/attrs/application_type/chrome.py:19
|
||||||
#: applications/serializers/attrs/application_type/custom.py:25
|
msgid "Chrome username"
|
||||||
#: applications/serializers/attrs/application_type/mysql_workbench.py:34
|
msgstr "Chrome 用户名"
|
||||||
#: applications/serializers/attrs/application_type/vmware_client.py:30
|
|
||||||
#: assets/models/base.py:177 audits/signals_handler.py:65
|
|
||||||
#: authentication/forms.py:22
|
|
||||||
#: authentication/templates/authentication/login.html:151
|
|
||||||
#: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21
|
|
||||||
#: users/templates/users/_msg_user_created.html:13
|
|
||||||
#: users/templates/users/user_password_update.html:43
|
|
||||||
#: users/templates/users/user_password_verify.html:18
|
|
||||||
#: xpack/plugins/change_auth_plan/models/base.py:39
|
|
||||||
#: xpack/plugins/change_auth_plan/models/base.py:118
|
|
||||||
#: xpack/plugins/change_auth_plan/models/base.py:193
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:24
|
|
||||||
msgid "Password"
|
|
||||||
msgstr "密码"
|
|
||||||
|
|
||||||
#: applications/serializers/attrs/application_type/custom.py:13
|
#: applications/serializers/attrs/application_type/chrome.py:22
|
||||||
|
#: applications/serializers/attrs/application_type/chrome.py:29
|
||||||
|
msgid "Chrome password"
|
||||||
|
msgstr "Chrome 密码"
|
||||||
|
|
||||||
|
#: applications/serializers/attrs/application_type/custom.py:11
|
||||||
msgid "Operating parameter"
|
msgid "Operating parameter"
|
||||||
msgstr "运行参数"
|
msgstr "运行参数"
|
||||||
|
|
||||||
#: applications/serializers/attrs/application_type/custom.py:17
|
#: applications/serializers/attrs/application_type/custom.py:15
|
||||||
msgid "Target url"
|
msgid "Target url"
|
||||||
msgstr "目标URL"
|
msgstr "目标URL"
|
||||||
|
|
||||||
|
#: applications/serializers/attrs/application_type/custom.py:19
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Custom username"
|
||||||
|
msgid "Custom Username"
|
||||||
|
msgstr "自定义用户名"
|
||||||
|
|
||||||
|
#: applications/serializers/attrs/application_type/custom.py:23
|
||||||
|
#: applications/serializers/attrs/application_type/custom.py:30
|
||||||
|
#: xpack/plugins/change_auth_plan/models/base.py:24
|
||||||
|
msgid "Custom password"
|
||||||
|
msgstr "自定义密码"
|
||||||
|
|
||||||
|
#: applications/serializers/attrs/application_type/mysql_workbench.py:29
|
||||||
|
msgid "Mysql workbench username"
|
||||||
|
msgstr "Mysql 工作台 用户名"
|
||||||
|
|
||||||
|
#: applications/serializers/attrs/application_type/mysql_workbench.py:33
|
||||||
|
#: applications/serializers/attrs/application_type/mysql_workbench.py:40
|
||||||
|
msgid "Mysql workbench password"
|
||||||
|
msgstr "Mysql 工作台 密码"
|
||||||
|
|
||||||
|
#: applications/serializers/attrs/application_type/vmware_client.py:25
|
||||||
|
msgid "Vmware username"
|
||||||
|
msgstr "Vmware 用户名"
|
||||||
|
|
||||||
|
#: applications/serializers/attrs/application_type/vmware_client.py:29
|
||||||
|
#: applications/serializers/attrs/application_type/vmware_client.py:36
|
||||||
|
msgid "Vmware password"
|
||||||
|
msgstr "Vmware 密码"
|
||||||
|
|
||||||
#: assets/api/domain.py:52
|
#: assets/api/domain.py:52
|
||||||
msgid "Number required"
|
msgid "Number required"
|
||||||
msgstr "需要为数字"
|
msgstr "需要为数字"
|
||||||
|
@ -453,7 +489,7 @@ msgstr "基础"
|
||||||
msgid "Charset"
|
msgid "Charset"
|
||||||
msgstr "编码"
|
msgstr "编码"
|
||||||
|
|
||||||
#: assets/models/asset.py:142 assets/serializers/asset.py:178
|
#: assets/models/asset.py:142 assets/serializers/asset.py:176
|
||||||
#: tickets/models/ticket.py:54
|
#: tickets/models/ticket.py:54
|
||||||
msgid "Meta"
|
msgid "Meta"
|
||||||
msgstr "元数据"
|
msgstr "元数据"
|
||||||
|
@ -463,7 +499,8 @@ msgid "Internal"
|
||||||
msgstr "内部的"
|
msgstr "内部的"
|
||||||
|
|
||||||
#: assets/models/asset.py:163 assets/models/asset.py:217
|
#: assets/models/asset.py:163 assets/models/asset.py:217
|
||||||
#: assets/serializers/asset.py:65 perms/serializers/asset/user_permission.py:43
|
#: assets/serializers/account.py:14 assets/serializers/asset.py:63
|
||||||
|
#: perms/serializers/asset/user_permission.py:43
|
||||||
msgid "Platform"
|
msgid "Platform"
|
||||||
msgstr "系统平台"
|
msgstr "系统平台"
|
||||||
|
|
||||||
|
@ -523,8 +560,8 @@ msgstr "系统架构"
|
||||||
msgid "Hostname raw"
|
msgid "Hostname raw"
|
||||||
msgstr "主机名原始"
|
msgstr "主机名原始"
|
||||||
|
|
||||||
#: assets/models/asset.py:216 assets/serializers/asset.py:67
|
#: assets/models/asset.py:216 assets/serializers/account.py:15
|
||||||
#: perms/serializers/asset/user_permission.py:41
|
#: assets/serializers/asset.py:65 perms/serializers/asset/user_permission.py:41
|
||||||
#: xpack/plugins/cloud/models.py:104 xpack/plugins/cloud/serializers/task.py:42
|
#: xpack/plugins/cloud/models.py:104 xpack/plugins/cloud/serializers/task.py:42
|
||||||
msgid "Protocols"
|
msgid "Protocols"
|
||||||
msgstr "协议组"
|
msgstr "协议组"
|
||||||
|
@ -569,17 +606,7 @@ msgstr "标签管理"
|
||||||
msgid "Created by"
|
msgid "Created by"
|
||||||
msgstr "创建者"
|
msgstr "创建者"
|
||||||
|
|
||||||
#: assets/models/asset.py:231 assets/models/base.py:181
|
#: assets/models/authbook.py:27
|
||||||
#: assets/models/cluster.py:26 assets/models/domain.py:27
|
|
||||||
#: assets/models/gathered_user.py:19 assets/models/group.py:22
|
|
||||||
#: assets/models/label.py:25 common/db/models.py:113 common/mixins/models.py:50
|
|
||||||
#: ops/models/adhoc.py:38 ops/models/command.py:29 orgs/models.py:26
|
|
||||||
#: orgs/models.py:435 perms/models/base.py:92 users/models/group.py:18
|
|
||||||
#: users/models/user.py:783 xpack/plugins/cloud/models.py:122
|
|
||||||
msgid "Date created"
|
|
||||||
msgstr "创建日期"
|
|
||||||
|
|
||||||
#: assets/models/authbook.py:26
|
|
||||||
msgid "AuthBook"
|
msgid "AuthBook"
|
||||||
msgstr "账号"
|
msgstr "账号"
|
||||||
|
|
||||||
|
@ -678,6 +705,20 @@ msgstr "可连接性"
|
||||||
msgid "Date verified"
|
msgid "Date verified"
|
||||||
msgstr "校验日期"
|
msgstr "校验日期"
|
||||||
|
|
||||||
|
#: assets/models/base.py:177 audits/signals_handler.py:65
|
||||||
|
#: authentication/forms.py:22
|
||||||
|
#: authentication/templates/authentication/login.html:151
|
||||||
|
#: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21
|
||||||
|
#: users/templates/users/_msg_user_created.html:13
|
||||||
|
#: users/templates/users/user_password_update.html:43
|
||||||
|
#: users/templates/users/user_password_verify.html:18
|
||||||
|
#: xpack/plugins/change_auth_plan/models/base.py:39
|
||||||
|
#: xpack/plugins/change_auth_plan/models/base.py:118
|
||||||
|
#: xpack/plugins/change_auth_plan/models/base.py:193
|
||||||
|
#: xpack/plugins/cloud/serializers/account_attrs.py:24
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "密码"
|
||||||
|
|
||||||
#: assets/models/base.py:178 xpack/plugins/change_auth_plan/models/asset.py:53
|
#: assets/models/base.py:178 xpack/plugins/change_auth_plan/models/asset.py:53
|
||||||
#: xpack/plugins/change_auth_plan/models/asset.py:130
|
#: xpack/plugins/change_auth_plan/models/asset.py:130
|
||||||
#: xpack/plugins/change_auth_plan/models/asset.py:206
|
#: xpack/plugins/change_auth_plan/models/asset.py:206
|
||||||
|
@ -690,12 +731,6 @@ msgstr "SSH密钥"
|
||||||
msgid "SSH public key"
|
msgid "SSH public key"
|
||||||
msgstr "SSH公钥"
|
msgstr "SSH公钥"
|
||||||
|
|
||||||
#: assets/models/base.py:182 assets/models/gathered_user.py:20
|
|
||||||
#: common/db/models.py:114 common/mixins/models.py:51 ops/models/adhoc.py:39
|
|
||||||
#: orgs/models.py:436
|
|
||||||
msgid "Date updated"
|
|
||||||
msgstr "更新日期"
|
|
||||||
|
|
||||||
#: assets/models/cluster.py:20
|
#: assets/models/cluster.py:20
|
||||||
msgid "Bandwidth"
|
msgid "Bandwidth"
|
||||||
msgstr "带宽"
|
msgstr "带宽"
|
||||||
|
@ -965,39 +1000,39 @@ msgstr ""
|
||||||
"{} - 账号备份任务已完成: 未设置加密密码 - 请前往个人信息 -> 文件加密密码中设"
|
"{} - 账号备份任务已完成: 未设置加密密码 - 请前往个人信息 -> 文件加密密码中设"
|
||||||
"置加密密码"
|
"置加密密码"
|
||||||
|
|
||||||
#: assets/serializers/account.py:31 assets/serializers/account.py:52
|
#: assets/serializers/account.py:39 assets/serializers/account.py:67
|
||||||
msgid "System user display"
|
msgid "System user display"
|
||||||
msgstr "系统用户名称"
|
msgstr "系统用户名称"
|
||||||
|
|
||||||
#: assets/serializers/asset.py:22
|
#: assets/serializers/asset.py:20
|
||||||
msgid "Protocol format should {}/{}"
|
msgid "Protocol format should {}/{}"
|
||||||
msgstr "协议格式 {}/{}"
|
msgstr "协议格式 {}/{}"
|
||||||
|
|
||||||
#: assets/serializers/asset.py:39
|
#: assets/serializers/asset.py:37
|
||||||
msgid "Protocol duplicate: {}"
|
msgid "Protocol duplicate: {}"
|
||||||
msgstr "协议重复: {}"
|
msgstr "协议重复: {}"
|
||||||
|
|
||||||
#: assets/serializers/asset.py:68
|
#: assets/serializers/asset.py:66
|
||||||
msgid "Domain name"
|
msgid "Domain name"
|
||||||
msgstr "网域名称"
|
msgstr "网域名称"
|
||||||
|
|
||||||
#: assets/serializers/asset.py:70
|
#: assets/serializers/asset.py:68
|
||||||
msgid "Nodes name"
|
msgid "Nodes name"
|
||||||
msgstr "节点名称"
|
msgstr "节点名称"
|
||||||
|
|
||||||
#: assets/serializers/asset.py:73
|
#: assets/serializers/asset.py:71
|
||||||
msgid "Labels name"
|
msgid "Labels name"
|
||||||
msgstr "标签名称"
|
msgstr "标签名称"
|
||||||
|
|
||||||
#: assets/serializers/asset.py:107
|
#: assets/serializers/asset.py:105
|
||||||
msgid "Hardware info"
|
msgid "Hardware info"
|
||||||
msgstr "硬件信息"
|
msgstr "硬件信息"
|
||||||
|
|
||||||
#: assets/serializers/asset.py:108
|
#: assets/serializers/asset.py:106
|
||||||
msgid "Admin user display"
|
msgid "Admin user display"
|
||||||
msgstr "特权用户名称"
|
msgstr "特权用户名称"
|
||||||
|
|
||||||
#: assets/serializers/asset.py:109
|
#: assets/serializers/asset.py:107
|
||||||
msgid "CPU info"
|
msgid "CPU info"
|
||||||
msgstr "CPU信息"
|
msgstr "CPU信息"
|
||||||
|
|
||||||
|
@ -1622,11 +1657,11 @@ msgstr "{ApplicationPermission} 移除 {SystemUser}"
|
||||||
msgid "Invalid token"
|
msgid "Invalid token"
|
||||||
msgstr "无效的令牌"
|
msgstr "无效的令牌"
|
||||||
|
|
||||||
#: authentication/api/mfa.py:50
|
#: authentication/api/mfa.py:63
|
||||||
msgid "Current user not support mfa type: {}"
|
msgid "Current user not support mfa type: {}"
|
||||||
msgstr "当前用户不支持 MFA 类型: {}"
|
msgstr "当前用户不支持 MFA 类型: {}"
|
||||||
|
|
||||||
#: authentication/api/mfa.py:97
|
#: authentication/api/mfa.py:110
|
||||||
msgid "Code is invalid, {}"
|
msgid "Code is invalid, {}"
|
||||||
msgstr "验证码无效: {}"
|
msgstr "验证码无效: {}"
|
||||||
|
|
||||||
|
@ -1795,15 +1830,15 @@ msgstr "该 时间段 不被允许登录"
|
||||||
msgid "SSO auth closed"
|
msgid "SSO auth closed"
|
||||||
msgstr "SSO 认证关闭了"
|
msgstr "SSO 认证关闭了"
|
||||||
|
|
||||||
#: authentication/errors.py:300 authentication/mixins.py:359
|
#: authentication/errors.py:300 authentication/mixins.py:364
|
||||||
msgid "Your password is too simple, please change it for security"
|
msgid "Your password is too simple, please change it for security"
|
||||||
msgstr "你的密码过于简单,为了安全,请修改"
|
msgstr "你的密码过于简单,为了安全,请修改"
|
||||||
|
|
||||||
#: authentication/errors.py:309 authentication/mixins.py:366
|
#: authentication/errors.py:309 authentication/mixins.py:371
|
||||||
msgid "You should to change your password before login"
|
msgid "You should to change your password before login"
|
||||||
msgstr "登录完成前,请先修改密码"
|
msgstr "登录完成前,请先修改密码"
|
||||||
|
|
||||||
#: authentication/errors.py:318 authentication/mixins.py:373
|
#: authentication/errors.py:318 authentication/mixins.py:378
|
||||||
msgid "Your password has expired, please reset before logging in"
|
msgid "Your password has expired, please reset before logging in"
|
||||||
msgstr "您的密码已过期,先修改再登录"
|
msgstr "您的密码已过期,先修改再登录"
|
||||||
|
|
||||||
|
@ -1899,7 +1934,7 @@ msgstr "清空手机号码禁用"
|
||||||
msgid "The MFA type ({}) is not enabled"
|
msgid "The MFA type ({}) is not enabled"
|
||||||
msgstr "该 MFA ({}) 方式没有启用"
|
msgstr "该 MFA ({}) 方式没有启用"
|
||||||
|
|
||||||
#: authentication/mixins.py:349
|
#: authentication/mixins.py:354
|
||||||
msgid "Please change your password"
|
msgid "Please change your password"
|
||||||
msgstr "请修改密码"
|
msgstr "请修改密码"
|
||||||
|
|
||||||
|
@ -2824,7 +2859,7 @@ msgstr "用户组数量"
|
||||||
msgid "System users amount"
|
msgid "System users amount"
|
||||||
msgstr "系统用户数量"
|
msgstr "系统用户数量"
|
||||||
|
|
||||||
#: perms/serializers/application/permission.py:88
|
#: perms/serializers/application/permission.py:79
|
||||||
msgid ""
|
msgid ""
|
||||||
"The application list contains applications that are different from the "
|
"The application list contains applications that are different from the "
|
||||||
"permission type. ({})"
|
"permission type. ({})"
|
||||||
|
@ -5755,10 +5790,6 @@ msgstr "改密计划执行"
|
||||||
msgid "Change auth plan task"
|
msgid "Change auth plan task"
|
||||||
msgstr "改密计划任务"
|
msgstr "改密计划任务"
|
||||||
|
|
||||||
#: xpack/plugins/change_auth_plan/models/base.py:24
|
|
||||||
msgid "Custom password"
|
|
||||||
msgstr "自定义密码"
|
|
||||||
|
|
||||||
#: xpack/plugins/change_auth_plan/models/base.py:25
|
#: xpack/plugins/change_auth_plan/models/base.py:25
|
||||||
msgid "All assets use the same random password"
|
msgid "All assets use the same random password"
|
||||||
msgstr "使用相同的随机密码"
|
msgstr "使用相同的随机密码"
|
||||||
|
|
Loading…
Reference in New Issue