diff --git a/apps/core/ipchooser/handlers/host_handler.py b/apps/core/ipchooser/handlers/host_handler.py index 26117da0b..4bb24b5c9 100644 --- a/apps/core/ipchooser/handlers/host_handler.py +++ b/apps/core/ipchooser/handlers/host_handler.py @@ -12,6 +12,9 @@ from django_mysql.models import QuerySet +from apps.core.ipchooser.tools.host_tool import HostTool +from apps.node_man.models import GlobalSettings + from .. import constants, types from ..tools import base from .base import BaseHandler @@ -23,12 +26,14 @@ def details_base( scope_list: types.ScopeList, or_conditions: typing.List[types.Condition], limit_host_ids: typing.Optional[typing.List[int]] = None, + show_agent_realtime_state: bool = False, ) -> typing.List[types.FormatHostInfo]: """ 获取主机详情 :param scope_list: 资源范围数组 :param or_conditions: 逻辑或查询条件 :param limit_host_ids: 限制检索的主机 ID 列表 + :param show_agent_realtime_state: 是否展示Agent实时状态 :return: """ host_queryset: QuerySet = base.HostQuerySqlHelper.multiple_cond_sql( @@ -40,6 +45,15 @@ def details_base( # 获取主机信息 host_fields: typing.List[str] = constants.CommonEnum.DEFAULT_HOST_FIELDS.value untreated_host_infos: typing.List[types.HostInfo] = list(host_queryset.values(*host_fields)) + + if show_agent_realtime_state: + enable = GlobalSettings.get_config( + key=GlobalSettings.KeyEnum.IP_CHOOSER_ENABLE_SHOW_REALTIME_AGENT_STATE.value, default=False + ) + if not enable: + return BaseHandler.format_hosts(untreated_host_infos) + HostTool.fill_agent_state_info_to_hosts(host_infos=untreated_host_infos) + return BaseHandler.format_hosts(untreated_host_infos) @classmethod @@ -107,12 +121,13 @@ def check( @classmethod def details( - cls, scope_list: types.ScopeList, host_list: typing.List[types.FormatHostInfo] + cls, scope_list: types.ScopeList, host_list: typing.List[types.FormatHostInfo], show_agent_realtime_state: bool ) -> typing.List[types.FormatHostInfo]: """ 根据主机关键信息获取机器详情信息 :param scope_list: 资源范围数组 :param host_list: 主机关键信息列表 + :param show_agent_realtime_state: 是否展示Agent实时状态 :return: """ bk_host_id_set: typing.Set[int] = set() @@ -129,4 +144,4 @@ def details( {"key": "bk_host_id", "val": bk_host_id_set}, {"key": "cloud_inner_ip", "val": cloud_inner_ip_set}, ] - return cls.details_base(scope_list, or_conditions) + return cls.details_base(scope_list, or_conditions, show_agent_realtime_state=show_agent_realtime_state) diff --git a/apps/core/ipchooser/serializers/host_sers.py b/apps/core/ipchooser/serializers/host_sers.py index 92c4cddff..4f83b6afc 100644 --- a/apps/core/ipchooser/serializers/host_sers.py +++ b/apps/core/ipchooser/serializers/host_sers.py @@ -47,6 +47,7 @@ class Meta: class HostDetailsRequestSer(base.ScopeSelectorBaseSer): host_list = serializers.ListField(child=base.HostInfoWithMetaSer(), default=[]) + agent_realtime_state = serializers.BooleanField(label=_("agent实时状态"), required=False, default=False) class Meta: swagger_schema_fields = {"example": mock_data.API_HOST_DETAILS_REQUEST} diff --git a/apps/core/ipchooser/tests/test_handlers.py b/apps/core/ipchooser/tests/test_handlers.py index b432972aa..89953f9ae 100644 --- a/apps/core/ipchooser/tests/test_handlers.py +++ b/apps/core/ipchooser/tests/test_handlers.py @@ -13,13 +13,15 @@ from django.test import TestCase from apps.core.ipchooser.handlers.host_handler import HostHandler +from apps.mock_data.api_mkd.gse.utils import GseApiMockClient, get_gse_api_helper from apps.node_man import models from apps.node_man.tests.utils import MockClient, cmdb_or_cache_biz, create_host +from env.constants import GseVersion class TestHostHandler(TestCase): @patch("apps.node_man.handlers.cmdb.CmdbHandler.cmdb_or_cache_biz", cmdb_or_cache_biz) - @patch("apps.node_man.handlers.cmdb.client_v2", MockClient) + @patch("apps.core.ipchooser.query.resource.CCApi", MockClient.cc) def test_check(self): create_host(1, bk_host_id=1000, ip="127.0.0.1", bk_cloud_id=0) res = HostHandler.check( @@ -56,3 +58,21 @@ def test_check(self): key_list=[], ) self.assertEqual(res[0]["ipv6"], "0000:0000:0000:0000:0000:ffff:7f00:0002") + + @patch("apps.core.ipchooser.query.resource.CCApi", MockClient.cc) + @patch( + "apps.node_man.periodic_tasks.sync_agent_status_task.get_gse_api_helper", + get_gse_api_helper(GseVersion.V2.value, GseApiMockClient()), + ) + def test_details(self): + models.GlobalSettings.set_config( + key=models.GlobalSettings.KeyEnum.IP_CHOOSER_ENABLE_SHOW_REALTIME_AGENT_STATE.value, value=True + ) + create_host(100) + res = HostHandler().details( + scope_list=[{"scope_type": "biz", "scope_id": f"{i}", "bk_biz_id": i} for i in range(27, 40)], + host_list=[{"host_id": 1, "meta": {"scope_type": "biz", "scope_id": "28", "bk_biz_id": 28}}], + show_agent_realtime_state=True, + ) + self.assertEqual(res[0]["alive"], 1) + self.assertEqual(res[0]["bk_agent_alive"], 1) diff --git a/apps/core/ipchooser/views.py b/apps/core/ipchooser/views.py index 4486bdb6f..0e08558e0 100644 --- a/apps/core/ipchooser/views.py +++ b/apps/core/ipchooser/views.py @@ -128,6 +128,8 @@ def check(self, request, *args, **kwargs): def details(self, request, *args, **kwargs): return Response( host_handler.HostHandler.details( - scope_list=self.validated_data["scope_list"], host_list=self.validated_data["host_list"] + scope_list=self.validated_data["scope_list"], + host_list=self.validated_data["host_list"], + show_agent_realtime_state=self.validated_data["agent_realtime_state"], ) ) diff --git a/apps/node_man/models.py b/apps/node_man/models.py index 5c05c78e9..81c53f002 100644 --- a/apps/node_man/models.py +++ b/apps/node_man/models.py @@ -162,6 +162,8 @@ class KeyEnum(Enum): PLUGIN_PROC_START_CHECK_SECS = "PLUGIN_PROC_START_CHECK_SECS" # 查询服务实例时module_id阈值,当小于该阈值时以单module_id并发查询 SERVICE_INSTANCE_MODULE_ID_THRESHOLD = "SERVICE_INSTANCE_MODULE_ID_THRESHOLD" + # IP选择器详情接口是否实时展示agent状态 + IP_CHOOSER_ENABLE_SHOW_REALTIME_AGENT_STATE = "IP_CHOOSER_ENABLE_SHOW_REALTIME_AGENT_STATE" key = models.CharField(_("键"), max_length=255, db_index=True, primary_key=True) v_json = JSONField(_("值"))