mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-07-04 02:26:34 +00:00
perf: 解决冲突
This commit is contained in:
commit
cde59f7ae8
@ -45,6 +45,7 @@ class AccountViewSet(OrgBulkModelViewSet):
|
|||||||
accounts = asset.accounts.all()
|
accounts = asset.accounts.all()
|
||||||
else:
|
else:
|
||||||
accounts = []
|
accounts = []
|
||||||
|
accounts = self.filter_queryset(accounts)
|
||||||
serializer = serializers.AccountSerializer(accounts, many=True)
|
serializer = serializers.AccountSerializer(accounts, many=True)
|
||||||
return Response(data=serializer.data)
|
return Response(data=serializer.data)
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ from rest_framework.response import Response
|
|||||||
|
|
||||||
from accounts import serializers
|
from accounts import serializers
|
||||||
from accounts.tasks import verify_accounts_connectivity_task, push_accounts_to_assets_task
|
from accounts.tasks import verify_accounts_connectivity_task, push_accounts_to_assets_task
|
||||||
|
from assets.exceptions import NotSupportedTemporarilyError
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'AccountsTaskCreateAPI',
|
'AccountsTaskCreateAPI',
|
||||||
@ -28,6 +29,11 @@ class AccountsTaskCreateAPI(CreateAPIView):
|
|||||||
if data['action'] == 'push':
|
if data['action'] == 'push':
|
||||||
task = push_accounts_to_assets_task.delay(account_ids)
|
task = push_accounts_to_assets_task.delay(account_ids)
|
||||||
else:
|
else:
|
||||||
|
account = accounts[0]
|
||||||
|
asset = account.asset
|
||||||
|
if not asset.auto_info['ansible_enabled'] or \
|
||||||
|
not asset.auto_info['ping_enabled']:
|
||||||
|
raise NotSupportedTemporarilyError()
|
||||||
task = verify_accounts_connectivity_task.delay(account_ids)
|
task = verify_accounts_connectivity_task.delay(account_ids)
|
||||||
|
|
||||||
data = getattr(serializer, '_data', {})
|
data = getattr(serializer, '_data', {})
|
||||||
|
@ -86,6 +86,10 @@ class ChangeSecretManager(AccountBasePlaybookManager):
|
|||||||
accounts = accounts.filter(username__in=self.snapshot_account_usernames)
|
accounts = accounts.filter(username__in=self.snapshot_account_usernames)
|
||||||
|
|
||||||
accounts = accounts.filter(secret_type=self.secret_type)
|
accounts = accounts.filter(secret_type=self.secret_type)
|
||||||
|
if not accounts:
|
||||||
|
print('没有发现待改密账号: %s 用户名: %s 类型: %s' % (asset.name, account.username, self.secret_type))
|
||||||
|
return []
|
||||||
|
|
||||||
method_attr = getattr(automation, self.method_type() + '_method')
|
method_attr = getattr(automation, self.method_type() + '_method')
|
||||||
method_hosts = self.method_hosts_mapper[method_attr]
|
method_hosts = self.method_hosts_mapper[method_attr]
|
||||||
method_hosts = [h for h in method_hosts if h != host['name']]
|
method_hosts = [h for h in method_hosts if h != host['name']]
|
||||||
@ -137,8 +141,10 @@ class ChangeSecretManager(AccountBasePlaybookManager):
|
|||||||
recorder.status = 'success'
|
recorder.status = 'success'
|
||||||
recorder.date_finished = timezone.now()
|
recorder.date_finished = timezone.now()
|
||||||
recorder.save()
|
recorder.save()
|
||||||
print('recorder.new_secret', recorder.new_secret)
|
|
||||||
account = recorder.account
|
account = recorder.account
|
||||||
|
if not account:
|
||||||
|
print("Account not found, deleted ?", recorder)
|
||||||
|
return
|
||||||
account.secret = recorder.new_secret
|
account.secret = recorder.new_secret
|
||||||
account.save(update_fields=['secret'])
|
account.save(update_fields=['secret'])
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class PushAccountManager(ChangeSecretManager, AccountBasePlaybookManager):
|
|||||||
|
|
||||||
def get_accounts(self, privilege_account, accounts: QuerySet):
|
def get_accounts(self, privilege_account, accounts: QuerySet):
|
||||||
if not privilege_account:
|
if not privilege_account:
|
||||||
logger.debug(f'not privilege account')
|
print(f'not privilege account')
|
||||||
return []
|
return []
|
||||||
snapshot_account_usernames = self.execution.snapshot['accounts']
|
snapshot_account_usernames = self.execution.snapshot['accounts']
|
||||||
if '*' in snapshot_account_usernames:
|
if '*' in snapshot_account_usernames:
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Verify account
|
- name: Verify account
|
||||||
mongodb_ping:
|
mongodb_ping:
|
||||||
login_user: "{{ jms_account.username }}"
|
login_user: "{{ account.username }}"
|
||||||
login_password: "{{ jms_account.secret }}"
|
login_password: "{{ account.secret }}"
|
||||||
login_host: "{{ jms_asset.address }}"
|
login_host: "{{ jms_asset.address }}"
|
||||||
login_port: "{{ jms_asset.port }}"
|
login_port: "{{ jms_asset.port }}"
|
||||||
login_database: "{{ jms_asset.spec_info.db_name }}"
|
login_database: "{{ jms_asset.spec_info.db_name }}"
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Verify account
|
- name: Verify account
|
||||||
oracle_ping:
|
oracle_ping:
|
||||||
login_user: "{{ jms_account.username }}"
|
login_user: "{{ account.username }}"
|
||||||
login_password: "{{ jms_account.secret }}"
|
login_password: "{{ account.secret }}"
|
||||||
login_host: "{{ jms_asset.address }}"
|
login_host: "{{ jms_asset.address }}"
|
||||||
login_port: "{{ jms_asset.port }}"
|
login_port: "{{ jms_asset.port }}"
|
||||||
login_database: "{{ jms_asset.spec_info.db_name }}"
|
login_database: "{{ jms_asset.spec_info.db_name }}"
|
||||||
mode: "{{ jms_account.mode }}"
|
mode: "{{ account.mode }}"
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Verify account
|
- name: Verify account
|
||||||
community.general.mssql_script:
|
community.general.mssql_script:
|
||||||
login_user: "{{ jms_account.username }}"
|
login_user: "{{ account.username }}"
|
||||||
login_password: "{{ jms_account.secret }}"
|
login_password: "{{ account.secret }}"
|
||||||
login_host: "{{ jms_asset.address }}"
|
login_host: "{{ jms_asset.address }}"
|
||||||
login_port: "{{ jms_asset.port }}"
|
login_port: "{{ jms_asset.port }}"
|
||||||
name: '{{ jms_asset.spec_info.db_name }}'
|
name: '{{ jms_asset.spec_info.db_name }}'
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
# 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'},
|
|
||||||
),
|
|
||||||
]
|
|
@ -68,6 +68,9 @@ class Account(AbsConnectivity, BaseAccount):
|
|||||||
('push_account', _('Can push account')),
|
('push_account', _('Can push account')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{}'.format(self.username)
|
||||||
|
|
||||||
@lazyproperty
|
@lazyproperty
|
||||||
def platform(self):
|
def platform(self):
|
||||||
return self.asset.platform
|
return self.asset.platform
|
||||||
@ -78,9 +81,6 @@ class Account(AbsConnectivity, BaseAccount):
|
|||||||
return self.username
|
return self.username
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '{}'.format(self.username)
|
|
||||||
|
|
||||||
@lazyproperty
|
@lazyproperty
|
||||||
def has_secret(self):
|
def has_secret(self):
|
||||||
return bool(self.secret)
|
return bool(self.secret)
|
||||||
@ -99,14 +99,6 @@ class Account(AbsConnectivity, BaseAccount):
|
|||||||
""" 排除自己和以自己为 su-from 的账号 """
|
""" 排除自己和以自己为 su-from 的账号 """
|
||||||
return self.asset.accounts.exclude(id=self.id).exclude(su_from=self)
|
return self.asset.accounts.exclude(id=self.id).exclude(su_from=self)
|
||||||
|
|
||||||
def secret_changed(self):
|
|
||||||
history = self.history.first()
|
|
||||||
if not history:
|
|
||||||
return True
|
|
||||||
if history.secret != self.secret or history.secret_type != self.secret_type:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class AccountTemplate(BaseAccount):
|
class AccountTemplate(BaseAccount):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -109,7 +109,7 @@ class BaseAccount(JMSOrgBaseModel):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def private_key_path(self):
|
def private_key_path(self):
|
||||||
if not self.secret_type != SecretType.SSH_KEY \
|
if self.secret_type != SecretType.SSH_KEY \
|
||||||
or not self.secret \
|
or not self.secret \
|
||||||
or not self.private_key:
|
or not self.private_key:
|
||||||
return None
|
return None
|
||||||
|
@ -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_task.delay([instance.id], [instance.asset_id])
|
push_accounts_to_assets_task.delay([instance.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)
|
||||||
@ -102,7 +102,7 @@ class AccountSerializer(AccountSerializerCreateMixin, BaseAccountSerializer):
|
|||||||
class Meta(BaseAccountSerializer.Meta):
|
class Meta(BaseAccountSerializer.Meta):
|
||||||
model = Account
|
model = Account
|
||||||
fields = BaseAccountSerializer.Meta.fields \
|
fields = BaseAccountSerializer.Meta.fields \
|
||||||
+ ['su_from', 'version', 'asset'] \
|
+ ['su_from', 'asset'] \
|
||||||
+ ['template', 'push_now', 'source']
|
+ ['template', 'push_now', 'source']
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
**BaseAccountSerializer.Meta.extra_kwargs,
|
**BaseAccountSerializer.Meta.extra_kwargs,
|
||||||
|
@ -38,6 +38,8 @@ class BaseAutomationSerializer(PeriodTaskSerializerMixin, BulkOrgResourceModelSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
def validate_name(self, name):
|
def validate_name(self, name):
|
||||||
|
if self.instance:
|
||||||
|
return name
|
||||||
if BaseAutomation.objects.filter(name=name, type=self.model_type).exists():
|
if BaseAutomation.objects.filter(name=name, type=self.model_type).exists():
|
||||||
raise serializers.ValidationError(_('Name already exists'))
|
raise serializers.ValidationError(_('Name already exists'))
|
||||||
return name
|
return name
|
||||||
|
@ -1,17 +1,3 @@
|
|||||||
from django.db.models.signals import pre_save
|
|
||||||
from django.dispatch import receiver
|
|
||||||
|
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from .models import Account
|
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@receiver(pre_save, sender=Account)
|
|
||||||
def on_account_pre_create(sender, instance, update_fields=(), **kwargs):
|
|
||||||
# 这是创建时
|
|
||||||
if instance.version == 0 or instance.secret_changed():
|
|
||||||
instance.version += 1
|
|
||||||
|
|
||||||
# 即使在 root 组织也不怕
|
|
||||||
instance.org_id = instance.asset.org_id
|
|
||||||
|
@ -8,12 +8,10 @@ from rest_framework.response import Response
|
|||||||
|
|
||||||
from accounts.tasks import push_accounts_to_assets_task, verify_accounts_connectivity_task
|
from accounts.tasks import push_accounts_to_assets_task, verify_accounts_connectivity_task
|
||||||
from assets import serializers
|
from assets import serializers
|
||||||
|
from assets.exceptions import NotSupportedTemporarilyError
|
||||||
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
|
||||||
from assets.tasks import (
|
from assets.tasks import test_assets_connectivity_manual, update_assets_hardware_info_manual
|
||||||
test_assets_connectivity_manual,
|
|
||||||
update_assets_hardware_info_manual
|
|
||||||
)
|
|
||||||
from common.api import SuggestionMixin
|
from common.api import SuggestionMixin
|
||||||
from common.drf.filters import BaseFilterSet
|
from common.drf.filters import BaseFilterSet
|
||||||
from common.utils import get_logger, is_uuid
|
from common.utils import get_logger, is_uuid
|
||||||
@ -154,6 +152,10 @@ class AssetsTaskMixin:
|
|||||||
if data["action"] == "refresh":
|
if data["action"] == "refresh":
|
||||||
task = update_assets_hardware_info_manual(assets)
|
task = update_assets_hardware_info_manual(assets)
|
||||||
else:
|
else:
|
||||||
|
asset = assets[0]
|
||||||
|
if not asset.auto_info['ansible_enabled'] or \
|
||||||
|
not asset.auto_info['ping_enabled']:
|
||||||
|
raise NotSupportedTemporarilyError()
|
||||||
task = test_assets_connectivity_manual(assets)
|
task = test_assets_connectivity_manual(assets)
|
||||||
return task
|
return task
|
||||||
|
|
||||||
@ -205,9 +207,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_task.delay(account_ids, asset_ids)
|
task = push_accounts_to_assets_task.delay(account_ids)
|
||||||
elif action == "test_account":
|
elif action == "test_account":
|
||||||
task = verify_accounts_connectivity_task.delay(account_ids, asset_ids)
|
task = verify_accounts_connectivity_task.delay(account_ids)
|
||||||
else:
|
else:
|
||||||
task = None
|
task = None
|
||||||
return task
|
return task
|
||||||
|
@ -67,7 +67,7 @@ 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:
|
if settings.DEBUG_DEV:
|
||||||
logger.debug('Ansible runtime dir: {}'.format(path))
|
print(f'Ansible runtime dir: {path}')
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -156,10 +156,9 @@ class BasePlaybookManager:
|
|||||||
return sub_playbook_path
|
return sub_playbook_path
|
||||||
|
|
||||||
def get_runners(self):
|
def get_runners(self):
|
||||||
# TODO 临时打印一下 找一下打印不出日志的原因
|
|
||||||
print('ansible runner: 任务开始执行')
|
|
||||||
assets_group_by_platform = self.get_assets_group_by_platform()
|
assets_group_by_platform = self.get_assets_group_by_platform()
|
||||||
print('ansible runner: 获取资产分组', assets_group_by_platform)
|
if settings.DEBUG_DEV:
|
||||||
|
print("assets_group_by_platform: {}".format(assets_group_by_platform))
|
||||||
runners = []
|
runners = []
|
||||||
for platform, assets in assets_group_by_platform.items():
|
for platform, assets in assets_group_by_platform.items():
|
||||||
assets_bulked = [assets[i:i + self.bulk_size] for i in range(0, len(assets), self.bulk_size)]
|
assets_bulked = [assets[i:i + self.bulk_size] for i in range(0, len(assets), self.bulk_size)]
|
||||||
@ -213,6 +212,7 @@ class BasePlaybookManager:
|
|||||||
def file_to_json(path):
|
def file_to_json(path):
|
||||||
with open(path, 'r') as f:
|
with open(path, 'r') as f:
|
||||||
d = json.load(f)
|
d = json.load(f)
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
|
||||||
from common.exceptions import JMSException
|
from common.exceptions import JMSException
|
||||||
|
|
||||||
|
|
||||||
class NodeIsBeingUpdatedByOthers(JMSException):
|
class NodeIsBeingUpdatedByOthers(JMSException):
|
||||||
status_code = status.HTTP_409_CONFLICT
|
status_code = status.HTTP_409_CONFLICT
|
||||||
|
|
||||||
|
|
||||||
|
class NotSupportedTemporarilyError(JMSException):
|
||||||
|
default_detail = _("This function is not supported temporarily")
|
||||||
|
@ -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'), ('change_assettonode', 'Can change asset nodes')], 'verbose_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'},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
# 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'), ('match_asset', 'Can match asset'), ('change_assetnodes', 'Can change asset nodes')], 'verbose_name': 'Asset'},
|
|
||||||
),
|
|
||||||
]
|
|
@ -277,6 +277,8 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
|
|||||||
|
|
||||||
@atomic
|
@atomic
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
|
if not validated_data.get('accounts'):
|
||||||
|
validated_data.pop('accounts', None)
|
||||||
nodes_display = validated_data.pop('nodes_display', '')
|
nodes_display = validated_data.pop('nodes_display', '')
|
||||||
instance = super().update(instance, validated_data)
|
instance = super().update(instance, validated_data)
|
||||||
self.perform_nodes_display_create(instance, nodes_display)
|
self.perform_nodes_display_create(instance, nodes_display)
|
||||||
|
@ -530,7 +530,7 @@ class Config(dict):
|
|||||||
'PERIOD_TASK_ENABLED': True,
|
'PERIOD_TASK_ENABLED': True,
|
||||||
|
|
||||||
# 导航栏 帮助
|
# 导航栏 帮助
|
||||||
'HELP_DOCUMENT_URL': 'http://docs.jumpserver.org',
|
'HELP_DOCUMENT_URL': 'https://docs.jumpserver.org/zh/v3/',
|
||||||
'HELP_SUPPORT_URL': 'http://www.jumpserver.org/support/',
|
'HELP_SUPPORT_URL': 'http://www.jumpserver.org/support/',
|
||||||
|
|
||||||
'FORGOT_PASSWORD_URL': '',
|
'FORGOT_PASSWORD_URL': '',
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:331188bb5169bb463da018a635589e12a2136d476db264ac7e5d6e5d63ca474a
|
oid sha256:af57d16430705feb02ebbb99fc3a2f5fc3bab69209f558aa4d69b1e8055a6f5f
|
||||||
size 135916
|
size 136036
|
||||||
|
@ -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-21 18:29+0800\n"
|
"POT-Creation-Date: 2023-02-21 22:44+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"
|
||||||
@ -908,7 +908,7 @@ msgstr "アプリケーション"
|
|||||||
msgid "Can match application"
|
msgid "Can match application"
|
||||||
msgstr "アプリケーションを一致させることができます"
|
msgstr "アプリケーションを一致させることができます"
|
||||||
|
|
||||||
#: assets/api/asset/asset.py:144
|
#: assets/api/asset/asset.py:142
|
||||||
msgid "Cannot create asset directly, you should create a host or other"
|
msgid "Cannot create asset directly, you should create a host or other"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"資産を直接作成することはできません。ホストまたはその他を作成する必要がありま"
|
"資産を直接作成することはできません。ホストまたはその他を作成する必要がありま"
|
||||||
@ -1051,6 +1051,10 @@ msgstr "基本"
|
|||||||
msgid "Script"
|
msgid "Script"
|
||||||
msgstr "脚本"
|
msgstr "脚本"
|
||||||
|
|
||||||
|
#: assets/exceptions.py:12
|
||||||
|
msgid "This function is not supported temporarily"
|
||||||
|
msgstr "この機能は一時的にサポートされていません"
|
||||||
|
|
||||||
#: assets/models/_user.py:25
|
#: assets/models/_user.py:25
|
||||||
msgid "SSH private key"
|
msgid "SSH private key"
|
||||||
msgstr "SSH秘密鍵"
|
msgstr "SSH秘密鍵"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:2cdc2b875c98f41bd698833a989195d8cc4245f39f52b7eab41ad4d95075cb17
|
oid sha256:3b6ee4a378810f2515be5020e3fa0b1297e1c207260ca60bb14dc5407ca19c43
|
||||||
size 111666
|
size 111750
|
||||||
|
@ -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-21 18:29+0800\n"
|
"POT-Creation-Date: 2023-02-21 22:44+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"
|
||||||
@ -902,7 +902,7 @@ msgstr "应用程序"
|
|||||||
msgid "Can match application"
|
msgid "Can match application"
|
||||||
msgstr "匹配应用"
|
msgstr "匹配应用"
|
||||||
|
|
||||||
#: assets/api/asset/asset.py:144
|
#: assets/api/asset/asset.py:142
|
||||||
msgid "Cannot create asset directly, you should create a host or other"
|
msgid "Cannot create asset directly, you should create a host or other"
|
||||||
msgstr "不能直接创建资产, 你应该创建主机或其他资产"
|
msgstr "不能直接创建资产, 你应该创建主机或其他资产"
|
||||||
|
|
||||||
@ -1043,6 +1043,10 @@ msgstr "基本"
|
|||||||
msgid "Script"
|
msgid "Script"
|
||||||
msgstr "脚本"
|
msgstr "脚本"
|
||||||
|
|
||||||
|
#: assets/exceptions.py:12
|
||||||
|
msgid "This function is not supported temporarily"
|
||||||
|
msgstr "暂时不支持此功能"
|
||||||
|
|
||||||
#: assets/models/_user.py:25
|
#: assets/models/_user.py:25
|
||||||
msgid "SSH private key"
|
msgid "SSH private key"
|
||||||
msgstr "SSH密钥"
|
msgstr "SSH密钥"
|
||||||
|
@ -6,6 +6,7 @@ from django.conf import settings
|
|||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
|
||||||
|
from common.exceptions import JMSException
|
||||||
from orgs.mixins.api import OrgBulkModelViewSet
|
from orgs.mixins.api import OrgBulkModelViewSet
|
||||||
from ..exception import PlaybookNoValidEntry
|
from ..exception import PlaybookNoValidEntry
|
||||||
from ..models import Playbook
|
from ..models import Playbook
|
||||||
@ -39,7 +40,11 @@ class PlaybookViewSet(OrgBulkModelViewSet):
|
|||||||
if 'multipart/form-data' in self.request.headers['Content-Type']:
|
if 'multipart/form-data' in self.request.headers['Content-Type']:
|
||||||
src_path = os.path.join(settings.MEDIA_ROOT, instance.path.name)
|
src_path = os.path.join(settings.MEDIA_ROOT, instance.path.name)
|
||||||
dest_path = os.path.join(settings.DATA_DIR, "ops", "playbook", instance.id.__str__())
|
dest_path = os.path.join(settings.DATA_DIR, "ops", "playbook", instance.id.__str__())
|
||||||
unzip_playbook(src_path, dest_path)
|
try:
|
||||||
|
unzip_playbook(src_path, dest_path)
|
||||||
|
except RuntimeError as e:
|
||||||
|
raise JMSException(code='invalid_playbook_file', detail={"msg": "Unzip failed"})
|
||||||
|
|
||||||
if 'main.yml' not in os.listdir(dest_path):
|
if 'main.yml' not in os.listdir(dest_path):
|
||||||
raise PlaybookNoValidEntry
|
raise PlaybookNoValidEntry
|
||||||
|
|
||||||
|
@ -111,7 +111,8 @@ class Applet(JMSBaseModel):
|
|||||||
return instance
|
return instance
|
||||||
|
|
||||||
def select_host_account(self):
|
def select_host_account(self):
|
||||||
hosts = list(self.hosts.all())
|
# 选择激活的发布机
|
||||||
|
hosts = list(self.hosts.filter(is_active=True).all())
|
||||||
if not hosts:
|
if not hosts:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user