From 53e71fe82f94ba44fc2b8bb5afd4f343b8fdb473 Mon Sep 17 00:00:00 2001
From: iSecloud <869820505@qq.com>
Date: Thu, 2 Jan 2025 15:50:28 +0800
Subject: [PATCH] =?UTF-8?q?fix(backend):=20=E5=8E=BB=E6=8E=89=E8=B6=85?=
 =?UTF-8?q?=E7=AE=A1=E5=AF=B9=E5=BE=85=E5=AE=A1=E6=89=B9=E3=80=81=E5=BE=85?=
 =?UTF-8?q?=E6=89=A7=E8=A1=8C=E7=9A=84=E7=A1=AE=E8=AE=A4=E6=9D=83=E9=99=90?=
 =?UTF-8?q?=20#8883?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 dbm-ui/backend/db_meta/enums/spec.py          | 67 -------------------
 .../backend/db_services/dbbase/serializers.py |  2 +-
 dbm-ui/backend/db_services/dbbase/views.py    |  9 ++-
 dbm-ui/backend/ticket/todos/__init__.py       |  7 +-
 dbm-ui/backend/ticket/todos/itsm_todo.py      |  5 ++
 dbm-ui/backend/ticket/todos/pause_todo.py     |  5 ++
 6 files changed, 25 insertions(+), 70 deletions(-)

diff --git a/dbm-ui/backend/db_meta/enums/spec.py b/dbm-ui/backend/db_meta/enums/spec.py
index b99a5a797f..1a0da044a0 100644
--- a/dbm-ui/backend/db_meta/enums/spec.py
+++ b/dbm-ui/backend/db_meta/enums/spec.py
@@ -54,70 +54,3 @@ class SpecMachineType(str, StructuredEnum):
     DORIS_FOLLOWER = EnumField("doris_follower", _("doris_follower"))
     DORIS_OBSERVER = EnumField("doris_observer", _("doris_observer"))
     DORIS_BACKEND = EnumField("doris_backend", _("doris_backend"))
-
-
-# TODO: 规格迁移脚本函数,迁移完成后删除
-def migrate_spec():
-    from django.db import transaction
-
-    from backend.configuration.constants import DBType
-    from backend.db_meta.enums import ClusterType, MachineType
-    from backend.db_meta.models.spec import Spec
-
-    # 原规格层级和新规格层级的映射
-    MIGRATE_SPEC_MACHINE_MAP = {
-        MachineType.SINGLE: SpecMachineType.BACKEND,
-        MachineType.BACKEND: SpecMachineType.BACKEND,
-        MachineType.PROXY: SpecMachineType.PROXY,
-        MachineType.SPIDER: SpecMachineType.PROXY,
-        MachineType.REMOTE: SpecMachineType.BACKEND,
-        ClusterType.TendisTwemproxyRedisInstance: {
-            MachineType.TENDISCACHE: SpecMachineType.TendisTwemproxyRedisInstance,
-            MachineType.TWEMPROXY: SpecMachineType.PROXY,
-        },
-        ClusterType.TwemproxyTendisSSDInstance: {
-            MachineType.TENDISSSD: SpecMachineType.TwemproxyTendisSSDInstance,
-            MachineType.TWEMPROXY: SpecMachineType.PROXY,
-        },
-        ClusterType.TendisPredixyTendisplusCluster: {
-            MachineType.TENDISPLUS: SpecMachineType.TendisPredixyTendisplusCluster,
-            MachineType.PREDIXY: SpecMachineType.PROXY,
-        },
-        ClusterType.TendisPredixyRedisCluster: {
-            MachineType.TENDISCACHE: SpecMachineType.TendisTwemproxyRedisInstance,
-            MachineType.PREDIXY: SpecMachineType.PROXY,
-        },
-        ClusterType.TendisRedisInstance: {
-            MachineType.TENDISCACHE: SpecMachineType.TendisTwemproxyRedisInstance,
-        },
-        MachineType.SQLSERVER_HA: SpecMachineType.SQLSERVER,
-        MachineType.SQLSERVER_SINGLE: SpecMachineType.SQLSERVER,
-        MachineType.MONGOS: SpecMachineType.MONGOS,
-        MachineType.MONGODB: SpecMachineType.MONGODB,
-        MachineType.MONOG_CONFIG: SpecMachineType.MONOG_CONFIG,
-    }
-
-    specs = Spec.objects.all()
-    with transaction.atomic():
-        for spec in specs:
-            db_type = ClusterType.cluster_type_to_db_type(spec.spec_cluster_type)
-            if db_type in [
-                DBType.Es,
-                DBType.Kafka,
-                DBType.Hdfs,
-                DBType.InfluxDB,
-                DBType.Pulsar,
-                DBType.Vm,
-                DBType.Doris,
-                DBType.Riak,
-            ]:
-                continue
-
-            if db_type == DBType.Redis:
-                spec.spec_machine_type = MIGRATE_SPEC_MACHINE_MAP[spec.spec_cluster_type][spec.spec_machine_type]
-                spec.spec_cluster_type = db_type
-                spec.save()
-            else:
-                spec.spec_machine_type = MIGRATE_SPEC_MACHINE_MAP[spec.spec_machine_type]
-                spec.spec_cluster_type = db_type
-                spec.save()
diff --git a/dbm-ui/backend/db_services/dbbase/serializers.py b/dbm-ui/backend/db_services/dbbase/serializers.py
index 96179c0475..68d14e01b9 100644
--- a/dbm-ui/backend/db_services/dbbase/serializers.py
+++ b/dbm-ui/backend/db_services/dbbase/serializers.py
@@ -205,7 +205,7 @@ class QueryClusterInstanceCountSerializer(serializers.Serializer):
 
 class QueryClusterCapSerializer(serializers.Serializer):
     bk_biz_id = serializers.IntegerField(help_text=_("业务ID"))
-    cluster_type = serializers.ChoiceField(help_text=_("集群类型"), choices=ClusterType.get_choices())
+    cluster_type = serializers.CharField(help_text=_("集群类型(多个以逗号分隔)"))
 
 
 class QueryClusterCapResponseSerializer(serializers.Serializer):
diff --git a/dbm-ui/backend/db_services/dbbase/views.py b/dbm-ui/backend/db_services/dbbase/views.py
index 7943920a11..f0ff3fa507 100644
--- a/dbm-ui/backend/db_services/dbbase/views.py
+++ b/dbm-ui/backend/db_services/dbbase/views.py
@@ -398,5 +398,12 @@ def query_cluster_stat(self, request, *args, **kwargs):
         from backend.db_periodic_task.local_tasks.db_meta.sync_cluster_stat import sync_cluster_stat_by_cluster_type
 
         data = self.params_validate(self.get_serializer_class())
-        cluster_stat_map = sync_cluster_stat_by_cluster_type(data["bk_biz_id"], data["cluster_type"])
+        cluster_stat_map = {}
+        for cluster_type in data["cluster_type"].split(","):
+            cluster_stat_map.update(sync_cluster_stat_by_cluster_type(data["bk_biz_id"], cluster_type))
+
+        cluster_domain_qs = Cluster.objects.filter(bk_biz_id=3).values("immute_domain", "id")
+        cluster_domain_map = {cluster["immute_domain"]: cluster["id"] for cluster in cluster_domain_qs}
+        cluster_stat_map = {cluster_domain_map[domain]: cap for domain, cap in cluster_stat_map.items()}
+
         return Response(cluster_stat_map)
diff --git a/dbm-ui/backend/ticket/todos/__init__.py b/dbm-ui/backend/ticket/todos/__init__.py
index 35412d6cc3..ad71f9d014 100644
--- a/dbm-ui/backend/ticket/todos/__init__.py
+++ b/dbm-ui/backend/ticket/todos/__init__.py
@@ -47,6 +47,11 @@ def update_context(self, params):
             self.todo.context.update(remark=params["remark"])
         self.todo.save(update_fields=["context"])
 
+    @property
+    def allow_superuser_process(self):
+        # 是否允许超管操作,默认允许.
+        return True
+
     def process(self, username, action, params):
         # 当状态已经被确认,则不允许重复操作
         if self.todo.status not in TODO_RUNNING_STATUS:
@@ -57,7 +62,7 @@ def process(self, username, action, params):
             self._process(username, action, params)
             return
         # 允许超级用户和操作人确认
-        is_superuser = User.objects.get(username=username).is_superuser
+        is_superuser = User.objects.get(username=username).is_superuser and self.allow_superuser_process
         if not is_superuser and username not in self.todo.operators:
             raise TodoWrongOperatorException(_("{}不在处理人: {}中,无法处理").format(username, self.todo.operators))
 
diff --git a/dbm-ui/backend/ticket/todos/itsm_todo.py b/dbm-ui/backend/ticket/todos/itsm_todo.py
index 931565595b..e0a4b514f9 100644
--- a/dbm-ui/backend/ticket/todos/itsm_todo.py
+++ b/dbm-ui/backend/ticket/todos/itsm_todo.py
@@ -28,6 +28,11 @@ class ItsmTodoContext(BaseTodoContext):
 class ItsmTodo(todos.TodoActor):
     """来自审批中的待办"""
 
+    @property
+    def allow_superuser_process(self):
+        # 单据未执行前(待审批、待执行时)超管不拥有特权。规避超管误点的风险
+        return False
+
     def process(self, username, action, params):
         # itsm的todo允许本人操作
         if username == self.todo.ticket.creator and self.todo.status in TODO_RUNNING_STATUS:
diff --git a/dbm-ui/backend/ticket/todos/pause_todo.py b/dbm-ui/backend/ticket/todos/pause_todo.py
index 2211bc6790..c8997558ef 100644
--- a/dbm-ui/backend/ticket/todos/pause_todo.py
+++ b/dbm-ui/backend/ticket/todos/pause_todo.py
@@ -32,6 +32,11 @@ class ResourceReplenishTodoContext(BaseTodoContext):
 class PauseTodo(todos.TodoActor):
     """来自主流程的待办"""
 
+    @property
+    def allow_superuser_process(self):
+        # 单据未执行前(待审批、待执行时)超管不拥有特权。规避超管误点的风险
+        return False
+
     def _process(self, username, action, params):
         """确认/终止"""
         if action == ActionType.TERMINATE: