diff --git a/apps/accounts/automations/change_secret/host/aix/main.yml b/apps/accounts/automations/change_secret/host/aix/main.yml new file mode 100644 index 000000000..cca9d681b --- /dev/null +++ b/apps/accounts/automations/change_secret/host/aix/main.yml @@ -0,0 +1,54 @@ +- hosts: demo + gather_facts: no + tasks: + - name: Test privileged account + ansible.builtin.ping: + + - name: Change password + ansible.builtin.user: + name: "{{ account.username }}" + password: "{{ account.secret | password_hash('des') }}" + update_password: always + when: secret_type == "password" + + - name: create user If it already exists, no operation will be performed + ansible.builtin.user: + name: "{{ account.username }}" + when: secret_type == "ssh_key" + + - name: remove jumpserver ssh key + ansible.builtin.lineinfile: + dest: "{{ kwargs.dest }}" + regexp: "{{ kwargs.regexp }}" + state: absent + when: + - secret_type == "ssh_key" + - kwargs.strategy == "set_jms" + + - name: Change SSH key + ansible.builtin.authorized_key: + user: "{{ account.username }}" + key: "{{ account.secret }}" + exclusive: "{{ kwargs.exclusive }}" + when: secret_type == "ssh_key" + + - name: Refresh connection + ansible.builtin.meta: reset_connection + + - name: Verify password + ansible.builtin.ping: + become: no + vars: + ansible_user: "{{ account.username }}" + ansible_password: "{{ account.secret }}" + ansible_become: no + when: secret_type == "password" + + - name: Verify SSH key + ansible.builtin.ping: + become: no + vars: + ansible_user: "{{ account.username }}" + ansible_ssh_private_key_file: "{{ account.private_key_path }}" + ansible_become: no + when: secret_type == "ssh_key" diff --git a/apps/accounts/automations/change_secret/host/aix/manifest.yml b/apps/accounts/automations/change_secret/host/aix/manifest.yml new file mode 100644 index 000000000..5c44f0350 --- /dev/null +++ b/apps/accounts/automations/change_secret/host/aix/manifest.yml @@ -0,0 +1,6 @@ +id: change_secret_aix +name: Change secret for aix +category: host +type: + - AIX +method: change_secret diff --git a/apps/accounts/automations/change_secret/manager.py b/apps/accounts/automations/change_secret/manager.py index 4a8e548a3..c076ab56b 100644 --- a/apps/accounts/automations/change_secret/manager.py +++ b/apps/accounts/automations/change_secret/manager.py @@ -11,6 +11,7 @@ from accounts.const import AutomationTypes, SecretType, SSHKeyStrategy, SecretSt from accounts.models import ChangeSecretRecord from accounts.notifications import ChangeSecretExecutionTaskMsg from accounts.serializers import ChangeSecretRecordBackUpSerializer +from assets.const import HostTypes from common.utils import get_logger, lazyproperty from common.utils.file import encrypt_and_compress_zip_file from common.utils.timezone import local_now_display @@ -91,6 +92,11 @@ class ChangeSecretManager(AccountBasePlaybookManager): inventory_hosts = [] records = [] host['secret_type'] = self.secret_type + + if asset.type == HostTypes.WINDOWS and self.secret_type == SecretType.SSH_KEY: + print(f'Windows {asset} does not support ssh key push \n') + return inventory_hosts + for account in accounts: h = deepcopy(host) h['name'] += '(' + account.username + ')' diff --git a/apps/accounts/automations/push_account/manager.py b/apps/accounts/automations/push_account/manager.py index 12d89e7ed..f2f21c51a 100644 --- a/apps/accounts/automations/push_account/manager.py +++ b/apps/accounts/automations/push_account/manager.py @@ -4,6 +4,7 @@ from django.db.models import QuerySet from accounts.const import AutomationTypes, SecretType from accounts.models import Account +from assets.const import HostTypes from common.utils import get_logger from ..base.manager import AccountBasePlaybookManager from ..change_secret.manager import ChangeSecretManager @@ -61,6 +62,10 @@ class PushAccountManager(ChangeSecretManager, AccountBasePlaybookManager): inventory_hosts = [] host['secret_type'] = self.secret_type + if asset.type == HostTypes.WINDOWS and self.secret_type == SecretType.SSH_KEY: + print(f'Windows {asset} does not support ssh key push \n') + return inventory_hosts + for account in accounts: h = deepcopy(host) h['name'] += '(' + account.username + ')' diff --git a/apps/accounts/serializers/account/base.py b/apps/accounts/serializers/account/base.py index 6c1eb95ed..489bd794f 100644 --- a/apps/accounts/serializers/account/base.py +++ b/apps/accounts/serializers/account/base.py @@ -38,7 +38,7 @@ class AuthValidateMixin(serializers.Serializer): return secret def clean_auth_fields(self, validated_data): - secret_type = validated_data['secret_type'] + secret_type = validated_data.get('secret_type') passphrase = validated_data.get('passphrase') secret = validated_data.pop('secret', None) self.handle_secret(secret, secret_type, passphrase) diff --git a/apps/assets/automations/base/manager.py b/apps/assets/automations/base/manager.py index 0f9949dce..bb5963981 100644 --- a/apps/assets/automations/base/manager.py +++ b/apps/assets/automations/base/manager.py @@ -1,3 +1,4 @@ +import json import os import shutil from collections import defaultdict @@ -152,8 +153,12 @@ class BasePlaybookManager: return sub_playbook_path def get_runners(self): + # TODO 临时打印一下 找一下打印不出日志的原因 + print('ansible runner: 任务开始执行') + assets_group_by_platform = self.get_assets_group_by_platform() + print('ansible runner: 获取资产分组', assets_group_by_platform) runners = [] - for platform, assets in self.get_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)] for i, _assets in enumerate(assets_bulked, start=1): @@ -198,6 +203,30 @@ class BasePlaybookManager: def before_runner_start(self, runner): pass + @staticmethod + def delete_sensitive_data(path): + if settings.DEBUG_DEV: + return + + with open(path, 'r') as f: + d = json.load(f) + def delete_keys(d, keys_to_delete): + """ + 递归函数:删除嵌套字典中的指定键 + """ + if not isinstance(d, dict): + return d + keys = list(d.keys()) + for key in keys: + if key in keys_to_delete: + del d[key] + else: + delete_keys(d[key], keys_to_delete) + return d + d = delete_keys(d, ['secret', 'ansible_password']) + with open(path, 'w') as f: + json.dump(d, f) + def run(self, *args, **kwargs): runners = self.get_runners() if len(runners) > 1: @@ -215,6 +244,7 @@ class BasePlaybookManager: self.before_runner_start(runner) try: cb = runner.run(**kwargs) + self.delete_sensitive_data(runner.inventory) self.on_runner_success(runner, cb) except Exception as e: self.on_runner_failed(runner, e) diff --git a/apps/assets/automations/gather_facts/manager.py b/apps/assets/automations/gather_facts/manager.py index 877ce811c..5ec25cb17 100644 --- a/apps/assets/automations/gather_facts/manager.py +++ b/apps/assets/automations/gather_facts/manager.py @@ -24,7 +24,7 @@ class GatherFactsManager(BasePlaybookManager): asset = self.host_asset_mapper.get(host) if asset and info: for k, v in info.items(): - info[k] = v.strip() + info[k] = v.strip() if isinstance(v, str) else v asset.info = info asset.save() else: diff --git a/apps/assets/const/host.py b/apps/assets/const/host.py index 11d9e3407..a2e99865e 100644 --- a/apps/assets/const/host.py +++ b/apps/assets/const/host.py @@ -81,7 +81,13 @@ class HostTypes(BaseType): {'name': 'Unix'}, {'name': 'macOS'}, {'name': 'BSD'}, - {'name': 'AIX'}, + { + 'name': 'AIX', + 'automation': { + 'push_account_method': 'push_account_aix', + 'change_secret_method': 'change_secret_aix', + } + }, ], cls.WINDOWS: [ {'name': 'Windows'}, diff --git a/apps/assets/serializers/asset/host.py b/apps/assets/serializers/asset/host.py index dd8d3bc2f..10b06dc20 100644 --- a/apps/assets/serializers/asset/host.py +++ b/apps/assets/serializers/asset/host.py @@ -12,8 +12,7 @@ class HostInfoSerializer(serializers.Serializer): vendor = serializers.CharField(max_length=64, required=False, allow_blank=True, label=_('Vendor')) model = serializers.CharField(max_length=54, required=False, allow_blank=True, label=_('Model')) sn = serializers.CharField(max_length=128, required=False, allow_blank=True, label=_('Serial number')) - - cpu_model = serializers.CharField(max_length=64, required=False, allow_blank=True, label=_('CPU model')) + cpu_model = serializers.ListField(child=serializers.CharField(max_length=64, allow_blank=True), required=False, label=_('CPU model')) cpu_count = serializers.IntegerField(required=False, label=_('CPU count')) cpu_cores = serializers.IntegerField(required=False, label=_('CPU cores')) cpu_vcpus = serializers.IntegerField(required=False, label=_('CPU vcpus')) diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py index 893d980a3..277c8388d 100644 --- a/apps/assets/serializers/platform.py +++ b/apps/assets/serializers/platform.py @@ -1,5 +1,6 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import serializers +from django.core import validators from assets.const.web import FillType from common.serializers import WritableNestedModelSerializer @@ -86,6 +87,9 @@ class PlatformProtocolsSerializer(serializers.ModelSerializer): class PlatformSerializer(WritableNestedModelSerializer): + name = serializers.CharField( + label=_("Name"), max_length=50, validators=[validators.validate_unicode_slug] + ) charset = LabeledChoiceField( choices=Platform.CharsetChoices.choices, label=_("Charset") ) diff --git a/apps/audits/api.py b/apps/audits/api.py index 601de6d5b..e1aff002a 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -30,6 +30,7 @@ class JobAuditViewSet(OrgReadonlyModelViewSet): ('date_start', ('date_from', 'date_to')) ] search_fields = ['creator__name', 'material'] + filterset_fields = ['creator__name', 'material'] serializer_class = JobLogSerializer ordering = ['-date_start'] diff --git a/apps/common/sdk/sms/huawei.py b/apps/common/sdk/sms/huawei.py index c5d6bb116..d2243058d 100644 --- a/apps/common/sdk/sms/huawei.py +++ b/apps/common/sdk/sms/huawei.py @@ -86,8 +86,11 @@ class HuaweiSMS(BaseSMSClient): except Exception as error: raise JMSException(code='response_bad', detail=error) - if resp_msg.get('code') != '000000': - raise JMSException(code='response_bad', detail=resp_msg) + resp_code = resp_msg.get('code', '') + resp_desc = resp_msg.get('description', '') + if resp_code != '000000': + raise JMSException(code='response_bad', + detail="{}:{},{}:{}".format("code", resp_code, "description", resp_desc)) return resp_msg diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 48382f434..038515a76 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-02-21 13:14+0800\n" +"POT-Creation-Date: 2023-02-21 13:46+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -182,7 +182,7 @@ msgid "Su from" msgstr "から切り替え" #: 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" msgstr "バージョン" @@ -215,7 +215,7 @@ msgstr "資産履歴アカウントを表示できます" msgid "Can view asset history account secret" msgstr "資産履歴アカウントパスワードを表示できます" -#: accounts/models/account.py:67 assets/models/asset/common.py:285 +#: accounts/models/account.py:67 msgid "Can verify account" msgstr "アカウントを確認できます" @@ -250,7 +250,7 @@ msgstr "アカウントバックアップ計画" #: accounts/models/automations/backup_account.py:83 #: assets/models/automations/base.py:114 audits/models.py:55 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py: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 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 @@ -372,7 +372,7 @@ msgstr "開始日" #: accounts/models/automations/change_secret.py:74 #: assets/models/automations/base.py:115 ops/models/base.py:56 #: ops/models/celery.py:64 ops/models/job.py:123 -#: terminal/models/applet/host.py:109 +#: terminal/models/applet/host.py:110 msgid "Date finished" msgstr "終了日" @@ -447,13 +447,13 @@ msgstr "アカウントの確認" #: assets/models/group.py:20 assets/models/label.py:18 #: assets/models/platform.py:21 assets/models/platform.py:76 #: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142 -#: assets/serializers/platform.py:132 +#: assets/serializers/platform.py:91 assets/serializers/platform.py:136 #: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21 #: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py: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 #: 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/storage.py:26 terminal/models/component/task.py:15 #: terminal/models/component/terminal.py:79 users/forms/profile.py:33 @@ -470,7 +470,7 @@ msgstr "特権アカウント" #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/label.py:22 #: 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" msgstr "アクティブです。" @@ -533,7 +533,7 @@ msgstr "エスクローされたパスワード" #: accounts/serializers/account/account.py:75 applications/models.py:11 #: assets/models/label.py:21 assets/models/platform.py:77 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 -#: assets/serializers/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 #: tickets/models/ticket/apply_application.py:13 msgid "Category" @@ -544,10 +544,10 @@ msgstr "カテゴリ" #: acls/serializers/command_acl.py:18 applications/models.py:14 #: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/cmd_filter.py:74 assets/models/platform.py:78 -#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:92 +#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96 #: audits/serializers.py:48 #: 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:146 terminal/serializers/applet.py:28 #: terminal/serializers/session.py:22 terminal/serializers/storage.py:224 @@ -824,7 +824,7 @@ msgstr "" "192.168.10.1、192.168.1.0/24、10.1.1.1-10.1.1.20、2001:db8:2de::e13、2001:" "db8:1a:1110:::/64 (ドメイン名サポート)" -#: acls/serializers/base.py:40 assets/serializers/asset/host.py:37 +#: acls/serializers/base.py:40 assets/serializers/asset/host.py:36 msgid "IP/Host" msgstr "IP/ホスト" @@ -930,7 +930,7 @@ msgstr "削除に失敗し、ノードにアセットが含まれています。 msgid "App assets" msgstr "アプリ資産" -#: assets/automations/base/manager.py:106 +#: assets/automations/base/manager.py:107 msgid "{} disabled" msgstr "{} 無効" @@ -1003,11 +1003,11 @@ msgid "Cloud service" msgstr "クラウド サービス" #: 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" 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 msgid "General" msgstr "一般" @@ -1043,7 +1043,7 @@ msgid "Basic" msgstr "基本" #: 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" msgstr "脚本" @@ -1059,8 +1059,8 @@ msgstr "SSHパブリックキー" #: 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 #: 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/host.py:110 terminal/models/component/endpoint.py:24 +#: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:155 +#: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:100 #: terminal/models/session/session.py:47 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:756 @@ -1109,7 +1109,7 @@ msgstr "ユーザーと同じユーザー名" #: assets/models/_user.py:52 authentication/models/connection_token.py:38 #: 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 msgid "Protocol" msgstr "プロトコル" @@ -1198,14 +1198,10 @@ msgid "Can test asset connectivity" msgstr "資産接続をテストできます" #: assets/models/asset/common.py:284 -msgid "Can push account to asset" -msgstr "アカウントをアセットにプッシュできます" - -#: assets/models/asset/common.py:286 msgid "Can match asset" msgstr "アセットを一致させることができます" -#: assets/models/asset/common.py:287 +#: assets/models/asset/common.py:285 msgid "Can change asset nodes" msgstr "資産ノードを変更できます" @@ -1230,22 +1226,22 @@ msgstr "クライアントキー" msgid "Allow invalid cert" 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" msgstr "自動充填" #: 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" msgstr "ユーザー名ピッカー" #: 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" msgstr "パスワードセレクター" #: 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" msgstr "ボタンセレクターを確認する" @@ -1264,7 +1260,7 @@ msgstr "アセットの自動化タスク" #: assets/models/automations/base.py:112 audits/models.py:177 #: 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/serializers/applet_host.py:93 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 @@ -1406,45 +1402,45 @@ msgstr "有効化" msgid "Ansible config" 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" msgstr "アセット ディスカバリを有効にする" -#: assets/models/platform.py:45 assets/serializers/platform.py:61 +#: assets/models/platform.py:45 assets/serializers/platform.py:62 msgid "Ping method" msgstr "資産検出方法" #: assets/models/platform.py:46 assets/models/platform.py:59 -#: assets/serializers/platform.py:62 +#: assets/serializers/platform.py:63 msgid "Gather facts enabled" msgstr "資産情報の収集を有効にする" #: assets/models/platform.py:47 assets/models/platform.py:61 -#: assets/serializers/platform.py:63 +#: assets/serializers/platform.py:64 msgid "Gather facts method" 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" 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" 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" 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" 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" 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" msgstr "アカウント認証方法" @@ -1456,23 +1452,23 @@ msgstr "メタ" msgid "Internal" msgstr "ビルトイン" -#: assets/models/platform.py:83 assets/serializers/platform.py:90 +#: assets/models/platform.py:83 assets/serializers/platform.py:94 msgid "Charset" msgstr "シャーセット" -#: assets/models/platform.py:85 assets/serializers/platform.py:118 +#: assets/models/platform.py:85 assets/serializers/platform.py:122 msgid "Domain enabled" msgstr "ドメインを有効にする" -#: assets/models/platform.py:87 assets/serializers/platform.py:117 +#: assets/models/platform.py:87 assets/serializers/platform.py:121 msgid "Su enabled" msgstr "アカウントの切り替えを有効にする" -#: assets/models/platform.py:88 assets/serializers/platform.py:100 +#: assets/models/platform.py:88 assets/serializers/platform.py:104 msgid "Su method" msgstr "アカウントの切り替え方法" -#: assets/models/platform.py:90 assets/serializers/platform.py:97 +#: assets/models/platform.py:90 assets/serializers/platform.py:101 msgid "Automation" msgstr "オートメーション" @@ -1485,7 +1481,7 @@ msgstr "%(value)s は偶数ではありません" msgid "Auto fill" 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:66 #: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:99 @@ -1532,40 +1528,40 @@ msgstr "モデル" msgid "Serial number" msgstr "シリアル番号" -#: assets/serializers/asset/host.py:16 +#: assets/serializers/asset/host.py:15 msgid "CPU model" msgstr "CPU モデル" -#: assets/serializers/asset/host.py:17 +#: assets/serializers/asset/host.py:16 msgid "CPU count" msgstr "CPU カウント" -#: assets/serializers/asset/host.py:18 +#: assets/serializers/asset/host.py:17 msgid "CPU cores" msgstr "CPU カラー" -#: assets/serializers/asset/host.py:19 +#: assets/serializers/asset/host.py:18 msgid "CPU vcpus" msgstr "CPU 合計" -#: assets/serializers/asset/host.py:20 +#: assets/serializers/asset/host.py:19 msgid "Memory" msgstr "メモリ" -#: assets/serializers/asset/host.py:21 +#: assets/serializers/asset/host.py:20 msgid "Disk total" msgstr "ディスクの合計" -#: assets/serializers/asset/host.py:23 +#: assets/serializers/asset/host.py:22 #: authentication/serializers/connect_token_secret.py:105 msgid "OS" msgstr "OS" -#: assets/serializers/asset/host.py:24 +#: assets/serializers/asset/host.py:23 msgid "OS version" msgstr "システムバージョン" -#: assets/serializers/asset/host.py:25 +#: assets/serializers/asset/host.py:24 msgid "OS arch" msgstr "システムアーキテクチャ" @@ -1597,31 +1593,31 @@ msgstr "含まれない:/" msgid "The same level node name cannot be the same" msgstr "同じレベルのノード名を同じにすることはできません。" -#: assets/serializers/platform.py:25 +#: assets/serializers/platform.py:26 msgid "SFTP enabled" msgstr "SFTP が有効" -#: assets/serializers/platform.py:26 +#: assets/serializers/platform.py:27 msgid "SFTP home" msgstr "SFTP ルート パス" -#: assets/serializers/platform.py:42 +#: assets/serializers/platform.py:43 msgid "Auth with username" msgstr "ユーザー名で認証する" -#: assets/serializers/platform.py:70 +#: assets/serializers/platform.py:71 msgid "Gather accounts enabled" msgstr "アカウント収集を有効にする" -#: assets/serializers/platform.py:71 +#: assets/serializers/platform.py:72 msgid "Gather accounts method" msgstr "アカウントの収集方法" -#: assets/serializers/platform.py:77 +#: assets/serializers/platform.py:78 msgid "Primary" msgstr "主要" -#: assets/serializers/platform.py:119 +#: assets/serializers/platform.py:123 msgid "Default Domain" msgstr "デフォルト ドメイン" @@ -1765,7 +1761,7 @@ msgid "Change password" msgstr "パスワードを変更する" #: 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 msgid "Terminal" msgstr "ターミナル" @@ -1782,7 +1778,7 @@ msgstr "セッションログ" msgid "Login log" 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 msgid "Task" msgstr "タスク" @@ -3590,7 +3586,7 @@ msgstr "組織" msgid "Org name" 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" msgstr "ビルトイン" @@ -3835,7 +3831,7 @@ msgstr "パーマ" msgid "Users amount" 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" msgstr "表示名" @@ -3899,8 +3895,8 @@ msgstr "タスクセンター" msgid "My assets" msgstr "私の資産" -#: rbac/tree.py:57 terminal/models/applet/applet.py:42 -#: terminal/models/applet/applet.py:147 terminal/models/applet/host.py:27 +#: rbac/tree.py:57 terminal/models/applet/applet.py:43 +#: terminal/models/applet/applet.py:151 terminal/models/applet/host.py:28 msgid "Applet" msgstr "リモートアプリケーション" @@ -5334,7 +5330,7 @@ msgstr "テスト成功" msgid "Test failure: Account invalid" msgstr "テスト失敗: アカウントが無効" -#: terminal/api/component/terminal.py:35 +#: terminal/api/component/terminal.py:55 msgid "Have online sessions" msgstr "オンラインセッションを持つ" @@ -5424,44 +5420,44 @@ msgstr "一括作成非サポート" msgid "Storage is invalid" msgstr "ストレージが無効です" -#: terminal/models/applet/applet.py:29 +#: terminal/models/applet/applet.py:30 msgid "Author" msgstr "著者" -#: terminal/models/applet/applet.py:34 +#: terminal/models/applet/applet.py:35 msgid "Tags" 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" msgstr "ホスト" -#: terminal/models/applet/applet.py:83 +#: terminal/models/applet/applet.py:84 msgid "Applet pkg not valid, Missing file {}" msgstr "無効なアプレット パッケージ、ファイル {} がありません" -#: terminal/models/applet/applet.py:149 terminal/models/applet/host.py:33 -#: terminal/models/applet/host.py:105 +#: terminal/models/applet/applet.py:153 terminal/models/applet/host.py:34 +#: terminal/models/applet/host.py:106 msgid "Hosting" 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" msgstr "展開パラメーター" -#: terminal/models/applet/host.py:19 +#: terminal/models/applet/host.py:20 msgid "Inited" msgstr "初期化された" -#: terminal/models/applet/host.py:20 +#: terminal/models/applet/host.py:21 msgid "Date inited" msgstr "" -#: terminal/models/applet/host.py:21 +#: terminal/models/applet/host.py:22 msgid "Date synced" msgstr "同期日" -#: terminal/models/applet/host.py:106 +#: terminal/models/applet/host.py:107 msgid "Initial" msgstr "初期化" @@ -7358,6 +7354,9 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" +#~ msgid "Can push account to asset" +#~ msgstr "アカウントをアセットにプッシュできます" + #~ msgid "Add asset to node" #~ msgstr "ノードにアセットを追加する" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 98d9bfb7f..d884a2053 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-02-21 13:14+0800\n" +"POT-Creation-Date: 2023-02-21 13:46+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -181,7 +181,7 @@ msgid "Su from" msgstr "切换自" #: 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" msgstr "版本" @@ -214,7 +214,7 @@ msgstr "可以查看资产历史账号" msgid "Can view asset history account secret" msgstr "可以查看资产历史账号密码" -#: accounts/models/account.py:67 assets/models/asset/common.py:285 +#: accounts/models/account.py:67 msgid "Can verify account" msgstr "可以验证账号" @@ -249,7 +249,7 @@ msgstr "账号备份计划" #: accounts/models/automations/backup_account.py:83 #: assets/models/automations/base.py:114 audits/models.py:55 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py: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 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 @@ -371,7 +371,7 @@ msgstr "开始日期" #: accounts/models/automations/change_secret.py:74 #: assets/models/automations/base.py:115 ops/models/base.py:56 #: ops/models/celery.py:64 ops/models/job.py:123 -#: terminal/models/applet/host.py:109 +#: terminal/models/applet/host.py:110 msgid "Date finished" msgstr "结束日期" @@ -446,13 +446,13 @@ msgstr "账号验证" #: assets/models/group.py:20 assets/models/label.py:18 #: assets/models/platform.py:21 assets/models/platform.py:76 #: assets/serializers/asset/common.py:68 assets/serializers/asset/common.py:142 -#: assets/serializers/platform.py:132 +#: assets/serializers/platform.py:91 assets/serializers/platform.py:136 #: authentication/serializers/connect_token_secret.py:103 ops/mixin.py:21 #: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py: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 #: 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/storage.py:26 terminal/models/component/task.py:15 #: terminal/models/component/terminal.py:79 users/forms/profile.py:33 @@ -469,7 +469,7 @@ msgstr "特权账号" #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/label.py:22 #: 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" msgstr "激活" @@ -529,7 +529,7 @@ msgstr "已托管密码" #: accounts/serializers/account/account.py:75 applications/models.py:11 #: assets/models/label.py:21 assets/models/platform.py:77 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 -#: assets/serializers/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 #: tickets/models/ticket/apply_application.py:13 msgid "Category" @@ -540,10 +540,10 @@ msgstr "类别" #: acls/serializers/command_acl.py:18 applications/models.py:14 #: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/cmd_filter.py:74 assets/models/platform.py:78 -#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:92 +#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:96 #: audits/serializers.py:48 #: 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:146 terminal/serializers/applet.py:28 #: terminal/serializers/session.py:22 terminal/serializers/storage.py:224 @@ -819,7 +819,7 @@ msgstr "" "格式为逗号分隔的字符串, * 表示匹配所有。例如: 192.168.10.1, 192.168.1.0/24, " "10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 (支持网域)" -#: acls/serializers/base.py:40 assets/serializers/asset/host.py:37 +#: acls/serializers/base.py:40 assets/serializers/asset/host.py:36 msgid "IP/Host" msgstr "IP/主机" @@ -922,7 +922,7 @@ msgstr "删除失败,节点包含资产" msgid "App assets" msgstr "资产管理" -#: assets/automations/base/manager.py:106 +#: assets/automations/base/manager.py:107 msgid "{} disabled" msgstr "{} 已禁用" @@ -995,11 +995,11 @@ msgid "Cloud service" msgstr "云服务" #: 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" 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 msgid "General" msgstr "一般" @@ -1035,7 +1035,7 @@ msgid "Basic" msgstr "基本" #: 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" msgstr "脚本" @@ -1051,8 +1051,8 @@ msgstr "SSH公钥" #: 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 #: 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/host.py:110 terminal/models/component/endpoint.py:24 +#: terminal/models/applet/applet.py:36 terminal/models/applet/applet.py:155 +#: terminal/models/applet/host.py:111 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:100 #: terminal/models/session/session.py:47 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:756 @@ -1101,7 +1101,7 @@ msgstr "用户名与用户相同" #: assets/models/_user.py:52 authentication/models/connection_token.py:38 #: 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 msgid "Protocol" msgstr "协议" @@ -1190,14 +1190,10 @@ msgid "Can test asset connectivity" msgstr "可以测试资产连接性" #: assets/models/asset/common.py:284 -msgid "Can push account to asset" -msgstr "可以推送账号到资产" - -#: assets/models/asset/common.py:286 msgid "Can match asset" msgstr "可以匹配资产" -#: assets/models/asset/common.py:287 +#: assets/models/asset/common.py:285 msgid "Can change asset nodes" msgstr "可以修改资产节点" @@ -1222,22 +1218,22 @@ msgstr "客户端密钥" msgid "Allow invalid cert" 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" msgstr "自动代填" #: 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" msgstr "用户名选择器" #: 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" msgstr "密码选择器" #: 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" msgstr "确认按钮选择器" @@ -1256,7 +1252,7 @@ msgstr "资产自动化任务" #: assets/models/automations/base.py:112 audits/models.py:177 #: 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/serializers/applet_host.py:93 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 @@ -1398,45 +1394,45 @@ msgstr "启用" msgid "Ansible config" 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" msgstr "启用资产探活" -#: assets/models/platform.py:45 assets/serializers/platform.py:61 +#: assets/models/platform.py:45 assets/serializers/platform.py:62 msgid "Ping method" msgstr "资产探活方式" #: assets/models/platform.py:46 assets/models/platform.py:59 -#: assets/serializers/platform.py:62 +#: assets/serializers/platform.py:63 msgid "Gather facts enabled" msgstr "启用收集资产信息" #: assets/models/platform.py:47 assets/models/platform.py:61 -#: assets/serializers/platform.py:63 +#: assets/serializers/platform.py:64 msgid "Gather facts method" 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" 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" 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" 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" 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" 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" msgstr "账号验证方式" @@ -1448,23 +1444,23 @@ msgstr "元数据" msgid "Internal" msgstr "内置" -#: assets/models/platform.py:83 assets/serializers/platform.py:90 +#: assets/models/platform.py:83 assets/serializers/platform.py:94 msgid "Charset" msgstr "编码" -#: assets/models/platform.py:85 assets/serializers/platform.py:118 +#: assets/models/platform.py:85 assets/serializers/platform.py:122 msgid "Domain enabled" msgstr "启用网域" -#: assets/models/platform.py:87 assets/serializers/platform.py:117 +#: assets/models/platform.py:87 assets/serializers/platform.py:121 msgid "Su enabled" msgstr "启用账号切换" -#: assets/models/platform.py:88 assets/serializers/platform.py:100 +#: assets/models/platform.py:88 assets/serializers/platform.py:104 msgid "Su method" msgstr "账号切换方式" -#: assets/models/platform.py:90 assets/serializers/platform.py:97 +#: assets/models/platform.py:90 assets/serializers/platform.py:101 msgid "Automation" msgstr "自动化" @@ -1477,7 +1473,7 @@ msgstr "%(value)s is not an even number" msgid "Auto fill" 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:66 #: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:99 @@ -1524,40 +1520,40 @@ msgstr "型号" msgid "Serial number" msgstr "序列号" -#: assets/serializers/asset/host.py:16 +#: assets/serializers/asset/host.py:15 msgid "CPU model" msgstr "CPU型号" -#: assets/serializers/asset/host.py:17 +#: assets/serializers/asset/host.py:16 msgid "CPU count" msgstr "CPU数量" -#: assets/serializers/asset/host.py:18 +#: assets/serializers/asset/host.py:17 msgid "CPU cores" msgstr "CPU核数" -#: assets/serializers/asset/host.py:19 +#: assets/serializers/asset/host.py:18 msgid "CPU vcpus" msgstr "CPU总数" -#: assets/serializers/asset/host.py:20 +#: assets/serializers/asset/host.py:19 msgid "Memory" msgstr "内存" -#: assets/serializers/asset/host.py:21 +#: assets/serializers/asset/host.py:20 msgid "Disk total" msgstr "硬盘大小" -#: assets/serializers/asset/host.py:23 +#: assets/serializers/asset/host.py:22 #: authentication/serializers/connect_token_secret.py:105 msgid "OS" msgstr "操作系统" -#: assets/serializers/asset/host.py:24 +#: assets/serializers/asset/host.py:23 msgid "OS version" msgstr "系统版本" -#: assets/serializers/asset/host.py:25 +#: assets/serializers/asset/host.py:24 msgid "OS arch" msgstr "系统架构" @@ -1589,31 +1585,31 @@ msgstr "不能包含: /" msgid "The same level node name cannot be the same" msgstr "同级别节点名字不能重复" -#: assets/serializers/platform.py:25 +#: assets/serializers/platform.py:26 msgid "SFTP enabled" msgstr "SFTP 已启用" -#: assets/serializers/platform.py:26 +#: assets/serializers/platform.py:27 msgid "SFTP home" msgstr "SFTP 根路径" -#: assets/serializers/platform.py:42 +#: assets/serializers/platform.py:43 msgid "Auth with username" msgstr "使用用户名认证" -#: assets/serializers/platform.py:70 +#: assets/serializers/platform.py:71 msgid "Gather accounts enabled" msgstr "启用账号收集" -#: assets/serializers/platform.py:71 +#: assets/serializers/platform.py:72 msgid "Gather accounts method" msgstr "收集账号方式" -#: assets/serializers/platform.py:77 +#: assets/serializers/platform.py:78 msgid "Primary" msgstr "主要的" -#: assets/serializers/platform.py:119 +#: assets/serializers/platform.py:123 msgid "Default Domain" msgstr "默认网域" @@ -1755,7 +1751,7 @@ msgid "Change password" msgstr "改密" #: 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 msgid "Terminal" msgstr "终端" @@ -1772,7 +1768,7 @@ msgstr "会话日志" msgid "Login log" 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 msgid "Task" msgstr "任务" @@ -3554,7 +3550,7 @@ msgstr "组织" msgid "Org name" 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" msgstr "内置的" @@ -3798,7 +3794,7 @@ msgstr "权限" msgid "Users amount" 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" msgstr "显示名称" @@ -3862,8 +3858,8 @@ msgstr "任务中心" msgid "My assets" msgstr "我的资产" -#: rbac/tree.py:57 terminal/models/applet/applet.py:42 -#: terminal/models/applet/applet.py:147 terminal/models/applet/host.py:27 +#: rbac/tree.py:57 terminal/models/applet/applet.py:43 +#: terminal/models/applet/applet.py:151 terminal/models/applet/host.py:28 msgid "Applet" msgstr "远程应用" @@ -4753,7 +4749,7 @@ msgstr "验证码有效时间" #: settings/serializers/security.py:117 msgid "Unit: second, reset password and send SMS code expiration time" -msgstr "单位: 秒, 重置密码和发送短信验证码过期时间" +msgstr "单位: 秒, 重置密码的验证码及发送短信的验证码过期时间" #: settings/serializers/security.py:121 msgid "Enable Login dynamic code" @@ -5262,7 +5258,7 @@ msgstr "测试成功" msgid "Test failure: Account invalid" msgstr "测试失败: 账号无效" -#: terminal/api/component/terminal.py:35 +#: terminal/api/component/terminal.py:55 msgid "Have online sessions" msgstr "有在线会话" @@ -5352,44 +5348,44 @@ msgstr "不支持批量创建" msgid "Storage is invalid" msgstr "存储无效" -#: terminal/models/applet/applet.py:29 +#: terminal/models/applet/applet.py:30 msgid "Author" msgstr "作者" -#: terminal/models/applet/applet.py:34 +#: terminal/models/applet/applet.py:35 msgid "Tags" 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" msgstr "主机" -#: terminal/models/applet/applet.py:83 +#: terminal/models/applet/applet.py:84 msgid "Applet pkg not valid, Missing file {}" msgstr "Applet pkg 无效,缺少文件 {}" -#: terminal/models/applet/applet.py:149 terminal/models/applet/host.py:33 -#: terminal/models/applet/host.py:105 +#: terminal/models/applet/applet.py:153 terminal/models/applet/host.py:34 +#: terminal/models/applet/host.py:106 msgid "Hosting" 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" msgstr "部署参数" -#: terminal/models/applet/host.py:19 +#: terminal/models/applet/host.py:20 msgid "Inited" msgstr "已初始化" -#: terminal/models/applet/host.py:20 +#: terminal/models/applet/host.py:21 msgid "Date inited" msgstr "初始化日期" -#: terminal/models/applet/host.py:21 +#: terminal/models/applet/host.py:22 msgid "Date synced" msgstr "同步日期" -#: terminal/models/applet/host.py:106 +#: terminal/models/applet/host.py:107 msgid "Initial" msgstr "初始化" @@ -7263,6 +7259,9 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "Can push account to asset" +#~ msgstr "可以推送账号到资产" + #~ msgid "Add asset to node" #~ msgstr "添加资产到节点" diff --git a/apps/ops/signal_handlers.py b/apps/ops/signal_handlers.py index faba5c9eb..5e5090e4b 100644 --- a/apps/ops/signal_handlers.py +++ b/apps/ops/signal_handlers.py @@ -67,7 +67,8 @@ def check_registered_tasks(*args, **kwargs): continue for attr in attrs: if not hasattr(task, attr): - print('>>> Task {} has no attribute {}'.format(name, attr)) + # print('>>> Task {} has no attribute {}'.format(name, attr)) + pass @signals.before_task_publish.connect diff --git a/apps/rbac/permissions.py b/apps/rbac/permissions.py index 788c10a69..7cc35d370 100644 --- a/apps/rbac/permissions.py +++ b/apps/rbac/permissions.py @@ -97,10 +97,10 @@ class RBACPermission(permissions.DjangoModelPermissions): else: model_cls = queryset.model except AssertionError as e: - logger.error('Error get model cls: ', e) + logger.error(f'Error get model cls: {e}') model_cls = None except AttributeError as e: - logger.error('Error get model cls: ', e) + logger.error(f'Error get model cls: {e}') model_cls = None except Exception as e: logger.error('Error get model class: {} of {}'.format(e, view)) diff --git a/apps/terminal/api/applet/host.py b/apps/terminal/api/applet/host.py index 40c0c6caf..38c42cd18 100644 --- a/apps/terminal/api/applet/host.py +++ b/apps/terminal/api/applet/host.py @@ -58,7 +58,7 @@ class AppletHostDeploymentViewSet(viewsets.ModelViewSet): def applets(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) - applet_id = serializer.validated_data.get('applet_id') + applet_id = serializer.validated_data.pop('applet_id') instance = serializer.save() task = run_applet_host_deployment_install_applet.delay(instance.id, applet_id) instance.save_task(task.id) diff --git a/apps/terminal/api/component/terminal.py b/apps/terminal/api/component/terminal.py index d877be1df..6d4c141d1 100644 --- a/apps/terminal/api/component/terminal.py +++ b/apps/terminal/api/component/terminal.py @@ -1,13 +1,15 @@ # -*- coding: utf-8 -*- # import logging - +from django.db.models import Q from django.conf import settings from django.utils.translation import gettext_lazy as _ from rest_framework import generics from rest_framework import status from rest_framework.views import APIView, Response +from django_filters import rest_framework as filters +from common.drf.filters import BaseFilterSet from common.api import JMSBulkModelViewSet from common.exceptions import JMSException from common.permissions import WithBootstrapToken @@ -21,10 +23,28 @@ __all__ = [ logger = logging.getLogger(__file__) +class TerminalFilterSet(BaseFilterSet): + name = filters.CharFilter(field_name='name', lookup_expr='icontains') + remote_addr = filters.CharFilter(field_name='remote_addr', lookup_expr='icontains') + + class Meta: + model = Terminal + fields = ['name', 'remote_addr', 'type'] + + def filter_queryset(self, queryset): + queryset = super().filter_queryset(queryset) + search = self.request.query_params.get('search') + if not search: + return queryset + q = Q(name__icontains=search) | Q(remote_addr__icontains=search) + queryset = queryset.filter(q) + return queryset + + class TerminalViewSet(JMSBulkModelViewSet): queryset = Terminal.objects.filter(is_deleted=False) serializer_class = serializers.TerminalSerializer - filterset_fields = ['name', 'remote_addr', 'type'] + filterset_class = TerminalFilterSet custom_filter_fields = ['load'] def destroy(self, request, *args, **kwargs): diff --git a/apps/terminal/applets/__init__.py b/apps/terminal/applets/__init__.py index bb09feecd..0d8e50a3b 100644 --- a/apps/terminal/applets/__init__.py +++ b/apps/terminal/applets/__init__.py @@ -11,9 +11,9 @@ def install_or_update_builtin_applets(): path = os.path.join(BASE_DIR, d) if not os.path.isdir(path) or not os.path.exists(os.path.join(path, 'manifest.yml')): continue - print("Install or update applet: {}".format(path)) try: - Applet.install_from_dir(path) + if Applet.install_from_dir(path): + print("Install or update applet: {}".format(path)) except Exception as e: print(e) diff --git a/apps/terminal/applets/dbeaver/app.py b/apps/terminal/applets/dbeaver/app.py index e9a7dff4d..f99fdd54c 100644 --- a/apps/terminal/applets/dbeaver/app.py +++ b/apps/terminal/applets/dbeaver/app.py @@ -2,8 +2,7 @@ import os import time import win32api import shutil - -from pywinauto import Application +import subprocess from common import wait_pid, BaseApplication @@ -61,16 +60,19 @@ class AppletApplication(BaseApplication): def run(self): self.launch() - self.app = Application(backend='uia') function = getattr(self, '_get_%s_exec_params' % self.protocol, None) if function is None: params = self._get_exec_params() else: params = function() + + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags = subprocess.CREATE_NEW_CONSOLE | subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE exec_string = '%s -con %s' % (self.path, params) - self.app.start(exec_string, wait_for_idle=False) - self.pid = self.app.process + ret = subprocess.Popen(exec_string, startupinfo=startupinfo) + self.pid = ret.pid def wait(self): wait_pid(self.pid) diff --git a/apps/terminal/automations/deploy_applet_host/playbook.yml b/apps/terminal/automations/deploy_applet_host/playbook.yml index 73e0e6c09..4185f3ba1 100644 --- a/apps/terminal/automations/deploy_applet_host/playbook.yml +++ b/apps/terminal/automations/deploy_applet_host/playbook.yml @@ -30,6 +30,16 @@ include_management_tools: yes register: rds_install + - name: Stop Tinker before install (jumpserver) + ansible.windows.win_powershell: + script: | + if (Get-Service -Name 'JumpServer Tinker' -ErrorAction SilentlyContinue) { + Stop-Service -Name 'JumpServer Tinker' -Force + } + else { + $Ansible.Changed = $false + } + - name: Download JumpServer Tinker installer (jumpserver) ansible.windows.win_get_url: url: "{{ APPLET_DOWNLOAD_HOST }}/download/applets/{{ TinkerInstaller }}" @@ -44,7 +54,7 @@ - /NORESTART state: present - - name: Set remote-server on the global system path (remote-server) + - name: Set Tinkerd on the global system path (jumpserver) ansible.windows.win_path: elements: - '%USERPROFILE%\AppData\Local\Programs\Tinker\' diff --git a/apps/terminal/models/applet/applet.py b/apps/terminal/models/applet/applet.py index 1fd8a670f..c71fe95c2 100644 --- a/apps/terminal/models/applet/applet.py +++ b/apps/terminal/models/applet/applet.py @@ -12,6 +12,7 @@ from rest_framework.serializers import ValidationError from common.db.models import JMSBaseModel from common.utils import lazyproperty, get_logger +from jumpserver.utils import has_valid_xpack_license logger = get_logger(__name__) @@ -95,6 +96,9 @@ class Applet(JMSBaseModel): manifest = cls.validate_pkg(path) name = manifest['name'] + if not has_valid_xpack_license() and name.lower() in ('navicat', ): + return + instance = cls.objects.filter(name=name).first() serializer = AppletSerializer(instance=instance, data=manifest) serializer.is_valid() diff --git a/apps/terminal/models/applet/host.py b/apps/terminal/models/applet/host.py index e179a8380..47de718df 100644 --- a/apps/terminal/models/applet/host.py +++ b/apps/terminal/models/applet/host.py @@ -10,6 +10,7 @@ from simple_history.utils import bulk_create_with_history from assets.models import Host from common.db.models import JMSBaseModel from common.utils import random_string +from terminal.const import PublishStatus __all__ = ['AppletHost', 'AppletHostDeployment'] @@ -63,11 +64,11 @@ class AppletHost(Host): status_applets = defaultdict(list) for applet in applets: if applet.name not in name_version_mapper: - status_applets['unpublished'].append(applet) + status_applets[PublishStatus.failed.value].append(applet) elif applet.version != name_version_mapper[applet.name]: - status_applets['not_match'].append(applet) + status_applets[PublishStatus.mismatch.value].append(applet) else: - status_applets['published'].append(applet) + status_applets[PublishStatus.success.value].append(applet) for status, applets in status_applets.items(): self.publications.filter(applet__in=applets) \ diff --git a/apps/tickets/api/ticket.py b/apps/tickets/api/ticket.py index 52c388cec..29163a342 100644 --- a/apps/tickets/api/ticket.py +++ b/apps/tickets/api/ticket.py @@ -2,13 +2,13 @@ # from rest_framework import viewsets from rest_framework.decorators import action -from rest_framework.response import Response from rest_framework.exceptions import MethodNotAllowed +from rest_framework.response import Response -from orgs.utils import tmp_to_root_org -from rbac.permissions import RBACPermission from common.api import CommonApiMixin from common.const.http import POST, PUT, PATCH +from orgs.utils import tmp_to_root_org +from rbac.permissions import RBACPermission from tickets import filters from tickets import serializers from tickets.models import ( @@ -40,6 +40,14 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet): 'open': 'tickets.view_ticket', } + + def retrieve(self, request, *args, **kwargs): + instance = self.get_object() + with tmp_to_root_org(): + serializer = self.get_serializer(instance) + data = serializer.data + return Response(data) + def create(self, request, *args, **kwargs): raise MethodNotAllowed(self.action) diff --git a/apps/tickets/templates/tickets/ticket_approve_diff.html b/apps/tickets/templates/tickets/ticket_approve_diff.html index 8426b34ed..79aad6b5c 100644 --- a/apps/tickets/templates/tickets/ticket_approve_diff.html +++ b/apps/tickets/templates/tickets/ticket_approve_diff.html @@ -18,7 +18,6 @@ {% endfor %} {% endfor %} - {% endif %}