Merge pull request #9649 from jumpserver/pr@dev@perf_account_tasks

perf: 优化 tasks
pull/9660/head
老广 2023-02-21 14:14:37 +08:00 committed by GitHub
commit b91b9ef39e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 612 additions and 591 deletions

View File

@ -1,4 +1,3 @@
from .account import * from .account import *
from .backup import * from .task import *
from .template import * from .template import *
from .gathered_account import *

View File

@ -1,12 +1,11 @@
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.generics import CreateAPIView, ListAPIView from rest_framework.generics import ListAPIView
from rest_framework.response import Response from rest_framework.response import Response
from accounts import serializers from accounts import serializers
from accounts.filters import AccountFilterSet from accounts.filters import AccountFilterSet
from accounts.models import Account from accounts.models import Account
from accounts.tasks import verify_accounts_connectivity
from assets.models import Asset from assets.models import Asset
from authentication.const import ConfirmType from authentication.const import ConfirmType
from common.permissions import UserConfirmation from common.permissions import UserConfirmation
@ -15,7 +14,7 @@ from orgs.mixins.api import OrgBulkModelViewSet
__all__ = [ __all__ = [
'AccountViewSet', 'AccountSecretsViewSet', 'AccountViewSet', 'AccountSecretsViewSet',
'AccountTaskCreateAPI', 'AccountHistoriesSecretAPI' 'AccountHistoriesSecretAPI'
] ]
from rbac.permissions import RBACPermission from rbac.permissions import RBACPermission
@ -29,7 +28,6 @@ class AccountViewSet(OrgBulkModelViewSet):
'default': serializers.AccountSerializer, 'default': serializers.AccountSerializer,
} }
rbac_perms = { rbac_perms = {
'verify_account': 'accounts.test_account',
'partial_update': ['accounts.change_account'], 'partial_update': ['accounts.change_account'],
'su_from_accounts': 'accounts.view_account', 'su_from_accounts': 'accounts.view_account',
} }
@ -38,6 +36,7 @@ class AccountViewSet(OrgBulkModelViewSet):
def su_from_accounts(self, request, *args, **kwargs): def su_from_accounts(self, request, *args, **kwargs):
account_id = request.query_params.get('account') account_id = request.query_params.get('account')
asset_id = request.query_params.get('asset') asset_id = request.query_params.get('asset')
if account_id: if account_id:
account = get_object_or_404(Account, pk=account_id) account = get_object_or_404(Account, pk=account_id)
accounts = account.get_su_from_accounts() accounts = account.get_su_from_accounts()
@ -49,14 +48,6 @@ class AccountViewSet(OrgBulkModelViewSet):
serializer = serializers.AccountSerializer(accounts, many=True) serializer = serializers.AccountSerializer(accounts, many=True)
return Response(data=serializer.data) return Response(data=serializer.data)
@action(methods=['post'], detail=True, url_path='verify')
def verify_account(self, request, *args, **kwargs):
account = super().get_object()
account_ids = [account.id]
asset_ids = [account.asset_id]
task = verify_accounts_connectivity.delay(account_ids, asset_ids)
return Response(data={'task': task.id})
class AccountSecretsViewSet(RecordViewLogMixin, AccountViewSet): class AccountSecretsViewSet(RecordViewLogMixin, AccountViewSet):
""" """
@ -84,33 +75,3 @@ class AccountHistoriesSecretAPI(RecordViewLogMixin, ListAPIView):
def get_queryset(self): def get_queryset(self):
return self.model.objects.filter(id=self.kwargs.get('pk')) return self.model.objects.filter(id=self.kwargs.get('pk'))
class AccountTaskCreateAPI(CreateAPIView):
serializer_class = serializers.AccountTaskSerializer
search_fields = AccountViewSet.search_fields
filterset_class = AccountViewSet.filterset_class
def check_permissions(self, request):
return request.user.has_perm('assets.test_assetconnectivity')
def get_accounts(self):
queryset = Account.objects.all()
queryset = self.filter_queryset(queryset)
return queryset
def perform_create(self, serializer):
accounts = self.get_accounts()
account_ids = accounts.values_list('id', flat=True)
asset_ids = [account.asset_id for account in accounts]
task = verify_accounts_connectivity.delay(account_ids, asset_ids)
data = getattr(serializer, '_data', {})
data["task"] = task.id
setattr(serializer, '_data', data)
return task
def get_exception_handler(self):
def handler(e, context):
return Response({"error": str(e)}, status=400)
return handler

View File

@ -1,42 +0,0 @@
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from django.utils.translation import ugettext_lazy as _
from accounts import serializers
from accounts.const import Source
from accounts.models import GatheredAccount
from accounts.filters import GatheredAccountFilterSet
from orgs.mixins.api import OrgBulkModelViewSet
__all__ = [
'GatheredAccountViewSet',
]
class GatheredAccountViewSet(OrgBulkModelViewSet):
model = GatheredAccount
search_fields = ('username',)
filterset_class = GatheredAccountFilterSet
serializer_classes = {
'default': serializers.GatheredAccountSerializer,
}
rbac_perms = {
'sync_account': 'assets.add_gatheredaccount',
}
@action(methods=['post'], detail=True, url_path='sync')
def sync_account(self, request, *args, **kwargs):
gathered_account = super().get_object()
asset = gathered_account.asset
username = gathered_account.username
accounts = asset.accounts.filter(username=username)
if accounts.exists():
accounts.update(source=Source.COLLECTED)
else:
asset.accounts.model.objects.create(
asset=asset, username=username,
name=f'{username}-{_("Collected")}',
source=Source.COLLECTED
)
return Response(status=status.HTTP_201_CREATED)

View File

@ -0,0 +1,42 @@
from rest_framework.generics import CreateAPIView
from rest_framework.response import Response
from accounts import serializers
from accounts.tasks import verify_accounts_connectivity_task, push_accounts_to_assets_task
__all__ = [
'AccountsTaskCreateAPI',
]
class AccountsTaskCreateAPI(CreateAPIView):
serializer_class = serializers.AccountTaskSerializer
def check_permissions(self, request):
act = request.data.get('action')
if act == 'push':
code = 'accounts.push_account'
else:
code = 'accounts.verify_account'
return request.user.has_perm(code)
def perform_create(self, serializer):
data = serializer.validated_data
accounts = data.get('accounts', [])
account_ids = [a.id for a in accounts]
if data['action'] == 'push':
task = push_accounts_to_assets_task.delay(account_ids)
else:
task = verify_accounts_connectivity_task.delay(account_ids)
data = getattr(serializer, '_data', {})
data["task"] = task.id
setattr(serializer, '_data', data)
return task
def get_exception_handler(self):
def handler(e, context):
return Response({"error": str(e)}, status=400)
return handler

View File

@ -1,3 +1,4 @@
from .backup import *
from .base import * from .base import *
from .change_secret import * from .change_secret import *
from .gather_accounts import * from .gather_accounts import *

View File

@ -7,7 +7,7 @@ from accounts import serializers
from accounts.models import ( from accounts.models import (
AccountBackupAutomation, AccountBackupExecution AccountBackupAutomation, AccountBackupExecution
) )
from accounts.tasks import execute_account_backup_plan from accounts.tasks import execute_account_backup_task
from common.const.choices import Trigger from common.const.choices import Trigger
from orgs.mixins.api import OrgBulkModelViewSet from orgs.mixins.api import OrgBulkModelViewSet
@ -38,5 +38,5 @@ class AccountBackupPlanExecutionViewSet(viewsets.ModelViewSet):
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
pid = serializer.data.get('plan') pid = serializer.data.get('plan')
task = execute_account_backup_plan.delay(pid=str(pid), trigger=Trigger.manual) task = execute_account_backup_task.delay(pid=str(pid), trigger=Trigger.manual)
return Response({'task': task.id}, status=status.HTTP_201_CREATED) return Response({'task': task.id}, status=status.HTTP_201_CREATED)

View File

@ -4,7 +4,7 @@ from rest_framework import status, mixins, viewsets
from rest_framework.response import Response from rest_framework.response import Response
from accounts.models import AutomationExecution from accounts.models import AutomationExecution
from accounts.tasks import execute_automation from accounts.tasks import execute_account_automation_task
from assets import serializers from assets import serializers
from assets.models import BaseAutomation from assets.models import BaseAutomation
from common.const.choices import Trigger from common.const.choices import Trigger
@ -109,7 +109,7 @@ class AutomationExecutionViewSet(
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
automation = serializer.validated_data.get('automation') automation = serializer.validated_data.get('automation')
task = execute_automation.delay( task = execute_account_automation_task.delay(
pid=str(automation.pk), trigger=Trigger.manual, tp=self.tp pid=str(automation.pk), trigger=Trigger.manual, tp=self.tp
) )
return Response({'task': task.id}, status=status.HTTP_201_CREATED) return Response({'task': task.id}, status=status.HTTP_201_CREATED)

View File

@ -1,13 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from django.utils.translation import ugettext_lazy as _
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from accounts import serializers from accounts import serializers
from accounts.const import AutomationTypes from accounts.const import AutomationTypes
from accounts.const import Source
from accounts.filters import GatheredAccountFilterSet
from accounts.models import GatherAccountsAutomation from accounts.models import GatherAccountsAutomation
from accounts.models import GatheredAccount
from orgs.mixins.api import OrgBulkModelViewSet from orgs.mixins.api import OrgBulkModelViewSet
from .base import AutomationExecutionViewSet from .base import AutomationExecutionViewSet
__all__ = [ __all__ = [
'GatherAccountsAutomationViewSet', 'GatherAccountsExecutionViewSet' 'GatherAccountsAutomationViewSet', 'GatherAccountsExecutionViewSet',
'GatheredAccountViewSet'
] ]
@ -31,3 +40,32 @@ class GatherAccountsExecutionViewSet(AutomationExecutionViewSet):
queryset = super().get_queryset() queryset = super().get_queryset()
queryset = queryset.filter(automation__type=self.tp) queryset = queryset.filter(automation__type=self.tp)
return queryset return queryset
class GatheredAccountViewSet(OrgBulkModelViewSet):
model = GatheredAccount
search_fields = ('username',)
filterset_class = GatheredAccountFilterSet
serializer_classes = {
'default': serializers.GatheredAccountSerializer,
}
rbac_perms = {
'sync_account': 'assets.add_gatheredaccount',
}
@action(methods=['post'], detail=True, url_path='sync')
def sync_account(self, request, *args, **kwargs):
gathered_account = super().get_object()
asset = gathered_account.asset
username = gathered_account.username
accounts = asset.accounts.filter(username=username)
if accounts.exists():
accounts.update(source=Source.COLLECTED)
else:
asset.accounts.model.objects.create(
asset=asset, username=username,
name=f'{username}-{_("Collected")}',
source=Source.COLLECTED
)
return Response(status=status.HTTP_201_CREATED)

View File

@ -17,19 +17,19 @@ class VerifyHostCallbackMixin:
def host_callback(self, host, asset=None, account=None, automation=None, path_dir=None, **kwargs): def host_callback(self, host, asset=None, account=None, automation=None, path_dir=None, **kwargs):
host = super().host_callback( host = super().host_callback(
host, asset=asset, account=account, automation=automation, host, asset=asset, account=account,
path_dir=path_dir, **kwargs automation=automation, path_dir=path_dir, **kwargs
) )
if host.get('error'): if host.get('error'):
return host return host
accounts = asset.accounts.all() accounts = asset.accounts.all()
accounts = self.get_accounts(account, accounts) accounts = self.get_accounts(account, accounts)
inventory_hosts = [] inventory_hosts = []
for account in accounts: for account in accounts:
h = deepcopy(host) h = deepcopy(host)
h['name'] += '_' + account.username h['name'] += '(' + account.username + ')'
self.host_account_mapper[h['name']] = account self.host_account_mapper[h['name']] = account
secret = account.secret secret = account.secret

View File

@ -3,10 +3,6 @@
tasks: tasks:
- name: Test privileged account - name: Test privileged account
ansible.builtin.ping: ansible.builtin.ping:
#
# - name: print variables
# debug:
# msg: "Username: {{ account.username }}, Secret: {{ account.secret }}, Secret type: {{ secret_type }}"
- name: Change password - name: Change password
ansible.builtin.user: ansible.builtin.user:
@ -26,8 +22,8 @@
regexp: "{{ kwargs.regexp }}" regexp: "{{ kwargs.regexp }}"
state: absent state: absent
when: when:
- secret_type == "ssh_key" - secret_type == "ssh_key"
- kwargs.strategy == "set_jms" - kwargs.strategy == "set_jms"
- name: Change SSH key - name: Change SSH key
ansible.builtin.authorized_key: ansible.builtin.authorized_key:

View File

@ -99,7 +99,7 @@ class ChangeSecretManager(AccountBasePlaybookManager):
for account in accounts: for account in accounts:
h = deepcopy(host) h = deepcopy(host)
h['name'] += '_' + account.username h['name'] += '(' + account.username + ')'
new_secret = self.get_secret() new_secret = self.get_secret()
recorder = ChangeSecretRecord( recorder = ChangeSecretRecord(

View File

@ -68,7 +68,7 @@ class PushAccountManager(ChangeSecretManager, AccountBasePlaybookManager):
for account in accounts: for account in accounts:
h = deepcopy(host) h = deepcopy(host)
h['name'] += '_' + account.username h['name'] += '(' + account.username + ')'
new_secret = self.get_secret() new_secret = self.get_secret()
self.name_recorder_mapper[h['name']] = { self.name_recorder_mapper[h['name']] = {

View File

@ -50,7 +50,6 @@ class Migration(migrations.Migration):
options={ options={
'verbose_name': 'Account', 'verbose_name': 'Account',
'permissions': [('view_accountsecret', 'Can view asset account secret'), 'permissions': [('view_accountsecret', 'Can view asset account secret'),
('change_accountsecret', 'Can change asset account secret'),
('view_historyaccount', 'Can view asset history account'), ('view_historyaccount', 'Can view asset history account'),
('view_historyaccountsecret', 'Can view asset history account secret')], ('view_historyaccountsecret', 'Can view asset history account secret')],
'unique_together': {('username', 'asset', 'secret_type'), ('name', 'asset')}, 'unique_together': {('username', 'asset', 'secret_type'), ('name', 'asset')},

View File

@ -12,6 +12,6 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.AlterModelOptions( migrations.AlterModelOptions(
name='account', name='account',
options={'permissions': [('view_accountsecret', 'Can view asset account secret'), ('view_historyaccount', 'Can view asset history account'), ('view_historyaccountsecret', 'Can view asset history account secret')], 'verbose_name': 'Account'}, options={'permissions': [('view_accountsecret', 'Can view asset account secret'), ('view_historyaccount', 'Can view asset history account'), ('view_historyaccountsecret', 'Can view asset history account secret'), ('verify_account', 'Can verify account'), ('push_account', 'Can push account')], 'verbose_name': 'Account'},
), ),
] ]

View File

@ -0,0 +1,17 @@
# Generated by Django 3.2.14 on 2023-02-21 05:13
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0007_alter_account_options'),
]
operations = [
migrations.AlterModelOptions(
name='account',
options={'permissions': [('view_accountsecret', 'Can view asset account secret'), ('view_historyaccount', 'Can view asset history account'), ('view_historyaccountsecret', 'Can view asset history account secret'), ('verify_account', 'Can verify account'), ('push_account', 'Can push account')], 'verbose_name': 'Account'},
),
]

View File

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

View File

@ -64,6 +64,8 @@ class Account(AbsConnectivity, BaseAccount):
('view_accountsecret', _('Can view asset account secret')), ('view_accountsecret', _('Can view asset account secret')),
('view_historyaccount', _('Can view asset history account')), ('view_historyaccount', _('Can view asset history account')),
('view_historyaccountsecret', _('Can view asset history account secret')), ('view_historyaccountsecret', _('Can view asset history account secret')),
('verify_account', _('Can verify account')),
('push_account', _('Can push account')),
] ]
@lazyproperty @lazyproperty

View File

@ -7,11 +7,11 @@ from celery import current_task
from django.db import models from django.db import models
from django.db.models import F 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.const.choices import Trigger from common.const.choices import Trigger
from common.db.encoder import ModelJSONFieldEncoder from common.db.encoder import ModelJSONFieldEncoder
from common.utils import get_logger from common.utils import get_logger
from common.utils import lazyproperty
from ops.mixin import PeriodTaskModelMixin from ops.mixin import PeriodTaskModelMixin
from orgs.mixins.models import OrgModelMixin, JMSOrgBaseModel from orgs.mixins.models import OrgModelMixin, JMSOrgBaseModel
@ -36,9 +36,9 @@ class AccountBackupAutomation(PeriodTaskModelMixin, JMSOrgBaseModel):
verbose_name = _('Account backup plan') verbose_name = _('Account backup plan')
def get_register_task(self): def get_register_task(self):
from ...tasks import execute_account_backup_plan from ...tasks import execute_account_backup_task
name = "account_backup_plan_period_{}".format(str(self.id)[:8]) name = "account_backup_plan_period_{}".format(str(self.id)[:8])
task = execute_account_backup_plan.name task = execute_account_backup_task.name
args = (str(self.id), Trigger.timing) args = (str(self.id), Trigger.timing)
kwargs = {} kwargs = {}
return name, task, args, kwargs return name, task, args, kwargs

View File

@ -1,6 +1,6 @@
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from accounts.tasks import execute_automation from accounts.tasks import execute_account_automation_task
from assets.models.automations import ( from assets.models.automations import (
BaseAutomation as AssetBaseAutomation, BaseAutomation as AssetBaseAutomation,
AutomationExecution as AssetAutomationExecution AutomationExecution as AssetAutomationExecution
@ -16,7 +16,7 @@ class AccountBaseAutomation(AssetBaseAutomation):
@property @property
def execute_task(self): def execute_task(self):
return execute_automation return execute_account_automation_task
@property @property
def execution_model(self): def execution_model(self):

View File

@ -16,11 +16,11 @@ class ChangeSecretMixin(models.Model):
choices=SecretType.choices, max_length=16, choices=SecretType.choices, max_length=16,
default=SecretType.PASSWORD, verbose_name=_('Secret type') default=SecretType.PASSWORD, verbose_name=_('Secret type')
) )
secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret'))
secret_strategy = models.CharField( secret_strategy = models.CharField(
choices=SecretStrategy.choices, max_length=16, choices=SecretStrategy.choices, max_length=16,
default=SecretStrategy.custom, verbose_name=_('Secret strategy') default=SecretStrategy.custom, verbose_name=_('Secret strategy')
) )
secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret'))
password_rules = models.JSONField(default=dict, verbose_name=_('Password rules')) password_rules = models.JSONField(default=dict, verbose_name=_('Password rules'))
ssh_key_change_strategy = models.CharField( ssh_key_change_strategy = models.CharField(
choices=SSHKeyStrategy.choices, max_length=16, choices=SSHKeyStrategy.choices, max_length=16,

View File

@ -1,9 +1,35 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.utils.translation import ugettext_lazy as _
from orgs.mixins.models import JMSOrgBaseModel
from accounts.const import AutomationTypes from accounts.const import AutomationTypes
from .base import AccountBaseAutomation from .base import AccountBaseAutomation
__all__ = ['GatherAccountsAutomation'] __all__ = ['GatherAccountsAutomation', 'GatheredAccount']
class GatheredAccount(JMSOrgBaseModel):
present = models.BooleanField(default=True, verbose_name=_("Present"))
date_last_login = models.DateTimeField(null=True, verbose_name=_("Date last login"))
asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_("Asset"))
username = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=_('Username'))
address_last_login = models.CharField(max_length=39, default='', verbose_name=_("Address last login"))
@property
def address(self):
return self.asset.address
class Meta:
verbose_name = _('Gather account')
unique_together = [
('username', 'asset'),
]
ordering = ['asset']
def __str__(self):
return '{}: {}'.format(self.asset, self.username)
class GatherAccountsAutomation(AccountBaseAutomation): class GatherAccountsAutomation(AccountBaseAutomation):

View File

@ -9,7 +9,6 @@ __all__ = ['PushAccountAutomation']
class PushAccountAutomation(ChangeSecretMixin, AccountBaseAutomation): class PushAccountAutomation(ChangeSecretMixin, AccountBaseAutomation):
accounts = None
triggers = models.JSONField(max_length=16, default=list, verbose_name=_('Triggers')) triggers = models.JSONField(max_length=16, default=list, verbose_name=_('Triggers'))
username = models.CharField(max_length=128, verbose_name=_('Username')) username = models.CharField(max_length=128, verbose_name=_('Username'))
action = models.CharField(max_length=16, verbose_name=_('Action')) action = models.CharField(max_length=16, verbose_name=_('Action'))

View File

@ -1,30 +0,0 @@
# -*- coding: utf-8 -*-
#
from django.db import models
from django.utils.translation import ugettext_lazy as _
from orgs.mixins.models import JMSOrgBaseModel
__all__ = ['GatheredAccount']
class GatheredAccount(JMSOrgBaseModel):
present = models.BooleanField(default=True, verbose_name=_("Present"))
date_last_login = models.DateTimeField(null=True, verbose_name=_("Date last login"))
asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, verbose_name=_("Asset"))
username = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=_('Username'))
address_last_login = models.CharField(max_length=39, default='', verbose_name=_("Address last login"))
@property
def address(self):
return self.asset.address
class Meta:
verbose_name = _('Gather account')
unique_together = [
('username', 'asset'),
]
ordering = ['asset']
def __str__(self):
return '{}: {}'.format(self.asset, self.username)

View File

@ -3,7 +3,7 @@ from rest_framework import serializers
from accounts.const import SecretType, Source from accounts.const import SecretType, Source
from accounts.models import Account, AccountTemplate from accounts.models import Account, AccountTemplate
from accounts.tasks import push_accounts_to_assets from accounts.tasks import push_accounts_to_assets_task
from assets.const import Category, AllTypes from assets.const import Category, AllTypes
from assets.models import Asset from assets.models import Asset
from common.serializers import SecretReadableMixin, BulkModelSerializer from common.serializers import SecretReadableMixin, BulkModelSerializer
@ -43,7 +43,7 @@ class AccountSerializerCreateValidateMixin:
def push_account(instance, push_now): def push_account(instance, push_now):
if not push_now: if not push_now:
return return
push_accounts_to_assets.delay([instance.id], [instance.asset_id]) push_accounts_to_assets_task.delay([instance.id], [instance.asset_id])
def create(self, validated_data): def create(self, validated_data):
push_now = validated_data.pop('push_now', None) push_now = validated_data.pop('push_now', None)
@ -140,6 +140,11 @@ class AccountHistorySerializer(serializers.ModelSerializer):
class AccountTaskSerializer(serializers.Serializer): class AccountTaskSerializer(serializers.Serializer):
ACTION_CHOICES = ( ACTION_CHOICES = (
('test', 'test'), ('test', 'test'),
('verify', 'verify'),
('push', 'push'),
) )
action = serializers.ChoiceField(choices=ACTION_CHOICES, write_only=True) action = serializers.ChoiceField(choices=ACTION_CHOICES, write_only=True)
accounts = serializers.PrimaryKeyRelatedField(
queryset=Account.objects, required=False, allow_empty=True, many=True
)
task = serializers.CharField(read_only=True) task = serializers.CharField(read_only=True)

View File

@ -7,58 +7,12 @@ from .change_secret import (
class PushAccountAutomationSerializer(ChangeSecretAutomationSerializer): class PushAccountAutomationSerializer(ChangeSecretAutomationSerializer):
# dynamic_username = serializers.BooleanField(label=_('Dynamic username'), default=False)
# triggers = TreeChoicesField(
# choice_cls=TriggerChoice, label=_('Triggers'),
# default=TriggerChoice.all(),
# )
# action = LabeledChoiceField(
# choices=PushAccountActionChoice.choices, label=_('Action'),
# default=PushAccountActionChoice.create_and_push
# )
class Meta(ChangeSecretAutomationSerializer.Meta): class Meta(ChangeSecretAutomationSerializer.Meta):
model = PushAccountAutomation model = PushAccountAutomation
fields = copy.copy(ChangeSecretAutomationSerializer.Meta.fields) fields = [
fields.remove('recipients') n for n in ChangeSecretAutomationSerializer.Meta.fields
if n not in ['recipients']
# fields = ChangeSecretAutomationSerializer.Meta.fields + [ ]
# 'dynamic_username', 'triggers', 'action'
# ]
# def validate_username(self, value):
# if self.initial_data.get('dynamic_username'):
# value = '@USER'
# queryset = self.Meta.model.objects.filter(username=value)
# if self.instance:
# queryset = queryset.exclude(id=self.instance.id)
# if queryset.exists():
# raise serializers.ValidationError(_('Username already exists'))
# return value
#
# def validate_dynamic_username(self, value):
# if not value:
# return value
# queryset = self.Meta.model.objects.filter(username='@USER')
# if self.instance:
# queryset = queryset.exclude(id=self.instance.id)
# if queryset.exists():
# raise serializers.ValidationError(_('Dynamic username already exists'))
# return value
#
# def validate_triggers(self, value):
# # Now triggers readonly, set all
# return TriggerChoice.all()
#
# def get_field_names(self, declared_fields, info):
# fields = super().get_field_names(declared_fields, info)
# excludes = [
# 'recipients', 'is_periodic', 'interval', 'crontab',
# 'periodic_display', 'assets', 'nodes'
# ]
# fields = [f for f in fields if f not in excludes]
# fields[fields.index('accounts')] = 'username'
# return fields
class PushAccountUpdateAssetSerializer(ChangeSecretUpdateAssetSerializer): class PushAccountUpdateAssetSerializer(ChangeSecretUpdateAssetSerializer):

View File

@ -24,7 +24,7 @@ def task_activity_callback(self, pid, trigger, tp):
queue='ansible', verbose_name=_('Account execute automation'), queue='ansible', verbose_name=_('Account execute automation'),
activity_callback=task_activity_callback activity_callback=task_activity_callback
) )
def execute_automation(pid, trigger, tp): def execute_account_automation_task(pid, trigger, tp):
model = AutomationTypes.get_type_model(tp) model = AutomationTypes.get_type_model(tp)
with tmp_to_root_org(): with tmp_to_root_org():
instance = get_object_or_none(model, pk=pid) instance = get_object_or_none(model, pk=pid)

View File

@ -10,6 +10,7 @@ logger = get_logger(__file__)
def task_activity_callback(self, pid, trigger): def task_activity_callback(self, pid, trigger):
from accounts.models import AccountBackupAutomation
with tmp_to_root_org(): with tmp_to_root_org():
plan = get_object_or_none(AccountBackupAutomation, pk=pid) plan = get_object_or_none(AccountBackupAutomation, pk=pid)
if not plan: if not plan:
@ -22,7 +23,7 @@ def task_activity_callback(self, pid, trigger):
@shared_task(verbose_name=_('Execute account backup plan'), activity_callback=task_activity_callback) @shared_task(verbose_name=_('Execute account backup plan'), activity_callback=task_activity_callback)
def execute_account_backup_plan(pid, trigger): def execute_account_backup_task(pid, trigger):
from accounts.models import AccountBackupAutomation from accounts.models import AccountBackupAutomation
with tmp_to_root_org(): with tmp_to_root_org():
plan = get_object_or_none(AccountBackupAutomation, pk=pid) plan = get_object_or_none(AccountBackupAutomation, pk=pid)

View File

@ -4,17 +4,14 @@ from assets.tasks.common import generate_automation_execution_data
from common.const.choices import Trigger from common.const.choices import Trigger
def automation_execute_start(task_name, tp, task_snapshot=None): def quickstart_automation_by_snapshot(task_name, tp, task_snapshot=None):
from accounts.models import AutomationExecution from accounts.models import AutomationExecution
data = generate_automation_execution_data(task_name, tp, task_snapshot) data = generate_automation_execution_data(task_name, tp, task_snapshot)
while True: pk = data['id']
try: if AutomationExecution.objects.filter(id=pk).exists():
_id = data['id'] data['id'] = str(uuid.uuid4())
AutomationExecution.objects.get(id=_id)
data['id'] = str(uuid.uuid4())
except AutomationExecution.DoesNotExist:
break
execution = AutomationExecution.objects.create( execution = AutomationExecution.objects.create(
trigger=Trigger.manual, **data trigger=Trigger.manual, **data
) )

View File

@ -4,12 +4,12 @@ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_noop from django.utils.translation import gettext_noop
from accounts.const import AutomationTypes from accounts.const import AutomationTypes
from accounts.tasks.common import automation_execute_start from accounts.tasks.common import quickstart_automation_by_snapshot
from assets.models import Node from assets.models import Node
from common.utils import get_logger from common.utils import get_logger
from orgs.utils import org_aware_func from orgs.utils import org_aware_func
__all__ = ['gather_asset_accounts'] __all__ = ['gather_asset_accounts_task']
logger = get_logger(__name__) logger = get_logger(__name__)
@ -22,14 +22,14 @@ def gather_asset_accounts_util(nodes, task_name):
'nodes': [str(node.id) for node in nodes], 'nodes': [str(node.id) for node in nodes],
} }
tp = AutomationTypes.verify_account tp = AutomationTypes.verify_account
automation_execute_start(task_name, tp, task_snapshot) quickstart_automation_by_snapshot(task_name, tp, task_snapshot)
@shared_task( @shared_task(
queue="ansible", verbose_name=_('Gather asset accounts'), queue="ansible", verbose_name=_('Gather asset accounts'),
activity_callback=lambda self, node_ids, task_name=None: (node_ids, None) activity_callback=lambda self, node_ids, task_name=None: (node_ids, None)
) )
def gather_asset_accounts(node_ids, task_name=None): def gather_asset_accounts_task(node_ids, task_name=None):
if task_name is None: if task_name is None:
task_name = gettext_noop("Gather assets accounts") task_name = gettext_noop("Gather assets accounts")

View File

@ -2,45 +2,33 @@ from celery import shared_task
from django.utils.translation import gettext_noop, ugettext_lazy as _ from django.utils.translation import gettext_noop, ugettext_lazy as _
from accounts.const import AutomationTypes from accounts.const import AutomationTypes
from accounts.tasks.common import automation_execute_start from accounts.tasks.common import quickstart_automation_by_snapshot
from common.utils import get_logger from common.utils import get_logger
from orgs.utils import org_aware_func
logger = get_logger(__file__) logger = get_logger(__file__)
__all__ = [ __all__ = [
'push_accounts_to_assets', 'push_accounts_to_assets_task',
] ]
def push_util(account, assets, task_name):
task_snapshot = {
'secret': account.secret,
'secret_type': account.secret_type,
'accounts': [account.username],
'assets': [str(asset.id) for asset in assets],
}
tp = AutomationTypes.push_account
automation_execute_start(task_name, tp, task_snapshot)
@org_aware_func("assets")
def push_accounts_to_assets_util(accounts, assets):
from accounts.models import PushAccountAutomation
task_name = gettext_noop("Push accounts to assets")
task_name = PushAccountAutomation.generate_unique_name(task_name)
for account in accounts:
push_util(account, assets, task_name)
@shared_task( @shared_task(
queue="ansible", verbose_name=_('Push accounts to assets'), queue="ansible", verbose_name=_('Push accounts to assets'),
activity_callback=lambda self, account_ids, asset_ids: (account_ids, None) activity_callback=lambda self, account_ids, asset_ids: (account_ids, None)
) )
def push_accounts_to_assets(account_ids, asset_ids): def push_accounts_to_assets_task(account_ids):
from assets.models import Asset from accounts.models import PushAccountAutomation
from accounts.models import Account from accounts.models import Account
assets = Asset.objects.filter(id__in=asset_ids)
accounts = Account.objects.filter(id__in=account_ids) accounts = Account.objects.filter(id__in=account_ids)
return push_accounts_to_assets_util(accounts, assets) task_name = gettext_noop("Push accounts to assets")
task_name = PushAccountAutomation.generate_unique_name(task_name)
for account in accounts:
task_snapshot = {
'secret': account.secret,
'secret_type': account.secret_type,
'accounts': [account.username],
'assets': [str(account.asset_id)],
}
tp = AutomationTypes.push_account
quickstart_automation_by_snapshot(task_name, tp, task_snapshot)

View File

@ -1,16 +1,16 @@
from celery import shared_task from celery import shared_task
from django.utils.translation import gettext_noop
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_noop
from accounts.const import AutomationTypes from accounts.const import AutomationTypes
from accounts.tasks.common import automation_execute_start from accounts.tasks.common import quickstart_automation_by_snapshot
from assets.const import GATEWAY_NAME from assets.const import GATEWAY_NAME
from common.utils import get_logger from common.utils import get_logger
from orgs.utils import org_aware_func from orgs.utils import org_aware_func
logger = get_logger(__name__) logger = get_logger(__name__)
__all__ = [ __all__ = [
'verify_accounts_connectivity' 'verify_accounts_connectivity_task'
] ]
@ -22,19 +22,26 @@ def verify_connectivity_util(assets, tp, accounts, task_name):
'accounts': account_usernames, 'accounts': account_usernames,
'assets': [str(asset.id) for asset in assets], 'assets': [str(asset.id) for asset in assets],
} }
automation_execute_start(task_name, tp, task_snapshot) quickstart_automation_by_snapshot(task_name, tp, task_snapshot)
@org_aware_func("assets") @org_aware_func("assets")
def verify_accounts_connectivity_util(accounts, assets, task_name): def verify_accounts_connectivity_util(accounts, task_name):
gateway_assets = assets.filter(platform__name=GATEWAY_NAME) from assets.models import Asset
asset_ids = [a.asset_id for a in accounts]
assets = Asset.objects.filter(id__in=asset_ids)
gateways = assets.filter(platform__name=GATEWAY_NAME)
verify_connectivity_util( verify_connectivity_util(
gateway_assets, AutomationTypes.verify_gateway_account, accounts, task_name gateways, AutomationTypes.verify_gateway_account,
accounts, task_name
) )
non_gateway_assets = assets.exclude(platform__name=GATEWAY_NAME) common_assets = assets.exclude(platform__name=GATEWAY_NAME)
verify_connectivity_util( verify_connectivity_util(
non_gateway_assets, AutomationTypes.verify_account, accounts, task_name common_assets, AutomationTypes.verify_account,
accounts, task_name
) )
@ -42,11 +49,9 @@ def verify_accounts_connectivity_util(accounts, assets, task_name):
queue="ansible", verbose_name=_('Verify asset account availability'), queue="ansible", verbose_name=_('Verify asset account availability'),
activity_callback=lambda self, account_ids, asset_ids: (account_ids, None) activity_callback=lambda self, account_ids, asset_ids: (account_ids, None)
) )
def verify_accounts_connectivity(account_ids, asset_ids): def verify_accounts_connectivity_task(account_ids):
from assets.models import Asset
from accounts.models import Account, VerifyAccountAutomation from accounts.models import Account, VerifyAccountAutomation
assets = Asset.objects.filter(id__in=asset_ids)
accounts = Account.objects.filter(id__in=account_ids) accounts = Account.objects.filter(id__in=account_ids)
task_name = gettext_noop("Verify accounts connectivity") task_name = gettext_noop("Verify accounts connectivity")
task_name = VerifyAccountAutomation.generate_unique_name(task_name) task_name = VerifyAccountAutomation.generate_unique_name(task_name)
return verify_accounts_connectivity_util(accounts, assets, task_name) return verify_accounts_connectivity_util(accounts, task_name)

View File

@ -25,17 +25,22 @@ router.register(r'push-account-executions', api.PushAccountExecutionViewSet, 'pu
router.register(r'push-account-records', api.PushAccountRecordViewSet, 'push-account-record') router.register(r'push-account-records', api.PushAccountRecordViewSet, 'push-account-record')
urlpatterns = [ urlpatterns = [
path('accounts/tasks/', api.AccountTaskCreateAPI.as_view(), name='account-task-create'), path('accounts/tasks/', api.AccountsTaskCreateAPI.as_view(), name='account-task-create'),
path('account-secrets/<uuid:pk>/histories/', api.AccountHistoriesSecretAPI.as_view(), name='account-secret-history'), path('account-secrets/<uuid:pk>/histories/', api.AccountHistoriesSecretAPI.as_view(),
name='account-secret-history'),
path('change-secret/<uuid:pk>/asset/remove/', api.ChangSecretRemoveAssetApi.as_view(), name='change-secret-remove-asset'), path('change-secret/<uuid:pk>/asset/remove/', api.ChangSecretRemoveAssetApi.as_view(),
name='change-secret-remove-asset'),
path('change-secret/<uuid:pk>/asset/add/', api.ChangSecretAddAssetApi.as_view(), name='change-secret-add-asset'), path('change-secret/<uuid:pk>/asset/add/', api.ChangSecretAddAssetApi.as_view(), name='change-secret-add-asset'),
path('change-secret/<uuid:pk>/nodes/', api.ChangSecretNodeAddRemoveApi.as_view(), name='change-secret-add-or-remove-node'), path('change-secret/<uuid:pk>/nodes/', api.ChangSecretNodeAddRemoveApi.as_view(),
name='change-secret-add-or-remove-node'),
path('change-secret/<uuid:pk>/assets/', api.ChangSecretAssetsListApi.as_view(), name='change-secret-assets'), path('change-secret/<uuid:pk>/assets/', api.ChangSecretAssetsListApi.as_view(), name='change-secret-assets'),
path('push-account/<uuid:pk>/asset/remove/', api.PushAccountRemoveAssetApi.as_view(), name='push-account-remove-asset'), path('push-account/<uuid:pk>/asset/remove/', api.PushAccountRemoveAssetApi.as_view(),
name='push-account-remove-asset'),
path('push-accountt/<uuid:pk>/asset/add/', api.PushAccountAddAssetApi.as_view(), name='push-account-add-asset'), path('push-accountt/<uuid:pk>/asset/add/', api.PushAccountAddAssetApi.as_view(), name='push-account-add-asset'),
path('push-account/<uuid:pk>/nodes/', api.PushAccountNodeAddRemoveApi.as_view(), name='push-account-add-or-remove-node'), path('push-account/<uuid:pk>/nodes/', api.PushAccountNodeAddRemoveApi.as_view(),
name='push-account-add-or-remove-node'),
path('push-account/<uuid:pk>/assets/', api.PushAccountAssetsListApi.as_view(), name='push-account-assets'), path('push-account/<uuid:pk>/assets/', api.PushAccountAssetsListApi.as_view(), name='push-account-assets'),
] ]

View File

@ -6,7 +6,7 @@ from django.utils.translation import gettext as _
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from accounts.tasks import push_accounts_to_assets, verify_accounts_connectivity from accounts.tasks import push_accounts_to_assets_task, verify_accounts_connectivity_task
from assets import serializers from assets import serializers
from assets.filters import IpInFilterBackend, LabelFilterBackend, NodeFilterBackend from assets.filters import IpInFilterBackend, LabelFilterBackend, NodeFilterBackend
from assets.models import Asset, Gateway from assets.models import Asset, Gateway
@ -180,9 +180,9 @@ class AssetTaskCreateApi(AssetsTaskMixin, generics.CreateAPIView):
def check_permissions(self, request): def check_permissions(self, request):
action_perm_require = { action_perm_require = {
"refresh": "assets.refresh_assethardwareinfo", "refresh": "assets.refresh_assethardwareinfo",
"push_account": "accounts.add_pushaccountexecution", "push_account": "accounts.push_account",
"test": "assets.test_assetconnectivity", "test": "assets.test_assetconnectivity",
"test_account": "assets.test_account", "test_account": "accounts.verify_account",
} }
_action = request.data.get("action") _action = request.data.get("action")
perm_required = action_perm_require.get(_action) perm_required = action_perm_require.get(_action)
@ -205,9 +205,9 @@ class AssetTaskCreateApi(AssetsTaskMixin, generics.CreateAPIView):
asset_ids = [asset.id] asset_ids = [asset.id]
account_ids = accounts.values_list("id", flat=True) account_ids = accounts.values_list("id", flat=True)
if action == "push_account": if action == "push_account":
task = push_accounts_to_assets.delay(account_ids, asset_ids) task = push_accounts_to_assets_task.delay(account_ids, asset_ids)
elif action == "test_account": elif action == "test_account":
task = verify_accounts_connectivity.delay(account_ids, asset_ids) task = verify_accounts_connectivity_task.delay(account_ids, asset_ids)
else: else:
task = None task = None
return task return task

View File

@ -103,7 +103,7 @@ class NodeAddAssetsApi(generics.UpdateAPIView):
instance = None instance = None
permission_classes = (RBACPermission,) permission_classes = (RBACPermission,)
rbac_perms = { rbac_perms = {
'PUT': 'assets.add_assettonode', 'PUT': 'assets.change_assetnodes',
} }
def perform_update(self, serializer): def perform_update(self, serializer):
@ -118,7 +118,7 @@ class NodeRemoveAssetsApi(generics.UpdateAPIView):
instance = None instance = None
permission_classes = (RBACPermission,) permission_classes = (RBACPermission,)
rbac_perms = { rbac_perms = {
'PUT': 'assets.remove_assetfromnode', 'PUT': 'assets.change_assetnodes',
} }
def perform_update(self, serializer): def perform_update(self, serializer):
@ -140,7 +140,7 @@ class MoveAssetsToNodeApi(generics.UpdateAPIView):
instance = None instance = None
permission_classes = (RBACPermission,) permission_classes = (RBACPermission,)
rbac_perms = { rbac_perms = {
'PUT': 'assets.move_assettonode', 'PUT': 'assets.change_assetnodes',
} }
def perform_update(self, serializer): def perform_update(self, serializer):

View File

@ -63,6 +63,8 @@ class BasePlaybookManager:
) )
if not os.path.exists(path): if not os.path.exists(path):
os.makedirs(path, exist_ok=True, mode=0o755) os.makedirs(path, exist_ok=True, mode=0o755)
if settings.DEBUG_DEV:
logger.debug('Ansible runtime dir: {}'.format(path))
return path return path
@staticmethod @staticmethod

View File

@ -33,7 +33,7 @@ class PingGatewayManager:
err = _('No account') err = _('No account')
return False, err return False, err
print('Test account: {}'.format(account)) print('- ' + _('Asset, {}, using account {}').format(gateway, account))
try: try:
proxy.connect( proxy.connect(
gateway.address, gateway.address,

View File

@ -15,4 +15,29 @@ class Migration(migrations.Migration):
name='charset', name='charset',
field=models.CharField(choices=[('utf-8', 'UTF-8'), ('gbk', 'GBK')], default='utf-8', max_length=8, verbose_name='Charset'), field=models.CharField(choices=[('utf-8', 'UTF-8'), ('gbk', 'GBK')], default='utf-8', max_length=8, verbose_name='Charset'),
), ),
migrations.AddField(
model_name='platform',
name='created_by',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Created by'),
),
migrations.AddField(
model_name='platform',
name='date_created',
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created'),
),
migrations.AddField(
model_name='platform',
name='date_updated',
field=models.DateTimeField(auto_now=True, verbose_name='Date updated'),
),
migrations.AddField(
model_name='platform',
name='updated_by',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Updated by'),
),
migrations.AlterField(
model_name='platform',
name='comment',
field=models.TextField(blank=True, default='', verbose_name='Comment'),
),
] ]

View File

@ -12,6 +12,6 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.AlterModelOptions( migrations.AlterModelOptions(
name='asset', name='asset',
options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetaccount', 'Can push account to asset'), ('test_account', 'Can verify account'), ('match_asset', 'Can match asset'), ('add_assettonode', 'Add asset to node'), ('move_assettonode', 'Move asset to node'), ('remove_assetfromnode', 'Remove asset from node')], 'verbose_name': 'Asset'}, options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetaccount', 'Can push account to asset'), ('test_account', 'Can verify account'), ('match_asset', 'Can match asset'), ('change_assettonode', 'Can change asset nodes')], 'verbose_name': 'Asset'},
), ),
] ]

View File

@ -0,0 +1,17 @@
# Generated by Django 3.2.14 on 2023-02-21 05:11
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('assets', '0109_alter_asset_options'),
]
operations = [
migrations.AlterModelOptions(
name='asset',
options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetaccount', 'Can push account to asset'), ('test_account', 'Can verify account'), ('match_asset', 'Can match asset'), ('change_assetnodes', 'Can change asset nodes')], 'verbose_name': 'Asset'},
),
]

View File

@ -1,38 +0,0 @@
# Generated by Django 3.2.14 on 2023-02-20 02:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assets', '0109_alter_asset_options'),
]
operations = [
migrations.AddField(
model_name='platform',
name='created_by',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Created by'),
),
migrations.AddField(
model_name='platform',
name='date_created',
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created'),
),
migrations.AddField(
model_name='platform',
name='date_updated',
field=models.DateTimeField(auto_now=True, verbose_name='Date updated'),
),
migrations.AddField(
model_name='platform',
name='updated_by',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Updated by'),
),
migrations.AlterField(
model_name='platform',
name='comment',
field=models.TextField(blank=True, default='', verbose_name='Comment'),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 3.2.14 on 2023-02-21 05:22
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('assets', '0110_alter_asset_options'),
]
operations = [
migrations.AlterModelOptions(
name='asset',
options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('match_asset', 'Can match asset'), ('change_assetnodes', 'Can change asset nodes')], 'verbose_name': 'Asset'},
),
]

View File

@ -281,10 +281,6 @@ class Asset(NodesRelationMixin, AbsConnectivity, JMSOrgBaseModel):
permissions = [ permissions = [
('refresh_assethardwareinfo', _('Can refresh asset hardware info')), ('refresh_assethardwareinfo', _('Can refresh asset hardware info')),
('test_assetconnectivity', _('Can test asset connectivity')), ('test_assetconnectivity', _('Can test asset connectivity')),
('push_assetaccount', _('Can push account to asset')),
('test_account', _('Can verify account')),
('match_asset', _('Can match asset')), ('match_asset', _('Can match asset')),
('add_assettonode', _('Add asset to node')), ('change_assetnodes', _('Can change asset nodes')),
('move_assettonode', _('Move asset to node')),
('remove_assetfromnode', _('Remove asset from node'))
] ]

View File

@ -6,7 +6,7 @@ from django.utils.translation import ugettext_lazy as _
from assets.models.asset import Asset from assets.models.asset import Asset
from assets.models.node import Node from assets.models.node import Node
from assets.tasks import execute_automation from assets.tasks import execute_asset_automation_task
from common.const.choices import Trigger from common.const.choices import Trigger
from common.db.fields import EncryptJsonDictTextField from common.db.fields import EncryptJsonDictTextField
from ops.mixin import PeriodTaskModelMixin from ops.mixin import PeriodTaskModelMixin
@ -49,7 +49,7 @@ class BaseAutomation(PeriodTaskModelMixin, JMSOrgBaseModel):
@property @property
def execute_task(self): def execute_task(self):
return execute_automation return execute_asset_automation_task
def get_register_task(self): def get_register_task(self):
name = f"automation_{self.type}_strategy_period_{str(self.id)[:8]}" name = f"automation_{self.type}_strategy_period_{str(self.id)[:8]}"

View File

@ -30,11 +30,11 @@ class Domain(JMSOrgBaseModel):
def random_gateway(self): def random_gateway(self):
gateways = [gw for gw in self.active_gateways if gw.is_connective] gateways = [gw for gw in self.active_gateways if gw.is_connective]
if not gateways: if not gateways:
logger.warn(f'Gateway all bad. domain={self}, gateway_num={len(gateways)}.')
gateways = self.active_gateways gateways = self.active_gateways
if not gateways: if not gateways:
logger.warn(f'Not active gateway. domain={self}') logger.warn(f'Not active gateway, domain={self}, pass')
return None return None
return random.choice(gateways) return random.choice(gateways)

View File

@ -83,7 +83,7 @@ class AssetAccountSerializer(
def validate_push_now(self, value): def validate_push_now(self, value):
request = self.context['request'] request = self.context['request']
if not request.user.has_perms('assets.push_assetaccount'): if not request.user.has_perms('accounts.push_account'):
return False return False
return value return value

View File

@ -1,9 +1,9 @@
from celery import shared_task from celery import shared_task
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from orgs.utils import tmp_to_root_org, tmp_to_org
from common.utils import get_logger, get_object_or_none
from assets.const import AutomationTypes from assets.const import AutomationTypes
from common.utils import get_logger, get_object_or_none
from orgs.utils import tmp_to_root_org, tmp_to_org
logger = get_logger(__file__) logger = get_logger(__file__)
@ -24,7 +24,7 @@ def task_activity_callback(self, pid, trigger, tp):
queue='ansible', verbose_name=_('Asset execute automation'), queue='ansible', verbose_name=_('Asset execute automation'),
activity_callback=task_activity_callback activity_callback=task_activity_callback
) )
def execute_automation(pid, trigger, tp): def execute_asset_automation_task(pid, trigger, tp):
model = AutomationTypes.get_type_model(tp) model = AutomationTypes.get_type_model(tp)
with tmp_to_root_org(): with tmp_to_root_org():
instance = get_object_or_none(model, pk=pid) instance = get_object_or_none(model, pk=pid)

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:8285be68ee7edb5423cf973c1c96a3659b75b40566c07a1557a17d59fcaf294d oid sha256:014483808a830a01f5432fdc44bc34f7f392e53a160ffa97eb377dbb49e0ec9a
size 136019 size 135547

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-20 19:19+0800\n" "POT-Creation-Date: 2023-02-21 13:46+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -158,7 +158,8 @@ msgstr "作成してプッシュ"
msgid "Only create" msgid "Only create"
msgstr "作成のみ" msgstr "作成のみ"
#: accounts/models/account.py:47 accounts/models/gathered_account.py:14 #: accounts/models/account.py:47
#: accounts/models/automations/gather_account.py:16
#: accounts/serializers/account/account.py:95 #: accounts/serializers/account/account.py:95
#: accounts/serializers/account/gathered_account.py:10 #: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:107 #: accounts/serializers/automations/change_secret.py:107
@ -181,7 +182,7 @@ msgid "Su from"
msgstr "から切り替え" msgstr "から切り替え"
#: accounts/models/account.py:53 settings/serializers/auth/cas.py:20 #: accounts/models/account.py:53 settings/serializers/auth/cas.py:20
#: terminal/models/applet/applet.py:28 #: terminal/models/applet/applet.py:29
msgid "Version" msgid "Version"
msgstr "バージョン" msgstr "バージョン"
@ -214,15 +215,23 @@ msgstr "資産履歴アカウントを表示できます"
msgid "Can view asset history account secret" msgid "Can view asset history account secret"
msgstr "資産履歴アカウントパスワードを表示できます" msgstr "資産履歴アカウントパスワードを表示できます"
#: accounts/models/account.py:111 #: accounts/models/account.py:67
msgid "Can verify account"
msgstr "アカウントを確認できます"
#: accounts/models/account.py:68
msgid "Can push account"
msgstr "アカウントをプッシュできます"
#: accounts/models/account.py:113
msgid "Account template" msgid "Account template"
msgstr "アカウント テンプレート" msgstr "アカウント テンプレート"
#: accounts/models/account.py:116 #: accounts/models/account.py:118
msgid "Can view asset account template secret" msgid "Can view asset account template secret"
msgstr "アセット アカウント テンプレートのパスワードを表示できます" msgstr "アセット アカウント テンプレートのパスワードを表示できます"
#: accounts/models/account.py:117 #: accounts/models/account.py:119
msgid "Can change asset account template secret" msgid "Can change asset account template secret"
msgstr "アセット アカウント テンプレートのパスワードを変更できます" msgstr "アセット アカウント テンプレートのパスワードを変更できます"
@ -241,7 +250,7 @@ msgstr "アカウントバックアップ計画"
#: accounts/models/automations/backup_account.py:83 #: accounts/models/automations/backup_account.py:83
#: assets/models/automations/base.py:114 audits/models.py:55 #: assets/models/automations/base.py:114 audits/models.py:55
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:122 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:122
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:108 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:109
#: terminal/models/session/session.py:45 #: terminal/models/session/session.py:45
#: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:19 #: tickets/models/ticket/apply_asset.py:19
@ -327,12 +336,7 @@ msgstr "プッシュ アカウントの作成の実行"
msgid "Secret type" msgid "Secret type"
msgstr "鍵の種類" msgstr "鍵の種類"
#: accounts/models/automations/change_secret.py:21 #: accounts/models/automations/change_secret.py:19
#: accounts/serializers/automations/change_secret.py:40
msgid "Secret strategy"
msgstr "鍵ポリシー"
#: accounts/models/automations/change_secret.py:23
#: accounts/models/automations/change_secret.py:72 accounts/models/base.py:38 #: accounts/models/automations/change_secret.py:72 accounts/models/base.py:38
#: authentication/models/temp_token.py:10 #: authentication/models/temp_token.py:10
#: authentication/templates/authentication/_access_key_modal.html:31 #: authentication/templates/authentication/_access_key_modal.html:31
@ -340,6 +344,11 @@ msgstr "鍵ポリシー"
msgid "Secret" msgid "Secret"
msgstr "ひみつ" msgstr "ひみつ"
#: accounts/models/automations/change_secret.py:22
#: accounts/serializers/automations/change_secret.py:40
msgid "Secret strategy"
msgstr "鍵ポリシー"
#: accounts/models/automations/change_secret.py:24 #: accounts/models/automations/change_secret.py:24
msgid "Password rules" msgid "Password rules"
msgstr "パスワードルール" msgstr "パスワードルール"
@ -363,7 +372,7 @@ msgstr "開始日"
#: accounts/models/automations/change_secret.py:74 #: accounts/models/automations/change_secret.py:74
#: assets/models/automations/base.py:115 ops/models/base.py:56 #: assets/models/automations/base.py:115 ops/models/base.py:56
#: ops/models/celery.py:64 ops/models/job.py:123 #: ops/models/celery.py:64 ops/models/job.py:123
#: terminal/models/applet/host.py:109 #: terminal/models/applet/host.py:110
msgid "Date finished" msgid "Date finished"
msgstr "終了日" msgstr "終了日"
@ -376,20 +385,19 @@ msgstr "間違い"
msgid "Change secret record" msgid "Change secret record"
msgstr "パスワード レコードの変更" msgstr "パスワード レコードの変更"
#: accounts/models/automations/gather_account.py:14
msgid "Present"
msgstr "存在する"
#: accounts/models/automations/gather_account.py:15 #: accounts/models/automations/gather_account.py:15
#: accounts/tasks/gather_accounts.py:29 msgid "Date last login"
msgid "Gather asset accounts" msgstr "最終ログイン日"
msgstr "アカウントのコレクション"
#: accounts/models/automations/push_account.py:13 #: accounts/models/automations/gather_account.py:17
msgid "Triggers" #: accounts/models/automations/push_account.py:13 accounts/models/base.py:34
msgstr "トリガー方式" #: acls/serializers/base.py:18 acls/serializers/base.py:49
#: assets/models/_user.py:23 audits/models.py:157 authentication/forms.py:25
#: accounts/models/automations/push_account.py:14 accounts/models/base.py:34 #: authentication/forms.py:27 authentication/models/temp_token.py:9
#: accounts/models/gathered_account.py:15 acls/serializers/base.py:18
#: acls/serializers/base.py:49 assets/models/_user.py:23 audits/models.py:157
#: authentication/forms.py:25 authentication/forms.py:27
#: authentication/models/temp_token.py:9
#: 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
#: users/forms/profile.py:32 users/forms/profile.py:112 #: users/forms/profile.py:32 users/forms/profile.py:112
@ -398,7 +406,24 @@ msgstr "トリガー方式"
msgid "Username" msgid "Username"
msgstr "ユーザー名" msgstr "ユーザー名"
#: accounts/models/automations/push_account.py:15 acls/models/base.py:81 #: accounts/models/automations/gather_account.py:18
msgid "Address last login"
msgstr "最終ログインアドレス"
#: accounts/models/automations/gather_account.py:25 rbac/tree.py:50
msgid "Gather account"
msgstr "アカウントを集める"
#: accounts/models/automations/gather_account.py:41
#: accounts/tasks/gather_accounts.py:29
msgid "Gather asset accounts"
msgstr "アカウントのコレクション"
#: accounts/models/automations/push_account.py:12
msgid "Triggers"
msgstr "トリガー方式"
#: accounts/models/automations/push_account.py:14 acls/models/base.py:81
#: acls/serializers/base.py:81 acls/serializers/login_acl.py:25 #: acls/serializers/base.py:81 acls/serializers/login_acl.py:25
#: assets/models/cmd_filter.py:81 audits/models.py:65 audits/serializers.py:82 #: assets/models/cmd_filter.py:81 audits/models.py:65 audits/serializers.py:82
#: authentication/serializers/connect_token_secret.py:109 #: authentication/serializers/connect_token_secret.py:109
@ -406,7 +431,7 @@ msgstr "ユーザー名"
msgid "Action" msgid "Action"
msgstr "アクション" msgstr "アクション"
#: accounts/models/automations/push_account.py:41 #: accounts/models/automations/push_account.py:40
msgid "Push asset account" msgid "Push asset account"
msgstr "アカウントプッシュ" msgstr "アカウントプッシュ"
@ -422,13 +447,13 @@ msgstr "アカウントの確認"
#: assets/models/group.py:20 assets/models/label.py:18 #: assets/models/group.py:20 assets/models/label.py:18
#: assets/models/platform.py:21 assets/models/platform.py:76 #: assets/models/platform.py:21 assets/models/platform.py:76
#: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142 #: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142
#: assets/serializers/platform.py:132 #: assets/serializers/platform.py:91 assets/serializers/platform.py:136
#: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21 #: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:26 ops/models/playbook.py:23 ops/serializers/job.py:19 #: ops/models/job.py:26 ops/models/playbook.py:23 ops/serializers/job.py:19
#: orgs/models.py:69 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: orgs/models.py:69 perms/models/asset_permission.py:56 rbac/models/role.py:29
#: settings/models.py:33 settings/serializers/sms.py:6 #: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:26 terminal/models/component/endpoint.py:12 #: terminal/models/applet/applet.py:27 terminal/models/component/endpoint.py:12
#: terminal/models/component/endpoint.py:90 #: terminal/models/component/endpoint.py:90
#: terminal/models/component/storage.py:26 terminal/models/component/task.py:15 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:15
#: terminal/models/component/terminal.py:79 users/forms/profile.py:33 #: terminal/models/component/terminal.py:79 users/forms/profile.py:33
@ -445,26 +470,10 @@ msgstr "特権アカウント"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22 #: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:107 #: authentication/serializers/connect_token_secret.py:107
#: terminal/models/applet/applet.py:31 users/serializers/user.py:159 #: terminal/models/applet/applet.py:32 users/serializers/user.py:159
msgid "Is active" msgid "Is active"
msgstr "アクティブです。" msgstr "アクティブです。"
#: accounts/models/gathered_account.py:12
msgid "Present"
msgstr "存在する"
#: accounts/models/gathered_account.py:13
msgid "Date last login"
msgstr "最終ログイン日"
#: accounts/models/gathered_account.py:16
msgid "Address last login"
msgstr "最終ログインアドレス"
#: accounts/models/gathered_account.py:23 rbac/tree.py:50
msgid "Gather account"
msgstr "アカウントを集める"
#: accounts/notifications.py:8 #: accounts/notifications.py:8
msgid "Notification of account backup route task results" msgid "Notification of account backup route task results"
msgstr "アカウントバックアップルートタスクの結果の通知" msgstr "アカウントバックアップルートタスクの結果の通知"
@ -524,7 +533,7 @@ msgstr "エスクローされたパスワード"
#: accounts/serializers/account/account.py:75 applications/models.py:11 #: accounts/serializers/account/account.py:75 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:77 #: assets/models/label.py:21 assets/models/platform.py:77
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
#: assets/serializers/platform.py:93 assets/serializers/platform.py:133 #: assets/serializers/platform.py:97 assets/serializers/platform.py:137
#: perms/serializers/user_permission.py:25 settings/models.py:35 #: perms/serializers/user_permission.py:25 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13 #: tickets/models/ticket/apply_application.py:13
msgid "Category" msgid "Category"
@ -535,10 +544,10 @@ msgstr "カテゴリ"
#: acls/serializers/command_acl.py:18 applications/models.py:14 #: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:78 #: assets/models/cmd_filter.py:74 assets/models/platform.py:78
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:92 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96
#: audits/serializers.py:48 #: audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:37 #: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:37
#: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:30 #: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:31
#: terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:28 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:28
#: terminal/serializers/session.py:22 terminal/serializers/storage.py:224 #: terminal/serializers/session.py:22 terminal/serializers/storage.py:224
@ -643,7 +652,7 @@ msgstr "失敗しました"
msgid "Account execute automation" msgid "Account execute automation"
msgstr "アカウント実行の自動化" msgstr "アカウント実行の自動化"
#: accounts/tasks/backup_account.py:24 #: accounts/tasks/backup_account.py:25
msgid "Execute account backup plan" msgid "Execute account backup plan"
msgstr "アカウントのバックアップ計画を実施する" msgstr "アカウントのバックアップ計画を実施する"
@ -651,15 +660,15 @@ msgstr "アカウントのバックアップ計画を実施する"
msgid "Gather assets accounts" msgid "Gather assets accounts"
msgstr "資産の口座番号を収集する" msgstr "資産の口座番号を収集する"
#: accounts/tasks/push_account.py:30 accounts/tasks/push_account.py:37 #: accounts/tasks/push_account.py:15 accounts/tasks/push_account.py:23
msgid "Push accounts to assets" msgid "Push accounts to assets"
msgstr "アカウントをアセットにプッシュ:" msgstr "アカウントをアセットにプッシュ:"
#: accounts/tasks/verify_account.py:42 #: accounts/tasks/verify_account.py:49
msgid "Verify asset account availability" msgid "Verify asset account availability"
msgstr "アセット アカウントの可用性を確認する" msgstr "アセット アカウントの可用性を確認する"
#: accounts/tasks/verify_account.py:50 #: accounts/tasks/verify_account.py:55
msgid "Verify accounts connectivity" msgid "Verify accounts connectivity"
msgstr "アカウント接続のテスト" msgstr "アカウント接続のテスト"
@ -921,7 +930,7 @@ msgstr "削除に失敗し、ノードにアセットが含まれています。
msgid "App assets" msgid "App assets"
msgstr "アプリ資産" msgstr "アプリ資産"
#: assets/automations/base/manager.py:105 #: assets/automations/base/manager.py:107
msgid "{} disabled" msgid "{} disabled"
msgstr "{} 無効" msgstr "{} 無効"
@ -930,6 +939,12 @@ msgstr "{} 無効"
msgid "No account" msgid "No account"
msgstr "アカウントなし" msgstr "アカウントなし"
#: assets/automations/ping_gateway/manager.py:36
#, fuzzy
#| msgid "Assets amount"
msgid "Asset, {}, using account {}"
msgstr "資産額"
#: assets/automations/ping_gateway/manager.py:55 #: assets/automations/ping_gateway/manager.py:55
#, python-brace-format #, python-brace-format
msgid "Unable to connect to port {port} on {address}" msgid "Unable to connect to port {port} on {address}"
@ -988,11 +1003,11 @@ msgid "Cloud service"
msgstr "クラウド サービス" msgstr "クラウド サービス"
#: assets/const/category.py:15 assets/models/asset/web.py:16 audits/const.py:33 #: assets/const/category.py:15 assets/models/asset/web.py:16 audits/const.py:33
#: terminal/models/applet/applet.py:24 #: terminal/models/applet/applet.py:25
msgid "Web" msgid "Web"
msgstr "Web" msgstr "Web"
#: assets/const/device.py:7 terminal/models/applet/applet.py:23 #: assets/const/device.py:7 terminal/models/applet/applet.py:24
#: tickets/const.py:8 #: tickets/const.py:8
msgid "General" msgid "General"
msgstr "一般" msgstr "一般"
@ -1028,7 +1043,7 @@ msgid "Basic"
msgstr "基本" msgstr "基本"
#: assets/const/web.py:61 assets/models/asset/web.py:13 #: assets/const/web.py:61 assets/models/asset/web.py:13
#: assets/serializers/asset/common.py:117 assets/serializers/platform.py:39 #: assets/serializers/asset/common.py:117 assets/serializers/platform.py:40
msgid "Script" msgid "Script"
msgstr "脚本" msgstr "脚本"
@ -1044,8 +1059,8 @@ msgstr "SSHパブリックキー"
#: assets/models/cmd_filter.py:88 assets/models/group.py:23 #: assets/models/cmd_filter.py:88 assets/models/group.py:23
#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:45 #: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:45
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38 #: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:35 terminal/models/applet/applet.py:151 #: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:155
#: terminal/models/applet/host.py:110 terminal/models/component/endpoint.py:24 #: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100 #: terminal/models/component/endpoint.py:100
#: terminal/models/session/session.py:47 tickets/models/comment.py:32 #: terminal/models/session/session.py:47 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:756 #: tickets/models/ticket/general.py:297 users/models/user.py:756
@ -1094,7 +1109,7 @@ msgstr "ユーザーと同じユーザー名"
#: assets/models/_user.py:52 authentication/models/connection_token.py:38 #: assets/models/_user.py:52 authentication/models/connection_token.py:38
#: authentication/serializers/connect_token_secret.py:104 #: authentication/serializers/connect_token_secret.py:104
#: terminal/models/applet/applet.py:33 terminal/serializers/session.py:20 #: terminal/models/applet/applet.py:34 terminal/serializers/session.py:20
#: terminal/serializers/session.py:41 terminal/serializers/storage.py:68 #: terminal/serializers/session.py:41 terminal/serializers/storage.py:68
msgid "Protocol" msgid "Protocol"
msgstr "プロトコル" msgstr "プロトコル"
@ -1183,28 +1198,12 @@ msgid "Can test asset connectivity"
msgstr "資産接続をテストできます" msgstr "資産接続をテストできます"
#: assets/models/asset/common.py:284 #: assets/models/asset/common.py:284
msgid "Can push account to asset"
msgstr "アカウントをアセットにプッシュできます"
#: assets/models/asset/common.py:285
msgid "Can verify account"
msgstr "アカウントを確認できます"
#: assets/models/asset/common.py:286
msgid "Can match asset" msgid "Can match asset"
msgstr "アセットを一致させることができます" msgstr "アセットを一致させることができます"
#: assets/models/asset/common.py:287 #: assets/models/asset/common.py:285
msgid "Add asset to node" msgid "Can change asset nodes"
msgstr "ノードにアセットを追加する" msgstr "資産ノードを変更できます"
#: assets/models/asset/common.py:288
msgid "Move asset to node"
msgstr "アセットをノードに移動する"
#: assets/models/asset/common.py:289
msgid "Remove asset from node"
msgstr "ノードからアセットを削除"
#: assets/models/asset/database.py:10 assets/serializers/asset/common.py:110 #: assets/models/asset/database.py:10 assets/serializers/asset/common.py:110
#: settings/serializers/email.py:37 #: settings/serializers/email.py:37
@ -1227,22 +1226,22 @@ msgstr "クライアントキー"
msgid "Allow invalid cert" msgid "Allow invalid cert"
msgstr "証明書チェックを無視" msgstr "証明書チェックを無視"
#: assets/models/asset/web.py:9 assets/serializers/platform.py:29 #: assets/models/asset/web.py:9 assets/serializers/platform.py:30
msgid "Autofill" msgid "Autofill"
msgstr "自動充填" msgstr "自動充填"
#: assets/models/asset/web.py:10 assets/serializers/asset/common.py:114 #: assets/models/asset/web.py:10 assets/serializers/asset/common.py:114
#: assets/serializers/platform.py:31 #: assets/serializers/platform.py:32
msgid "Username selector" msgid "Username selector"
msgstr "ユーザー名ピッカー" msgstr "ユーザー名ピッカー"
#: assets/models/asset/web.py:11 assets/serializers/asset/common.py:115 #: assets/models/asset/web.py:11 assets/serializers/asset/common.py:115
#: assets/serializers/platform.py:34 #: assets/serializers/platform.py:35
msgid "Password selector" msgid "Password selector"
msgstr "パスワードセレクター" msgstr "パスワードセレクター"
#: assets/models/asset/web.py:12 assets/serializers/asset/common.py:116 #: assets/models/asset/web.py:12 assets/serializers/asset/common.py:116
#: assets/serializers/platform.py:37 #: assets/serializers/platform.py:38
msgid "Submit selector" msgid "Submit selector"
msgstr "ボタンセレクターを確認する" msgstr "ボタンセレクターを確認する"
@ -1261,7 +1260,7 @@ msgstr "アセットの自動化タスク"
#: assets/models/automations/base.py:112 audits/models.py:177 #: assets/models/automations/base.py:112 audits/models.py:177
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:114 #: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:114
#: terminal/models/applet/applet.py:150 terminal/models/applet/host.py:107 #: terminal/models/applet/applet.py:154 terminal/models/applet/host.py:108
#: terminal/models/component/status.py:27 terminal/serializers/applet.py:17 #: terminal/models/component/status.py:27 terminal/serializers/applet.py:17
#: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283 #: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13 #: tickets/serializers/super_ticket.py:13
@ -1403,45 +1402,45 @@ msgstr "有効化"
msgid "Ansible config" msgid "Ansible config"
msgstr "Ansible 構成" msgstr "Ansible 構成"
#: assets/models/platform.py:44 assets/serializers/platform.py:60 #: assets/models/platform.py:44 assets/serializers/platform.py:61
msgid "Ping enabled" msgid "Ping enabled"
msgstr "アセット ディスカバリを有効にする" msgstr "アセット ディスカバリを有効にする"
#: assets/models/platform.py:45 assets/serializers/platform.py:61 #: assets/models/platform.py:45 assets/serializers/platform.py:62
msgid "Ping method" msgid "Ping method"
msgstr "資産検出方法" msgstr "資産検出方法"
#: assets/models/platform.py:46 assets/models/platform.py:59 #: assets/models/platform.py:46 assets/models/platform.py:59
#: assets/serializers/platform.py:62 #: assets/serializers/platform.py:63
msgid "Gather facts enabled" msgid "Gather facts enabled"
msgstr "資産情報の収集を有効にする" msgstr "資産情報の収集を有効にする"
#: assets/models/platform.py:47 assets/models/platform.py:61 #: assets/models/platform.py:47 assets/models/platform.py:61
#: assets/serializers/platform.py:63 #: assets/serializers/platform.py:64
msgid "Gather facts method" msgid "Gather facts method"
msgstr "情報収集の方法" msgstr "情報収集の方法"
#: assets/models/platform.py:48 assets/serializers/platform.py:66 #: assets/models/platform.py:48 assets/serializers/platform.py:67
msgid "Change secret enabled" msgid "Change secret enabled"
msgstr "パスワードの変更が有効" msgstr "パスワードの変更が有効"
#: assets/models/platform.py:50 assets/serializers/platform.py:67 #: assets/models/platform.py:50 assets/serializers/platform.py:68
msgid "Change secret method" msgid "Change secret method"
msgstr "パスワード変更モード" msgstr "パスワード変更モード"
#: assets/models/platform.py:52 assets/serializers/platform.py:68 #: assets/models/platform.py:52 assets/serializers/platform.py:69
msgid "Push account enabled" msgid "Push account enabled"
msgstr "アカウントのプッシュを有効にする" msgstr "アカウントのプッシュを有効にする"
#: assets/models/platform.py:54 assets/serializers/platform.py:69 #: assets/models/platform.py:54 assets/serializers/platform.py:70
msgid "Push account method" msgid "Push account method"
msgstr "アカウントプッシュ方式" msgstr "アカウントプッシュ方式"
#: assets/models/platform.py:56 assets/serializers/platform.py:64 #: assets/models/platform.py:56 assets/serializers/platform.py:65
msgid "Verify account enabled" msgid "Verify account enabled"
msgstr "アカウントの確認をオンにする" msgstr "アカウントの確認をオンにする"
#: assets/models/platform.py:58 assets/serializers/platform.py:65 #: assets/models/platform.py:58 assets/serializers/platform.py:66
msgid "Verify account method" msgid "Verify account method"
msgstr "アカウント認証方法" msgstr "アカウント認証方法"
@ -1453,23 +1452,23 @@ msgstr "メタ"
msgid "Internal" msgid "Internal"
msgstr "ビルトイン" msgstr "ビルトイン"
#: assets/models/platform.py:83 assets/serializers/platform.py:90 #: assets/models/platform.py:83 assets/serializers/platform.py:94
msgid "Charset" msgid "Charset"
msgstr "シャーセット" msgstr "シャーセット"
#: assets/models/platform.py:85 assets/serializers/platform.py:118 #: assets/models/platform.py:85 assets/serializers/platform.py:122
msgid "Domain enabled" msgid "Domain enabled"
msgstr "ドメインを有効にする" msgstr "ドメインを有効にする"
#: assets/models/platform.py:87 assets/serializers/platform.py:117 #: assets/models/platform.py:87 assets/serializers/platform.py:121
msgid "Su enabled" msgid "Su enabled"
msgstr "アカウントの切り替えを有効にする" msgstr "アカウントの切り替えを有効にする"
#: assets/models/platform.py:88 assets/serializers/platform.py:100 #: assets/models/platform.py:88 assets/serializers/platform.py:104
msgid "Su method" msgid "Su method"
msgstr "アカウントの切り替え方法" msgstr "アカウントの切り替え方法"
#: assets/models/platform.py:90 assets/serializers/platform.py:97 #: assets/models/platform.py:90 assets/serializers/platform.py:101
msgid "Automation" msgid "Automation"
msgstr "オートメーション" msgstr "オートメーション"
@ -1482,7 +1481,7 @@ msgstr "%(value)s は偶数ではありません"
msgid "Auto fill" msgid "Auto fill"
msgstr "自動充填" msgstr "自動充填"
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:95 #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:99
#: authentication/serializers/connect_token_secret.py:28 #: authentication/serializers/connect_token_secret.py:28
#: authentication/serializers/connect_token_secret.py:66 #: authentication/serializers/connect_token_secret.py:66
#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:99 #: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:99
@ -1594,31 +1593,31 @@ msgstr "含まれない:/"
msgid "The same level node name cannot be the same" msgid "The same level node name cannot be the same"
msgstr "同じレベルのノード名を同じにすることはできません。" msgstr "同じレベルのノード名を同じにすることはできません。"
#: assets/serializers/platform.py:25 #: assets/serializers/platform.py:26
msgid "SFTP enabled" msgid "SFTP enabled"
msgstr "SFTP が有効" msgstr "SFTP が有効"
#: assets/serializers/platform.py:26 #: assets/serializers/platform.py:27
msgid "SFTP home" msgid "SFTP home"
msgstr "SFTP ルート パス" msgstr "SFTP ルート パス"
#: assets/serializers/platform.py:42 #: assets/serializers/platform.py:43
msgid "Auth with username" msgid "Auth with username"
msgstr "ユーザー名で認証する" msgstr "ユーザー名で認証する"
#: assets/serializers/platform.py:70 #: assets/serializers/platform.py:71
msgid "Gather accounts enabled" msgid "Gather accounts enabled"
msgstr "アカウント収集を有効にする" msgstr "アカウント収集を有効にする"
#: assets/serializers/platform.py:71 #: assets/serializers/platform.py:72
msgid "Gather accounts method" msgid "Gather accounts method"
msgstr "アカウントの収集方法" msgstr "アカウントの収集方法"
#: assets/serializers/platform.py:77 #: assets/serializers/platform.py:78
msgid "Primary" msgid "Primary"
msgstr "主要" msgstr "主要"
#: assets/serializers/platform.py:119 #: assets/serializers/platform.py:123
msgid "Default Domain" msgid "Default Domain"
msgstr "デフォルト ドメイン" msgstr "デフォルト ドメイン"
@ -1762,7 +1761,7 @@ msgid "Change password"
msgstr "パスワードを変更する" msgstr "パスワードを変更する"
#: audits/const.py:34 settings/serializers/terminal.py:6 #: audits/const.py:34 settings/serializers/terminal.py:6
#: terminal/models/applet/host.py:24 terminal/models/component/terminal.py:156 #: terminal/models/applet/host.py:25 terminal/models/component/terminal.py:156
#: terminal/serializers/session.py:48 #: terminal/serializers/session.py:48
msgid "Terminal" msgid "Terminal"
msgstr "ターミナル" msgstr "ターミナル"
@ -1779,7 +1778,7 @@ msgstr "セッションログ"
msgid "Login log" msgid "Login log"
msgstr "ログインログ" msgstr "ログインログ"
#: audits/const.py:42 terminal/models/applet/host.py:111 #: audits/const.py:42 terminal/models/applet/host.py:112
#: terminal/models/component/task.py:24 #: terminal/models/component/task.py:24
msgid "Task" msgid "Task"
msgstr "タスク" msgstr "タスク"
@ -3587,7 +3586,7 @@ msgstr "組織"
msgid "Org name" msgid "Org name"
msgstr "組織名" msgstr "組織名"
#: orgs/models.py:70 rbac/models/role.py:36 terminal/models/applet/applet.py:32 #: orgs/models.py:70 rbac/models/role.py:36 terminal/models/applet/applet.py:33
msgid "Builtin" msgid "Builtin"
msgstr "ビルトイン" msgstr "ビルトイン"
@ -3832,7 +3831,7 @@ msgstr "パーマ"
msgid "Users amount" msgid "Users amount"
msgstr "ユーザー数" msgstr "ユーザー数"
#: rbac/serializers/role.py:28 terminal/models/applet/applet.py:27 #: rbac/serializers/role.py:28 terminal/models/applet/applet.py:28
msgid "Display name" msgid "Display name"
msgstr "表示名" msgstr "表示名"
@ -3896,8 +3895,8 @@ msgstr "タスクセンター"
msgid "My assets" msgid "My assets"
msgstr "私の資産" msgstr "私の資産"
#: rbac/tree.py:57 terminal/models/applet/applet.py:42 #: rbac/tree.py:57 terminal/models/applet/applet.py:43
#: terminal/models/applet/applet.py:147 terminal/models/applet/host.py:27 #: terminal/models/applet/applet.py:151 terminal/models/applet/host.py:28
msgid "Applet" msgid "Applet"
msgstr "リモートアプリケーション" msgstr "リモートアプリケーション"
@ -5421,44 +5420,44 @@ msgstr "一括作成非サポート"
msgid "Storage is invalid" msgid "Storage is invalid"
msgstr "ストレージが無効です" msgstr "ストレージが無効です"
#: terminal/models/applet/applet.py:29 #: terminal/models/applet/applet.py:30
msgid "Author" msgid "Author"
msgstr "著者" msgstr "著者"
#: terminal/models/applet/applet.py:34 #: terminal/models/applet/applet.py:35
msgid "Tags" msgid "Tags"
msgstr "ラベル" msgstr "ラベル"
#: terminal/models/applet/applet.py:38 terminal/serializers/storage.py:157 #: terminal/models/applet/applet.py:39 terminal/serializers/storage.py:157
msgid "Hosts" msgid "Hosts"
msgstr "ホスト" msgstr "ホスト"
#: terminal/models/applet/applet.py:83 #: terminal/models/applet/applet.py:84
msgid "Applet pkg not valid, Missing file {}" msgid "Applet pkg not valid, Missing file {}"
msgstr "無効なアプレット パッケージ、ファイル {} がありません" msgstr "無効なアプレット パッケージ、ファイル {} がありません"
#: terminal/models/applet/applet.py:149 terminal/models/applet/host.py:33 #: terminal/models/applet/applet.py:153 terminal/models/applet/host.py:34
#: terminal/models/applet/host.py:105 #: terminal/models/applet/host.py:106
msgid "Hosting" msgid "Hosting"
msgstr "ホスト マシン" msgstr "ホスト マシン"
#: terminal/models/applet/host.py:18 terminal/serializers/applet_host.py:43 #: terminal/models/applet/host.py:19 terminal/serializers/applet_host.py:43
msgid "Deploy options" msgid "Deploy options"
msgstr "展開パラメーター" msgstr "展開パラメーター"
#: terminal/models/applet/host.py:19 #: terminal/models/applet/host.py:20
msgid "Inited" msgid "Inited"
msgstr "初期化された" msgstr "初期化された"
#: terminal/models/applet/host.py:20 #: terminal/models/applet/host.py:21
msgid "Date inited" msgid "Date inited"
msgstr "" msgstr ""
#: terminal/models/applet/host.py:21 #: terminal/models/applet/host.py:22
msgid "Date synced" msgid "Date synced"
msgstr "同期日" msgstr "同期日"
#: terminal/models/applet/host.py:106 #: terminal/models/applet/host.py:107
msgid "Initial" msgid "Initial"
msgstr "初期化" msgstr "初期化"
@ -7287,14 +7286,6 @@ msgstr "実行回数"
msgid "Instance count" msgid "Instance count"
msgstr "インスタンス数" msgstr "インスタンス数"
#: xpack/plugins/cloud/tasks.py:27
msgid "Run sync instance task"
msgstr "同期インスタンス タスクを実行する"
#: xpack/plugins/cloud/tasks.py:41
msgid "Period clean sync instance task execution"
msgstr "同期インスタンス タスクの実行記録を定期的にクリアする"
#: xpack/plugins/cloud/utils.py:69 #: xpack/plugins/cloud/utils.py:69
msgid "Account unavailable" msgid "Account unavailable"
msgstr "利用できないアカウント" msgstr "利用できないアカウント"
@ -7362,3 +7353,21 @@ msgstr "究極のエディション"
#: xpack/plugins/license/models.py:85 #: xpack/plugins/license/models.py:85
msgid "Community edition" msgid "Community edition"
msgstr "コミュニティ版" msgstr "コミュニティ版"
#~ msgid "Can push account to asset"
#~ msgstr "アカウントをアセットにプッシュできます"
#~ msgid "Add asset to node"
#~ msgstr "ノードにアセットを追加する"
#~ msgid "Move asset to node"
#~ msgstr "アセットをノードに移動する"
#~ msgid "Remove asset from node"
#~ msgstr "ノードからアセットを削除"
#~ msgid "Run sync instance task"
#~ msgstr "同期インスタンス タスクを実行する"
#~ msgid "Period clean sync instance task execution"
#~ msgstr "同期インスタンス タスクの実行記録を定期的にクリアする"

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:3a10e56f57d89f413c4aac8026e4339f630f70f6a66df8b9edee5b39bed88a75 oid sha256:1c1524b6173a2613845d9450d84ef8ca9cf1be6d0f7cdae2a89f6131d6abc1f1
size 111742 size 111449

View File

@ -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: 2023-02-20 19:19+0800\n" "POT-Creation-Date: 2023-02-21 13:46+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"
@ -157,7 +157,8 @@ msgstr "创建并推送"
msgid "Only create" msgid "Only create"
msgstr "仅创建" msgstr "仅创建"
#: accounts/models/account.py:47 accounts/models/gathered_account.py:14 #: accounts/models/account.py:47
#: accounts/models/automations/gather_account.py:16
#: accounts/serializers/account/account.py:95 #: accounts/serializers/account/account.py:95
#: accounts/serializers/account/gathered_account.py:10 #: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:107 #: accounts/serializers/automations/change_secret.py:107
@ -180,7 +181,7 @@ msgid "Su from"
msgstr "切换自" msgstr "切换自"
#: accounts/models/account.py:53 settings/serializers/auth/cas.py:20 #: accounts/models/account.py:53 settings/serializers/auth/cas.py:20
#: terminal/models/applet/applet.py:28 #: terminal/models/applet/applet.py:29
msgid "Version" msgid "Version"
msgstr "版本" msgstr "版本"
@ -213,15 +214,23 @@ msgstr "可以查看资产历史账号"
msgid "Can view asset history account secret" msgid "Can view asset history account secret"
msgstr "可以查看资产历史账号密码" msgstr "可以查看资产历史账号密码"
#: accounts/models/account.py:111 #: accounts/models/account.py:67
msgid "Can verify account"
msgstr "可以验证账号"
#: accounts/models/account.py:68
msgid "Can push account"
msgstr "可以推送账号"
#: accounts/models/account.py:113
msgid "Account template" msgid "Account template"
msgstr "账号模版" msgstr "账号模版"
#: accounts/models/account.py:116 #: accounts/models/account.py:118
msgid "Can view asset account template secret" msgid "Can view asset account template secret"
msgstr "可以查看资产账号模版密码" msgstr "可以查看资产账号模版密码"
#: accounts/models/account.py:117 #: accounts/models/account.py:119
msgid "Can change asset account template secret" msgid "Can change asset account template secret"
msgstr "可以更改资产账号模版密码" msgstr "可以更改资产账号模版密码"
@ -240,7 +249,7 @@ msgstr "账号备份计划"
#: accounts/models/automations/backup_account.py:83 #: accounts/models/automations/backup_account.py:83
#: assets/models/automations/base.py:114 audits/models.py:55 #: assets/models/automations/base.py:114 audits/models.py:55
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:122 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:122
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:108 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:109
#: terminal/models/session/session.py:45 #: terminal/models/session/session.py:45
#: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:19 #: tickets/models/ticket/apply_asset.py:19
@ -326,12 +335,7 @@ msgstr "创建推送账号执行"
msgid "Secret type" msgid "Secret type"
msgstr "密文类型" msgstr "密文类型"
#: accounts/models/automations/change_secret.py:21 #: accounts/models/automations/change_secret.py:19
#: accounts/serializers/automations/change_secret.py:40
msgid "Secret strategy"
msgstr "密文策略"
#: accounts/models/automations/change_secret.py:23
#: accounts/models/automations/change_secret.py:72 accounts/models/base.py:38 #: accounts/models/automations/change_secret.py:72 accounts/models/base.py:38
#: authentication/models/temp_token.py:10 #: authentication/models/temp_token.py:10
#: authentication/templates/authentication/_access_key_modal.html:31 #: authentication/templates/authentication/_access_key_modal.html:31
@ -339,6 +343,11 @@ msgstr "密文策略"
msgid "Secret" msgid "Secret"
msgstr "密钥" msgstr "密钥"
#: accounts/models/automations/change_secret.py:22
#: accounts/serializers/automations/change_secret.py:40
msgid "Secret strategy"
msgstr "密文策略"
#: accounts/models/automations/change_secret.py:24 #: accounts/models/automations/change_secret.py:24
msgid "Password rules" msgid "Password rules"
msgstr "密码规则" msgstr "密码规则"
@ -362,7 +371,7 @@ msgstr "开始日期"
#: accounts/models/automations/change_secret.py:74 #: accounts/models/automations/change_secret.py:74
#: assets/models/automations/base.py:115 ops/models/base.py:56 #: assets/models/automations/base.py:115 ops/models/base.py:56
#: ops/models/celery.py:64 ops/models/job.py:123 #: ops/models/celery.py:64 ops/models/job.py:123
#: terminal/models/applet/host.py:109 #: terminal/models/applet/host.py:110
msgid "Date finished" msgid "Date finished"
msgstr "结束日期" msgstr "结束日期"
@ -375,20 +384,19 @@ msgstr "错误"
msgid "Change secret record" msgid "Change secret record"
msgstr "改密记录" msgstr "改密记录"
#: accounts/models/automations/gather_account.py:14
msgid "Present"
msgstr "存在"
#: accounts/models/automations/gather_account.py:15 #: accounts/models/automations/gather_account.py:15
#: accounts/tasks/gather_accounts.py:29 msgid "Date last login"
msgid "Gather asset accounts" msgstr "最后登录日期"
msgstr "收集账号"
#: accounts/models/automations/push_account.py:13 #: accounts/models/automations/gather_account.py:17
msgid "Triggers" #: accounts/models/automations/push_account.py:13 accounts/models/base.py:34
msgstr "触发方式" #: acls/serializers/base.py:18 acls/serializers/base.py:49
#: assets/models/_user.py:23 audits/models.py:157 authentication/forms.py:25
#: accounts/models/automations/push_account.py:14 accounts/models/base.py:34 #: authentication/forms.py:27 authentication/models/temp_token.py:9
#: accounts/models/gathered_account.py:15 acls/serializers/base.py:18
#: acls/serializers/base.py:49 assets/models/_user.py:23 audits/models.py:157
#: authentication/forms.py:25 authentication/forms.py:27
#: authentication/models/temp_token.py:9
#: 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
#: users/forms/profile.py:32 users/forms/profile.py:112 #: users/forms/profile.py:32 users/forms/profile.py:112
@ -397,7 +405,24 @@ msgstr "触发方式"
msgid "Username" msgid "Username"
msgstr "用户名" msgstr "用户名"
#: accounts/models/automations/push_account.py:15 acls/models/base.py:81 #: accounts/models/automations/gather_account.py:18
msgid "Address last login"
msgstr "最后登录地址"
#: accounts/models/automations/gather_account.py:25 rbac/tree.py:50
msgid "Gather account"
msgstr "收集账号"
#: accounts/models/automations/gather_account.py:41
#: accounts/tasks/gather_accounts.py:29
msgid "Gather asset accounts"
msgstr "收集账号"
#: accounts/models/automations/push_account.py:12
msgid "Triggers"
msgstr "触发方式"
#: accounts/models/automations/push_account.py:14 acls/models/base.py:81
#: acls/serializers/base.py:81 acls/serializers/login_acl.py:25 #: acls/serializers/base.py:81 acls/serializers/login_acl.py:25
#: assets/models/cmd_filter.py:81 audits/models.py:65 audits/serializers.py:82 #: assets/models/cmd_filter.py:81 audits/models.py:65 audits/serializers.py:82
#: authentication/serializers/connect_token_secret.py:109 #: authentication/serializers/connect_token_secret.py:109
@ -405,7 +430,7 @@ msgstr "用户名"
msgid "Action" msgid "Action"
msgstr "动作" msgstr "动作"
#: accounts/models/automations/push_account.py:41 #: accounts/models/automations/push_account.py:40
msgid "Push asset account" msgid "Push asset account"
msgstr "账号推送" msgstr "账号推送"
@ -421,13 +446,13 @@ msgstr "账号验证"
#: assets/models/group.py:20 assets/models/label.py:18 #: assets/models/group.py:20 assets/models/label.py:18
#: assets/models/platform.py:21 assets/models/platform.py:76 #: assets/models/platform.py:21 assets/models/platform.py:76
#: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142 #: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142
#: assets/serializers/platform.py:132 #: assets/serializers/platform.py:91 assets/serializers/platform.py:136
#: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21 #: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:26 ops/models/playbook.py:23 ops/serializers/job.py:19 #: ops/models/job.py:26 ops/models/playbook.py:23 ops/serializers/job.py:19
#: orgs/models.py:69 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: orgs/models.py:69 perms/models/asset_permission.py:56 rbac/models/role.py:29
#: settings/models.py:33 settings/serializers/sms.py:6 #: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:26 terminal/models/component/endpoint.py:12 #: terminal/models/applet/applet.py:27 terminal/models/component/endpoint.py:12
#: terminal/models/component/endpoint.py:90 #: terminal/models/component/endpoint.py:90
#: terminal/models/component/storage.py:26 terminal/models/component/task.py:15 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:15
#: terminal/models/component/terminal.py:79 users/forms/profile.py:33 #: terminal/models/component/terminal.py:79 users/forms/profile.py:33
@ -444,26 +469,10 @@ msgstr "特权账号"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22 #: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:107 #: authentication/serializers/connect_token_secret.py:107
#: terminal/models/applet/applet.py:31 users/serializers/user.py:159 #: terminal/models/applet/applet.py:32 users/serializers/user.py:159
msgid "Is active" msgid "Is active"
msgstr "激活" msgstr "激活"
#: accounts/models/gathered_account.py:12
msgid "Present"
msgstr "存在"
#: accounts/models/gathered_account.py:13
msgid "Date last login"
msgstr "最后登录日期"
#: accounts/models/gathered_account.py:16
msgid "Address last login"
msgstr "最后登录地址"
#: accounts/models/gathered_account.py:23 rbac/tree.py:50
msgid "Gather account"
msgstr "收集账号"
#: accounts/notifications.py:8 #: accounts/notifications.py:8
msgid "Notification of account backup route task results" msgid "Notification of account backup route task results"
msgstr "账号备份任务结果通知" msgstr "账号备份任务结果通知"
@ -520,7 +529,7 @@ msgstr "已托管密码"
#: accounts/serializers/account/account.py:75 applications/models.py:11 #: accounts/serializers/account/account.py:75 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:77 #: assets/models/label.py:21 assets/models/platform.py:77
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
#: assets/serializers/platform.py:93 assets/serializers/platform.py:133 #: assets/serializers/platform.py:97 assets/serializers/platform.py:137
#: perms/serializers/user_permission.py:25 settings/models.py:35 #: perms/serializers/user_permission.py:25 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13 #: tickets/models/ticket/apply_application.py:13
msgid "Category" msgid "Category"
@ -531,10 +540,10 @@ msgstr "类别"
#: acls/serializers/command_acl.py:18 applications/models.py:14 #: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:78 #: assets/models/cmd_filter.py:74 assets/models/platform.py:78
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:92 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96
#: audits/serializers.py:48 #: audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:37 #: authentication/serializers/connect_token_secret.py:116 ops/models/job.py:37
#: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:30 #: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:31
#: terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:28 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:28
#: terminal/serializers/session.py:22 terminal/serializers/storage.py:224 #: terminal/serializers/session.py:22 terminal/serializers/storage.py:224
@ -639,7 +648,7 @@ msgstr "失败"
msgid "Account execute automation" msgid "Account execute automation"
msgstr "账号执行自动化" msgstr "账号执行自动化"
#: accounts/tasks/backup_account.py:24 #: accounts/tasks/backup_account.py:25
msgid "Execute account backup plan" msgid "Execute account backup plan"
msgstr "执行账号备份计划" msgstr "执行账号备份计划"
@ -647,15 +656,15 @@ msgstr "执行账号备份计划"
msgid "Gather assets accounts" msgid "Gather assets accounts"
msgstr "收集资产上的账号" msgstr "收集资产上的账号"
#: accounts/tasks/push_account.py:30 accounts/tasks/push_account.py:37 #: accounts/tasks/push_account.py:15 accounts/tasks/push_account.py:23
msgid "Push accounts to assets" msgid "Push accounts to assets"
msgstr "推送账号到资产" msgstr "推送账号到资产"
#: accounts/tasks/verify_account.py:42 #: accounts/tasks/verify_account.py:49
msgid "Verify asset account availability" msgid "Verify asset account availability"
msgstr "验证资产账号可用性" msgstr "验证资产账号可用性"
#: accounts/tasks/verify_account.py:50 #: accounts/tasks/verify_account.py:55
msgid "Verify accounts connectivity" msgid "Verify accounts connectivity"
msgstr "测试账号可连接性" msgstr "测试账号可连接性"
@ -913,7 +922,7 @@ msgstr "删除失败,节点包含资产"
msgid "App assets" msgid "App assets"
msgstr "资产管理" msgstr "资产管理"
#: assets/automations/base/manager.py:105 #: assets/automations/base/manager.py:107
msgid "{} disabled" msgid "{} disabled"
msgstr "{} 已禁用" msgstr "{} 已禁用"
@ -922,6 +931,12 @@ msgstr "{} 已禁用"
msgid "No account" msgid "No account"
msgstr "没有账号" msgstr "没有账号"
#: assets/automations/ping_gateway/manager.py:36
#, fuzzy
#| msgid "Assets amount"
msgid "Asset, {}, using account {}"
msgstr "资产数量"
#: assets/automations/ping_gateway/manager.py:55 #: assets/automations/ping_gateway/manager.py:55
#, python-brace-format #, python-brace-format
msgid "Unable to connect to port {port} on {address}" msgid "Unable to connect to port {port} on {address}"
@ -980,11 +995,11 @@ msgid "Cloud service"
msgstr "云服务" msgstr "云服务"
#: assets/const/category.py:15 assets/models/asset/web.py:16 audits/const.py:33 #: assets/const/category.py:15 assets/models/asset/web.py:16 audits/const.py:33
#: terminal/models/applet/applet.py:24 #: terminal/models/applet/applet.py:25
msgid "Web" msgid "Web"
msgstr "Web" msgstr "Web"
#: assets/const/device.py:7 terminal/models/applet/applet.py:23 #: assets/const/device.py:7 terminal/models/applet/applet.py:24
#: tickets/const.py:8 #: tickets/const.py:8
msgid "General" msgid "General"
msgstr "一般" msgstr "一般"
@ -1020,7 +1035,7 @@ msgid "Basic"
msgstr "基本" msgstr "基本"
#: assets/const/web.py:61 assets/models/asset/web.py:13 #: assets/const/web.py:61 assets/models/asset/web.py:13
#: assets/serializers/asset/common.py:117 assets/serializers/platform.py:39 #: assets/serializers/asset/common.py:117 assets/serializers/platform.py:40
msgid "Script" msgid "Script"
msgstr "脚本" msgstr "脚本"
@ -1036,8 +1051,8 @@ msgstr "SSH公钥"
#: assets/models/cmd_filter.py:88 assets/models/group.py:23 #: assets/models/cmd_filter.py:88 assets/models/group.py:23
#: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:45 #: common/db/models.py:37 ops/models/adhoc.py:27 ops/models/job.py:45
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38 #: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:35 terminal/models/applet/applet.py:151 #: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:155
#: terminal/models/applet/host.py:110 terminal/models/component/endpoint.py:24 #: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100 #: terminal/models/component/endpoint.py:100
#: terminal/models/session/session.py:47 tickets/models/comment.py:32 #: terminal/models/session/session.py:47 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:756 #: tickets/models/ticket/general.py:297 users/models/user.py:756
@ -1086,7 +1101,7 @@ msgstr "用户名与用户相同"
#: assets/models/_user.py:52 authentication/models/connection_token.py:38 #: assets/models/_user.py:52 authentication/models/connection_token.py:38
#: authentication/serializers/connect_token_secret.py:104 #: authentication/serializers/connect_token_secret.py:104
#: terminal/models/applet/applet.py:33 terminal/serializers/session.py:20 #: terminal/models/applet/applet.py:34 terminal/serializers/session.py:20
#: terminal/serializers/session.py:41 terminal/serializers/storage.py:68 #: terminal/serializers/session.py:41 terminal/serializers/storage.py:68
msgid "Protocol" msgid "Protocol"
msgstr "协议" msgstr "协议"
@ -1175,28 +1190,12 @@ msgid "Can test asset connectivity"
msgstr "可以测试资产连接性" msgstr "可以测试资产连接性"
#: assets/models/asset/common.py:284 #: assets/models/asset/common.py:284
msgid "Can push account to asset"
msgstr "可以推送账号到资产"
#: assets/models/asset/common.py:285
msgid "Can verify account"
msgstr "可以验证账号"
#: assets/models/asset/common.py:286
msgid "Can match asset" msgid "Can match asset"
msgstr "可以匹配资产" msgstr "可以匹配资产"
#: assets/models/asset/common.py:287 #: assets/models/asset/common.py:285
msgid "Add asset to node" msgid "Can change asset nodes"
msgstr "添加资产到节点" msgstr "可以修改资产节点"
#: assets/models/asset/common.py:288
msgid "Move asset to node"
msgstr "移动资产到节点"
#: assets/models/asset/common.py:289
msgid "Remove asset from node"
msgstr "从节点移除资产"
#: assets/models/asset/database.py:10 assets/serializers/asset/common.py:110 #: assets/models/asset/database.py:10 assets/serializers/asset/common.py:110
#: settings/serializers/email.py:37 #: settings/serializers/email.py:37
@ -1219,22 +1218,22 @@ msgstr "客户端密钥"
msgid "Allow invalid cert" msgid "Allow invalid cert"
msgstr "忽略证书校验" msgstr "忽略证书校验"
#: assets/models/asset/web.py:9 assets/serializers/platform.py:29 #: assets/models/asset/web.py:9 assets/serializers/platform.py:30
msgid "Autofill" msgid "Autofill"
msgstr "自动代填" msgstr "自动代填"
#: assets/models/asset/web.py:10 assets/serializers/asset/common.py:114 #: assets/models/asset/web.py:10 assets/serializers/asset/common.py:114
#: assets/serializers/platform.py:31 #: assets/serializers/platform.py:32
msgid "Username selector" msgid "Username selector"
msgstr "用户名选择器" msgstr "用户名选择器"
#: assets/models/asset/web.py:11 assets/serializers/asset/common.py:115 #: assets/models/asset/web.py:11 assets/serializers/asset/common.py:115
#: assets/serializers/platform.py:34 #: assets/serializers/platform.py:35
msgid "Password selector" msgid "Password selector"
msgstr "密码选择器" msgstr "密码选择器"
#: assets/models/asset/web.py:12 assets/serializers/asset/common.py:116 #: assets/models/asset/web.py:12 assets/serializers/asset/common.py:116
#: assets/serializers/platform.py:37 #: assets/serializers/platform.py:38
msgid "Submit selector" msgid "Submit selector"
msgstr "确认按钮选择器" msgstr "确认按钮选择器"
@ -1253,7 +1252,7 @@ msgstr "资产自动化任务"
#: assets/models/automations/base.py:112 audits/models.py:177 #: assets/models/automations/base.py:112 audits/models.py:177
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:114 #: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:114
#: terminal/models/applet/applet.py:150 terminal/models/applet/host.py:107 #: terminal/models/applet/applet.py:154 terminal/models/applet/host.py:108
#: terminal/models/component/status.py:27 terminal/serializers/applet.py:17 #: terminal/models/component/status.py:27 terminal/serializers/applet.py:17
#: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283 #: terminal/serializers/applet_host.py:93 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13 #: tickets/serializers/super_ticket.py:13
@ -1395,45 +1394,45 @@ msgstr "启用"
msgid "Ansible config" msgid "Ansible config"
msgstr "Ansible 配置" msgstr "Ansible 配置"
#: assets/models/platform.py:44 assets/serializers/platform.py:60 #: assets/models/platform.py:44 assets/serializers/platform.py:61
msgid "Ping enabled" msgid "Ping enabled"
msgstr "启用资产探活" msgstr "启用资产探活"
#: assets/models/platform.py:45 assets/serializers/platform.py:61 #: assets/models/platform.py:45 assets/serializers/platform.py:62
msgid "Ping method" msgid "Ping method"
msgstr "资产探活方式" msgstr "资产探活方式"
#: assets/models/platform.py:46 assets/models/platform.py:59 #: assets/models/platform.py:46 assets/models/platform.py:59
#: assets/serializers/platform.py:62 #: assets/serializers/platform.py:63
msgid "Gather facts enabled" msgid "Gather facts enabled"
msgstr "启用收集资产信息" msgstr "启用收集资产信息"
#: assets/models/platform.py:47 assets/models/platform.py:61 #: assets/models/platform.py:47 assets/models/platform.py:61
#: assets/serializers/platform.py:63 #: assets/serializers/platform.py:64
msgid "Gather facts method" msgid "Gather facts method"
msgstr "收集信息方式" msgstr "收集信息方式"
#: assets/models/platform.py:48 assets/serializers/platform.py:66 #: assets/models/platform.py:48 assets/serializers/platform.py:67
msgid "Change secret enabled" msgid "Change secret enabled"
msgstr "启用改密" msgstr "启用改密"
#: assets/models/platform.py:50 assets/serializers/platform.py:67 #: assets/models/platform.py:50 assets/serializers/platform.py:68
msgid "Change secret method" msgid "Change secret method"
msgstr "改密方式" msgstr "改密方式"
#: assets/models/platform.py:52 assets/serializers/platform.py:68 #: assets/models/platform.py:52 assets/serializers/platform.py:69
msgid "Push account enabled" msgid "Push account enabled"
msgstr "启用账号推送" msgstr "启用账号推送"
#: assets/models/platform.py:54 assets/serializers/platform.py:69 #: assets/models/platform.py:54 assets/serializers/platform.py:70
msgid "Push account method" msgid "Push account method"
msgstr "账号推送方式" msgstr "账号推送方式"
#: assets/models/platform.py:56 assets/serializers/platform.py:64 #: assets/models/platform.py:56 assets/serializers/platform.py:65
msgid "Verify account enabled" msgid "Verify account enabled"
msgstr "开启账号验证" msgstr "开启账号验证"
#: assets/models/platform.py:58 assets/serializers/platform.py:65 #: assets/models/platform.py:58 assets/serializers/platform.py:66
msgid "Verify account method" msgid "Verify account method"
msgstr "账号验证方式" msgstr "账号验证方式"
@ -1445,23 +1444,23 @@ msgstr "元数据"
msgid "Internal" msgid "Internal"
msgstr "内置" msgstr "内置"
#: assets/models/platform.py:83 assets/serializers/platform.py:90 #: assets/models/platform.py:83 assets/serializers/platform.py:94
msgid "Charset" msgid "Charset"
msgstr "编码" msgstr "编码"
#: assets/models/platform.py:85 assets/serializers/platform.py:118 #: assets/models/platform.py:85 assets/serializers/platform.py:122
msgid "Domain enabled" msgid "Domain enabled"
msgstr "启用网域" msgstr "启用网域"
#: assets/models/platform.py:87 assets/serializers/platform.py:117 #: assets/models/platform.py:87 assets/serializers/platform.py:121
msgid "Su enabled" msgid "Su enabled"
msgstr "启用账号切换" msgstr "启用账号切换"
#: assets/models/platform.py:88 assets/serializers/platform.py:100 #: assets/models/platform.py:88 assets/serializers/platform.py:104
msgid "Su method" msgid "Su method"
msgstr "账号切换方式" msgstr "账号切换方式"
#: assets/models/platform.py:90 assets/serializers/platform.py:97 #: assets/models/platform.py:90 assets/serializers/platform.py:101
msgid "Automation" msgid "Automation"
msgstr "自动化" msgstr "自动化"
@ -1474,7 +1473,7 @@ msgstr "%(value)s is not an even number"
msgid "Auto fill" msgid "Auto fill"
msgstr "自动代填" msgstr "自动代填"
#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:95 #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:99
#: authentication/serializers/connect_token_secret.py:28 #: authentication/serializers/connect_token_secret.py:28
#: authentication/serializers/connect_token_secret.py:66 #: authentication/serializers/connect_token_secret.py:66
#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:99 #: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:99
@ -1586,31 +1585,31 @@ msgstr "不能包含: /"
msgid "The same level node name cannot be the same" msgid "The same level node name cannot be the same"
msgstr "同级别节点名字不能重复" msgstr "同级别节点名字不能重复"
#: assets/serializers/platform.py:25 #: assets/serializers/platform.py:26
msgid "SFTP enabled" msgid "SFTP enabled"
msgstr "SFTP 已启用" msgstr "SFTP 已启用"
#: assets/serializers/platform.py:26 #: assets/serializers/platform.py:27
msgid "SFTP home" msgid "SFTP home"
msgstr "SFTP 根路径" msgstr "SFTP 根路径"
#: assets/serializers/platform.py:42 #: assets/serializers/platform.py:43
msgid "Auth with username" msgid "Auth with username"
msgstr "使用用户名认证" msgstr "使用用户名认证"
#: assets/serializers/platform.py:70 #: assets/serializers/platform.py:71
msgid "Gather accounts enabled" msgid "Gather accounts enabled"
msgstr "启用账号收集" msgstr "启用账号收集"
#: assets/serializers/platform.py:71 #: assets/serializers/platform.py:72
msgid "Gather accounts method" msgid "Gather accounts method"
msgstr "收集账号方式" msgstr "收集账号方式"
#: assets/serializers/platform.py:77 #: assets/serializers/platform.py:78
msgid "Primary" msgid "Primary"
msgstr "主要的" msgstr "主要的"
#: assets/serializers/platform.py:119 #: assets/serializers/platform.py:123
msgid "Default Domain" msgid "Default Domain"
msgstr "默认网域" msgstr "默认网域"
@ -1752,7 +1751,7 @@ msgid "Change password"
msgstr "改密" msgstr "改密"
#: audits/const.py:34 settings/serializers/terminal.py:6 #: audits/const.py:34 settings/serializers/terminal.py:6
#: terminal/models/applet/host.py:24 terminal/models/component/terminal.py:156 #: terminal/models/applet/host.py:25 terminal/models/component/terminal.py:156
#: terminal/serializers/session.py:48 #: terminal/serializers/session.py:48
msgid "Terminal" msgid "Terminal"
msgstr "终端" msgstr "终端"
@ -1769,7 +1768,7 @@ msgstr "会话日志"
msgid "Login log" msgid "Login log"
msgstr "登录日志" msgstr "登录日志"
#: audits/const.py:42 terminal/models/applet/host.py:111 #: audits/const.py:42 terminal/models/applet/host.py:112
#: terminal/models/component/task.py:24 #: terminal/models/component/task.py:24
msgid "Task" msgid "Task"
msgstr "任务" msgstr "任务"
@ -3551,7 +3550,7 @@ msgstr "组织"
msgid "Org name" msgid "Org name"
msgstr "组织名称" msgstr "组织名称"
#: orgs/models.py:70 rbac/models/role.py:36 terminal/models/applet/applet.py:32 #: orgs/models.py:70 rbac/models/role.py:36 terminal/models/applet/applet.py:33
msgid "Builtin" msgid "Builtin"
msgstr "内置的" msgstr "内置的"
@ -3795,7 +3794,7 @@ msgstr "权限"
msgid "Users amount" msgid "Users amount"
msgstr "用户数量" msgstr "用户数量"
#: rbac/serializers/role.py:28 terminal/models/applet/applet.py:27 #: rbac/serializers/role.py:28 terminal/models/applet/applet.py:28
msgid "Display name" msgid "Display name"
msgstr "显示名称" msgstr "显示名称"
@ -3859,8 +3858,8 @@ msgstr "任务中心"
msgid "My assets" msgid "My assets"
msgstr "我的资产" msgstr "我的资产"
#: rbac/tree.py:57 terminal/models/applet/applet.py:42 #: rbac/tree.py:57 terminal/models/applet/applet.py:43
#: terminal/models/applet/applet.py:147 terminal/models/applet/host.py:27 #: terminal/models/applet/applet.py:151 terminal/models/applet/host.py:28
msgid "Applet" msgid "Applet"
msgstr "远程应用" msgstr "远程应用"
@ -5349,44 +5348,44 @@ msgstr "不支持批量创建"
msgid "Storage is invalid" msgid "Storage is invalid"
msgstr "存储无效" msgstr "存储无效"
#: terminal/models/applet/applet.py:29 #: terminal/models/applet/applet.py:30
msgid "Author" msgid "Author"
msgstr "作者" msgstr "作者"
#: terminal/models/applet/applet.py:34 #: terminal/models/applet/applet.py:35
msgid "Tags" msgid "Tags"
msgstr "标签" msgstr "标签"
#: terminal/models/applet/applet.py:38 terminal/serializers/storage.py:157 #: terminal/models/applet/applet.py:39 terminal/serializers/storage.py:157
msgid "Hosts" msgid "Hosts"
msgstr "主机" msgstr "主机"
#: terminal/models/applet/applet.py:83 #: terminal/models/applet/applet.py:84
msgid "Applet pkg not valid, Missing file {}" msgid "Applet pkg not valid, Missing file {}"
msgstr "Applet pkg 无效,缺少文件 {}" msgstr "Applet pkg 无效,缺少文件 {}"
#: terminal/models/applet/applet.py:149 terminal/models/applet/host.py:33 #: terminal/models/applet/applet.py:153 terminal/models/applet/host.py:34
#: terminal/models/applet/host.py:105 #: terminal/models/applet/host.py:106
msgid "Hosting" msgid "Hosting"
msgstr "宿主机" msgstr "宿主机"
#: terminal/models/applet/host.py:18 terminal/serializers/applet_host.py:43 #: terminal/models/applet/host.py:19 terminal/serializers/applet_host.py:43
msgid "Deploy options" msgid "Deploy options"
msgstr "部署参数" msgstr "部署参数"
#: terminal/models/applet/host.py:19 #: terminal/models/applet/host.py:20
msgid "Inited" msgid "Inited"
msgstr "已初始化" msgstr "已初始化"
#: terminal/models/applet/host.py:20 #: terminal/models/applet/host.py:21
msgid "Date inited" msgid "Date inited"
msgstr "初始化日期" msgstr "初始化日期"
#: terminal/models/applet/host.py:21 #: terminal/models/applet/host.py:22
msgid "Date synced" msgid "Date synced"
msgstr "同步日期" msgstr "同步日期"
#: terminal/models/applet/host.py:106 #: terminal/models/applet/host.py:107
msgid "Initial" msgid "Initial"
msgstr "初始化" msgstr "初始化"
@ -7192,14 +7191,6 @@ msgstr "执行次数"
msgid "Instance count" msgid "Instance count"
msgstr "实例个数" msgstr "实例个数"
#: xpack/plugins/cloud/tasks.py:27
msgid "Run sync instance task"
msgstr "执行同步实例任务"
#: xpack/plugins/cloud/tasks.py:41
msgid "Period clean sync instance task execution"
msgstr "定期清除同步实例任务执行记录"
#: xpack/plugins/cloud/utils.py:69 #: xpack/plugins/cloud/utils.py:69
msgid "Account unavailable" msgid "Account unavailable"
msgstr "账号无效" msgstr "账号无效"
@ -7268,6 +7259,24 @@ msgstr "旗舰版"
msgid "Community edition" msgid "Community edition"
msgstr "社区版" msgstr "社区版"
#~ msgid "Can push account to asset"
#~ msgstr "可以推送账号到资产"
#~ msgid "Add asset to node"
#~ msgstr "添加资产到节点"
#~ msgid "Move asset to node"
#~ msgstr "移动资产到节点"
#~ msgid "Remove asset from node"
#~ msgstr "从节点移除资产"
#~ msgid "Run sync instance task"
#~ msgstr "执行同步实例任务"
#~ msgid "Period clean sync instance task execution"
#~ msgstr "定期清除同步实例任务执行记录"
#~ msgid "Clean audits log" #~ msgid "Clean audits log"
#~ msgstr "清理审计日志" #~ msgstr "清理审计日志"

View File

@ -101,7 +101,7 @@ class JMSInventory:
def asset_to_host(self, asset, account, automation, protocols, platform): def asset_to_host(self, asset, account, automation, protocols, platform):
host = { host = {
'name': '{}'.format(asset.name), 'name': '{}'.format(asset.name.replace(' ', '_')),
'jms_asset': { 'jms_asset': {
'id': str(asset.id), 'name': asset.name, 'address': asset.address, 'id': str(asset.id), 'name': asset.name, 'address': asset.address,
'type': asset.type, 'category': asset.category, 'type': asset.type, 'category': asset.category,

View File

@ -46,9 +46,25 @@ def sync_registered_tasks(*args, **kwargs):
@receiver(django_ready) @receiver(django_ready)
def check_registered_tasks(*args, **kwargs): def check_registered_tasks(*args, **kwargs):
attrs = ['verbose_name', 'activity_callback'] attrs = ['verbose_name', 'activity_callback']
ignores = [
'users.tasks.check_user_expired_periodic', 'ops.tasks.clean_celery_periodic_tasks',
'terminal.tasks.delete_terminal_status_period', 'ops.tasks.check_server_performance_period',
'settings.tasks.ldap.import_ldap_user', 'users.tasks.check_password_expired',
'assets.tasks.nodes_amount.check_node_assets_amount_task', 'notifications.notifications.publish_task',
'perms.tasks.check_asset_permission_will_expired',
'ops.tasks.create_or_update_registered_periodic_tasks', 'perms.tasks.check_asset_permission_expired',
'settings.tasks.ldap.import_ldap_user_periodic', 'users.tasks.check_password_expired_periodic',
'common.utils.verify_code.send_async', 'assets.tasks.nodes_amount.check_node_assets_amount_period_task',
'users.tasks.check_user_expired', 'orgs.tasks.refresh_org_cache_task',
'terminal.tasks.upload_session_replay_to_external_storage', 'terminal.tasks.clean_orphan_session',
'audits.tasks.clean_audits_log_period', 'authentication.tasks.clean_django_sessions'
]
for name, task in app.tasks.items(): for name, task in app.tasks.items():
if name.startswith('celery.'): if name.startswith('celery.'):
continue continue
if name in ignores:
continue
for attr in attrs: for attr in attrs:
if not hasattr(task, attr): if not hasattr(task, attr):
# print('>>> Task {} has no attribute {}'.format(name, attr)) # print('>>> Task {} has no attribute {}'.format(name, attr))

View File

@ -49,6 +49,10 @@ exclude_permissions = (
('assets', 'gatherfactsautomation', '*', '*'), ('assets', 'gatherfactsautomation', '*', '*'),
('assets', 'commandfilter', '*', '*'), ('assets', 'commandfilter', '*', '*'),
('assets', 'commandfilterrule', '*', '*'), ('assets', 'commandfilterrule', '*', '*'),
('assets', 'asset', 'add,move', 'assettonode'),
('assets', 'asset', 'remove', 'assetfromnode'),
('assets', 'asset', 'test', 'account'),
('assets', 'asset', 'push', 'assetaccount'),
('accounts', 'historicalaccount', '*', '*'), ('accounts', 'historicalaccount', '*', '*'),
('accounts', 'accountbaseautomation', '*', '*'), ('accounts', 'accountbaseautomation', '*', '*'),

View File

@ -18,7 +18,8 @@ def migrate_remove_redundant_permission(apps, *args):
model.objects.filter(app_label='assets', model__in=[ model.objects.filter(app_label='assets', model__in=[
'authbook', 'historicalauthbook', 'test_gateway', 'authbook', 'historicalauthbook', 'test_gateway',
'accountbackupplan', 'accountbackupplanexecution', 'gathereduser', 'systemuser' 'accountbackupplan', 'accountbackupplanexecution',
'gathereduser', 'systemuser'
]).delete() ]).delete()
model.objects.filter(app_label='perms', model__in=[ model.objects.filter(app_label='perms', model__in=[
@ -27,7 +28,8 @@ def migrate_remove_redundant_permission(apps, *args):
perm_model = apps.get_model('auth', 'Permission') perm_model = apps.get_model('auth', 'Permission')
perm_model.objects.filter(codename__in=[ perm_model.objects.filter(codename__in=[
'view_permusergroupasset', 'view_permuserasset', 'push_assetsystemuser', 'change_accountsecret' 'view_permusergroupasset', 'view_permuserasset', 'push_assetsystemuser',
'add_assettonode', 'move_assettonode', 'remove_assetfromnode',
]).delete() ]).delete()