diff --git a/apps/accounts/backends/__init__.py b/apps/accounts/backends/__init__.py index 832033b73..5e26cfc76 100644 --- a/apps/accounts/backends/__init__.py +++ b/apps/accounts/backends/__init__.py @@ -5,8 +5,7 @@ from django.utils.functional import LazyObject from common.utils import get_logger from ..const import VaultTypeChoices -__all__ = ['vault_client', 'get_vault_client'] - +__all__ = ['vault_client', 'get_vault_client', 'refresh_vault_client'] logger = get_logger(__file__) @@ -38,3 +37,8 @@ class VaultClient(LazyObject): """ 为了安全, 页面修改配置, 重启服务后才会重新初始化 vault_client """ vault_client = VaultClient() + + +def refresh_vault_client(): + vault_client._wrapped = None + vault_client._setup() diff --git a/apps/accounts/signal_handlers.py b/apps/accounts/signal_handlers.py index ad07c9bb3..04c2cc333 100644 --- a/apps/accounts/signal_handlers.py +++ b/apps/accounts/signal_handlers.py @@ -3,14 +3,17 @@ from collections import defaultdict from django.db.models.signals import post_delete from django.db.models.signals import pre_save, post_save from django.dispatch import receiver +from django.utils.functional import LazyObject from django.utils.translation import gettext_noop -from accounts.backends import vault_client +from accounts.backends import vault_client, refresh_vault_client from accounts.const import Source from audits.const import ActivityChoices from audits.signal_handlers import create_activities from common.decorators import merge_delay_run +from common.signals import django_ready from common.utils import get_logger, i18n_fmt +from common.utils.connection import RedisPubSub from .models import Account, AccountTemplate from .tasks.push_account import push_accounts_to_assets_task @@ -91,3 +94,18 @@ class VaultSignalHandler(object): for model in (Account, AccountTemplate, Account.history.model): post_save.connect(VaultSignalHandler.save_to_vault, sender=model) post_delete.connect(VaultSignalHandler.delete_to_vault, sender=model) + + +class VaultPubSub(LazyObject): + def _setup(self): + self._wrapped = RedisPubSub('refresh_vault') + + +vault_pub_sub = VaultPubSub() + + +@receiver(django_ready) +def subscribe_vault_change(sender, **kwargs): + logger.debug("Start subscribe vault change") + + vault_pub_sub.subscribe(lambda name: refresh_vault_client()) diff --git a/apps/i18n/lina/en.json b/apps/i18n/lina/en.json index 49c65e37a..fecab5059 100644 --- a/apps/i18n/lina/en.json +++ b/apps/i18n/lina/en.json @@ -178,6 +178,7 @@ "Azure": "Azure (China)", "Azure_Int": "Azure (International)", "AzureKeyVault": "Azure vault", + "HashicorpVault": "HCP vault", "Backup": "Backup", "BackupAccountsHelpText": "Backup account information externally. it can be stored in an external system or sent via email, supporting segmented delivery.", "BadConflictErrorMsg": "Refreshing, please try again later", diff --git a/apps/i18n/lina/ja.json b/apps/i18n/lina/ja.json index 57288b30a..b4bd08b0b 100644 --- a/apps/i18n/lina/ja.json +++ b/apps/i18n/lina/ja.json @@ -178,6 +178,7 @@ "Azure": "Azure(中国)", "Azure_Int": "アジュール(インターナショナル)", "AzureKeyVault": "Azure vault", + "HashicorpVault": "HCP vault", "Backup": "バックアップ", "BackupAccountsHelpText": "アカウント情報を外部にバックアップする。外部システムに保存するかメールを送信することもできます、セクション方式をサポートしています", "BadConflictErrorMsg": "更新中です、しばらくお待ちください", diff --git a/apps/i18n/lina/zh.json b/apps/i18n/lina/zh.json index 7c82132b3..f84e5c540 100644 --- a/apps/i18n/lina/zh.json +++ b/apps/i18n/lina/zh.json @@ -178,6 +178,7 @@ "Azure": "Azure (中国)", "Azure_Int": "Azure (国际)", "AzureKeyVault": "Azure vault", + "HashicorpVault": "HCP vault", "Backup": "备份", "BackupAccountsHelpText": "备份账号信息到外部。可以存储到外部系统或发送邮件,支持分段方式", "BadConflictErrorMsg": "正在刷新中,请稍后再试", diff --git a/apps/i18n/lina/zh_hant.json b/apps/i18n/lina/zh_hant.json index 4adc747de..1216087ee 100644 --- a/apps/i18n/lina/zh_hant.json +++ b/apps/i18n/lina/zh_hant.json @@ -239,6 +239,7 @@ "Azure": "Azure (中國)", "Azure_Int": "Azure (國際)", "AzureKeyVault": "Azure vault", + "HashicorpVault": "HCP vault", "Backup": "備份", "BackupAccountsHelpText": "備份帳號資訊至外部。可以儲存到外部系統或寄送郵件,支援分段方式", "BadConflictErrorMsg": "正在刷新中,請稍後再試", diff --git a/apps/settings/serializers/feature.py b/apps/settings/serializers/feature.py index 23a484571..b6dcacc08 100644 --- a/apps/settings/serializers/feature.py +++ b/apps/settings/serializers/feature.py @@ -1,9 +1,9 @@ import uuid + from django.utils import timezone from django.utils.translation import gettext_lazy as _ from rest_framework import serializers -from accounts.const import VaultTypeChoices from assets.const import Protocol from common.serializers.fields import EncryptedField from common.utils import date_expired_default @@ -43,7 +43,16 @@ class AnnouncementSettingSerializer(serializers.Serializer): ANNOUNCEMENT = AnnouncementSerializer(label=_("Announcement")) -class VaultSettingSerializer(serializers.Serializer): +class BaseVaultSettingSerializer(serializers.Serializer): + + def validate(self, data): + from accounts.signal_handlers import vault_pub_sub + data = super().validate(data) + vault_pub_sub.publish('vault') + return data + + +class VaultSettingSerializer(BaseVaultSettingSerializer, serializers.Serializer): PREFIX_TITLE = _('Vault') VAULT_ENABLED = serializers.BooleanField( @@ -65,7 +74,7 @@ class VaultSettingSerializer(serializers.Serializer): ) -class HashicorpKVSerializer(serializers.Serializer): +class HashicorpKVSerializer(BaseVaultSettingSerializer, serializers.Serializer): PREFIX_TITLE = _('HCP Vault') VAULT_HCP_HOST = serializers.CharField( max_length=256, allow_blank=True, required=False, label=_('Host') @@ -78,7 +87,7 @@ class HashicorpKVSerializer(serializers.Serializer): ) -class AzureKVSerializer(serializers.Serializer): +class AzureKVSerializer(BaseVaultSettingSerializer, serializers.Serializer): PREFIX_TITLE = _('Azure Key Vault') VAULT_AZURE_HOST = serializers.CharField( max_length=256, allow_blank=True, required=False, label=_('Host')