diff --git a/apps/node_man/models.py b/apps/node_man/models.py index 6954224fe..2f4c701a2 100644 --- a/apps/node_man/models.py +++ b/apps/node_man/models.py @@ -152,6 +152,8 @@ class KeyEnum(Enum): ADD_HOST_CLOUD_BLACKLIST = "ADD_HOST_CLOUD_BLACKLIST" # 消息中心开关 ENABLE_NOTICE_CENTER = "ENABLE_NOTICE_CENTER" + # 禁用已停用插件 + DISABLE_STOPPED_PLUGIN = "DISABLE_STOPPED_PLUGIN" key = models.CharField(_("键"), max_length=255, db_index=True, primary_key=True) v_json = JSONField(_("值")) diff --git a/apps/node_man/serializers/plugin.py b/apps/node_man/serializers/plugin.py index dc9d0a6c3..ff2e6bfce 100644 --- a/apps/node_man/serializers/plugin.py +++ b/apps/node_man/serializers/plugin.py @@ -22,7 +22,13 @@ JobType, ProcType, ) -from apps.node_man.models import GsePluginDesc, Packages, ProcControl, ProcessStatus +from apps.node_man.models import ( + GlobalSettings, + GsePluginDesc, + Packages, + ProcControl, + ProcessStatus, +) from apps.node_man.serializers import base @@ -248,6 +254,10 @@ def validate(self, attrs): raise ValidationError(_("插件参数 plugin_params 和 plugin_params_list 参数不能同时为空")) if attrs.get("plugin_params"): + if GlobalSettings.get_config(key=GlobalSettings.KeyEnum.DISABLE_STOPPED_PLUGIN.value, default=True): + plugin_name = attrs["plugin_params"]["name"] + if GsePluginDesc.objects.filter(name=plugin_name, is_ready=False).first() is not None: + raise ValidationError(_("插件{}已被禁用,不能执行相关操作").format(plugin_name)) # 把2.0.x 的参数转为 2.1.x 的参数 attrs["plugin_params_list"] = [attrs.get("plugin_params")] diff --git a/apps/node_man/tests/test_views/test_plugins.py b/apps/node_man/tests/test_views/test_plugins.py index d56e08d5b..575fdfa94 100644 --- a/apps/node_man/tests/test_views/test_plugins.py +++ b/apps/node_man/tests/test_views/test_plugins.py @@ -55,3 +55,23 @@ def test_common_plugin_list(self): response = self.client.get(f"/api/plugin/{self.PLUGIN_NAME}/package/", {"os": "LINUX"}) self.assertFalse(response["result"]) self.assertRegex(response["message"], r"bk_collector_not-found in.*") + + +class PluginOperateViewTestCase(PluginViewTestCase): + PLUGIN_NAME = "stopped_plugin" + + def setUp(self) -> None: + super().setUp() + models.GsePluginDesc.objects.filter(name=self.PLUGIN_NAME).update(is_ready=False) + + def test_stopped_plugin_operate(self): + response = self.client.post( + "/api/plugin/operate/", + data={ + "job_type": "MAIN_INSTALL_PLUGIN", + "bk_host_id": [111], + "plugin_params": {"name": "stopped_plugin", "version": "latest"}, + }, + ) + self.assertFalse(response["result"]) + self.assertEqual(response["message"], f"插件{self.PLUGIN_NAME}已被禁用,不能执行相关操作(3800001)")