diff --git a/bkmonitor/packages/monitor_web/k8s/core/meta.py b/bkmonitor/packages/monitor_web/k8s/core/meta.py index 67b4a52cd..b27c3c257 100644 --- a/bkmonitor/packages/monitor_web/k8s/core/meta.py +++ b/bkmonitor/packages/monitor_web/k8s/core/meta.py @@ -62,7 +62,7 @@ def transform_filter_dict(self, filter_obj) -> Dict: else: field_name, condition = parsed_token # 字段映射, prometheus数据字段 映射到 ORM中的 模型字段 - field_name = resource_meta.column_mapping.get(field_name, field_name) + field_name = self.meta.column_mapping.get(field_name, field_name) # 重新组装特殊查询条件 new_key = field_name if len(parsed_token) == 1 else f"{field_name}__{condition}" orm_filter_dict[new_key] = value diff --git a/bkmonitor/packages/monitor_web/k8s/resources.py b/bkmonitor/packages/monitor_web/k8s/resources.py index 67cef8cee..db040dea3 100644 --- a/bkmonitor/packages/monitor_web/k8s/resources.py +++ b/bkmonitor/packages/monitor_web/k8s/resources.py @@ -112,7 +112,7 @@ class RequestSerializer(serializers.Serializer): bk_biz_id: int = serializers.IntegerField(required=True) namespace: str = serializers.CharField(required=True) resource_type: str = serializers.ChoiceField( - required=True, choices=["pod", "workload", "container"], label="资源类型" + required=True, choices=["pod", "workload", "container", "cluster"], label="资源类型" ) # 私有参数 pod_name: str = serializers.CharField(required=False, allow_null=True) @@ -132,6 +132,9 @@ def validate_request_data(self, request_data: Dict): elif resource_type == "container": fields = ["pod_name", "container_name"] self.validate_field_exist(resource_type, fields, request_data) + elif resource_type == "cluster": + # 只有 bk_biz_id, bcs_cluster_id 是必传的 + pass return super().validate_request_data(request_data) @@ -158,32 +161,23 @@ def link_to_string(cls, item: Dict): def perform_request(self, validated_request_data): bk_biz_id = validated_request_data["bk_biz_id"] bcs_cluster_id = validated_request_data["bcs_cluster_id"] - namespace = validated_request_data["namespace"] resource_type = validated_request_data["resource_type"] - if resource_type == "pod": - items: List[Dict] = resource.scene_view.get_kubernetes_pod( - bk_biz_id=bk_biz_id, - bcs_cluster_id=bcs_cluster_id, - namespace=namespace, - pod_name=validated_request_data["pod_name"], - ) - elif resource_type == "workload": - items: List[Dict] = resource.scene_view.get_kubernetes_workload( - bk_biz_id=bk_biz_id, - bcs_cluster_id=bcs_cluster_id, - namespace=namespace, - workload_name=validated_request_data["workload_name"], - workload_type=validated_request_data["workload_type"], - ) - elif resource_type == "container": - items: List[Dict] = resource.scene_view.get_kubernetes_container( - bk_biz_id=bk_biz_id, - bcs_cluster_id=bcs_cluster_id, - namespace=namespace, - pod_name=validated_request_data["pod_name"], - container_name=validated_request_data["container_name"], - ) + + # 不同的 resource_type 对应不同要调用的接口,并且记录额外要传递的参数 + resource_router: Dict[str, List[Dict]] = { + "cluster": [resource.scene_view.get_kubernetes_cluster, []], + "pod": [resource.scene_view.get_kubernetes_pod, ["namespace", "pod_name"]], + "workload": [resource.scene_view.get_kubernetes_workload, ["namespace", "workload_name", "workload_type"]], + "container": [resource.scene_view.get_kubernetes_container, ["namespace", "pod_name", "container_name"]], + } + # 构建同名字典 -> {"field":validated_request_data["field"]} + extra_request_arg = {key: validated_request_data[key] for key in resource_router[resource_type][1]} + + # 调用对应的资源类型的接口,返回对应的接口数据 + items = resource_router[resource_type][0]( + **{"bk_biz_id": bk_biz_id, "bcs_cluster_id": bcs_cluster_id, **extra_request_arg} + ) for item in items: self.link_to_string(item) diff --git a/bkmonitor/packages/monitor_web/tests/k8s/test_filter.py b/bkmonitor/packages/monitor_web/tests/k8s/test_filter.py index 8d4e762e1..f51091776 100644 --- a/bkmonitor/packages/monitor_web/tests/k8s/test_filter.py +++ b/bkmonitor/packages/monitor_web/tests/k8s/test_filter.py @@ -16,6 +16,7 @@ from django.utils import timezone from humanize import naturaldelta +from bkmonitor.models import BCSCluster from monitor_web.k8s.core.filters import ( ContainerFilter, NamespaceFilter, @@ -195,6 +196,23 @@ def setUp(self): created_at=timezone.now(), last_synced_at=timezone.now(), ).save() + BCSCluster( + bk_biz_id=2, + bcs_cluster_id="BCS-K8S-00000", + name="", + area_name="", + project_name="", + environment="正式", + updated_at=timezone.now(), + node_count=18, + cpu_usage_ratio=19.22, + memory_usage_ratio=65.36, + disk_usage_ratio=51.45, + created_at=timezone.now(), + status="RUNNING", + monitor_status="success", + last_synced_at=timezone.now(), + ).save() def test_link_to_string(self): items = [ @@ -525,6 +543,73 @@ def test_with_container(self): ] self.assertEqual(result, expect_data) + def test_with_cluster(self): + validated_request_data = { + "bk_biz_id": 2, + "bcs_cluster_id": "BCS-K8S-00000", + "namespace": "bkmonitor", + "resource_type": "cluster", + } + age = naturaldelta( + datetime.utcnow().replace(tzinfo=timezone.utc) - datetime.utcnow().replace(tzinfo=timezone.utc) + ) + with mock.patch("bkmonitor.models.BCSCluster.update_monitor_status") as mock_update_monitor_status: + mock_update_monitor_status.return_value = None + + actual_data = GetResourceDetail()(validated_request_data) + expect_data = [ + { + "key": "bcs_cluster_id", + "name": "集群ID", + "type": "string", + "value": "BCS-K8S-00000", + }, + {"key": "name", "name": "集群名称", "type": "string", "value": ""}, + {"key": "status", "name": "运行状态", "type": "string", "value": "RUNNING"}, + { + "key": "monitor_status", + "name": "采集状态", + "type": "status", + "value": {"type": "success", "text": "正常"}, + }, + {"key": "environment", "name": "环境", "type": "string", "value": "正式"}, + {"key": "node_count", "name": "节点数量", "type": "number", "value": 18}, + { + "key": "cpu_usage_ratio", + "name": "CPU使用率", + "type": "progress", + "value": {"value": 19.22, "label": "19.22%", "status": "SUCCESS"}, + }, + { + "key": "memory_usage_ratio", + "name": "内存使用率", + "type": "progress", + "value": {"value": 65.36, "label": "65.36%", "status": "SUCCESS"}, + }, + { + "key": "disk_usage_ratio", + "name": "磁盘使用率", + "type": "progress", + "value": {"value": 51.45, "label": "51.45%", "status": "SUCCESS"}, + }, + {"key": "area_name", "name": "区域", "type": "string", "value": ""}, + { + "key": "created_at", + "name": "创建时间", + "type": "string", + "value": age, + }, + { + "key": "updated_at", + "name": "更新时间", + "type": "string", + "value": age, + }, + {"key": "project_name", "name": "所属项目", "type": "string", "value": ""}, + {"key": "description", "name": "描述", "type": "string", "value": ""}, + ] + self.assertEqual(expect_data, actual_data) + class TestWorkloadOverview(TestCase): databases = {"default", "monitor_api"}