From 89086ff1628f67c5dc68c058aae27573980fe56c Mon Sep 17 00:00:00 2001 From: peterxucai Date: Thu, 19 Dec 2024 17:06:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(backend):=20=E9=9B=86=E7=BE=A4=E5=92=8C?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E8=A7=86=E5=9B=BE=E6=B7=BB=E5=8A=A0=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E6=98=BE=E7=A4=BA=20#8687?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/db_services/dbbase/serializers.py | 4 ++ dbm-ui/backend/db_services/dbbase/views.py | 67 ++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/dbm-ui/backend/db_services/dbbase/serializers.py b/dbm-ui/backend/db_services/dbbase/serializers.py index 0d4f76dc3e..9c91ef7550 100644 --- a/dbm-ui/backend/db_services/dbbase/serializers.py +++ b/dbm-ui/backend/db_services/dbbase/serializers.py @@ -190,3 +190,7 @@ class Meta: class ClusterDbTypeSerializer(serializers.Serializer): bk_biz_id = serializers.IntegerField(help_text=_("业务ID")) db_type = serializers.ChoiceField(help_text=_("数据库类型"), choices=DBType.get_choices()) + + +class QueryClusterInstanceCountSerializer(serializers.Serializer): + bk_biz_id = serializers.IntegerField(help_text=_("业务ID")) diff --git a/dbm-ui/backend/db_services/dbbase/views.py b/dbm-ui/backend/db_services/dbbase/views.py index fc856fd25d..5e54ee291d 100644 --- a/dbm-ui/backend/db_services/dbbase/views.py +++ b/dbm-ui/backend/db_services/dbbase/views.py @@ -11,7 +11,7 @@ from collections import defaultdict from typing import Dict, List, Set, Union -from django.db.models import Q +from django.db.models import Count, Q from django.utils.translation import ugettext as _ from rest_framework import status from rest_framework.decorators import action @@ -40,6 +40,7 @@ QueryAllTypeClusterSerializer, QueryBizClusterAttrsResponseSerializer, QueryBizClusterAttrsSerializer, + QueryClusterInstanceCountSerializer, ResourceAdministrationSerializer, WebConsoleResponseSerializer, WebConsoleSerializer, @@ -302,3 +303,67 @@ def get_ips_list(self, request, *args, **kwargs): ips.extend(cluster.proxyinstance_set.all().values_list("machine__ip", flat=True)) ips.extend(cluster.storageinstance_set.all().values_list("machine__ip", flat=True)) return Response(ips) + + @common_swagger_auto_schema( + operation_summary=_("根据业务id查询业务下所有集群集群数量与实例数量"), + auto_schema=ResponseSwaggerAutoSchema, + query_serializer=QueryClusterInstanceCountSerializer(), + tags=[SWAGGER_TAG], + ) + @action(methods=["GET"], detail=False, serializer_class=QueryClusterInstanceCountSerializer) + def query_cluster_instance_count(self, request, *args, **kwargs): + + validate_data = self.params_validate(self.get_serializer_class()) + cluster_queryset = Cluster.objects.filter(**validate_data) + storage_instance_queryset = StorageInstance.objects.filter(**validate_data) + proxy_instance_queryset = ProxyInstance.objects.filter(**validate_data) + # 统计每种 cluster_type 的数量 + cluster_type_counts = list(cluster_queryset.values("cluster_type").annotate(count=Count("cluster_type"))) + storage_type_counts = list( + storage_instance_queryset.values("cluster_type").annotate(count=Count("cluster_type")) + ) + proxy_type_counts = list(proxy_instance_queryset.values("cluster_type").annotate(count=Count("cluster_type"))) + + # 将列表转化为字典以便处理 + def list_to_dict(type_counts): + return {entry["cluster_type"]: entry["count"] for entry in type_counts} + + # 转换为字典 + cluster_type_dict = list_to_dict(cluster_type_counts) + storage_type_dict = list_to_dict(storage_type_counts) + proxy_type_dict = list_to_dict(proxy_type_counts) + + # 合并 storage 和 proxy 的类型计数 + instance_count_dict = defaultdict(int) + for cluster_type, count in storage_type_dict.items(): + instance_count_dict[cluster_type] += count + for cluster_type, count in proxy_type_dict.items(): + instance_count_dict[cluster_type] += count + + # 计算 Redis 相关类型的总计数 + redis_cluster_count = 0 + redis_instance_count = 0 + + redis_cluster_types = ClusterType.redis_cluster_types() + redis_cluster_types.remove(ClusterType.TendisRedisInstance) + + for cluster_type in redis_cluster_types: + redis_cluster_count += cluster_type_dict.get(cluster_type, 0) + redis_instance_count += instance_count_dict.get(cluster_type, 0) + + # 构建最终输出格式,包含所有 ClusterType 成员 + cluster_type_count_map = {} + for cluster_type in ClusterType: + if cluster_type.value not in redis_cluster_types: + cluster_count = cluster_type_dict.get(cluster_type.value, 0) + instance_count = instance_count_dict.get(cluster_type.value, 0) + cluster_type_count_map[cluster_type.value] = { + "cluster_count": cluster_count, + "instance_count": instance_count, + } + cluster_type_count_map["redis_cluster"] = { + "cluster_count": redis_cluster_count, + "instance_count": redis_instance_count, + } + + return Response(cluster_type_count_map)