Skip to content

Commit 9da5dc2

Browse files
committed
feat(other): 新增根ip查询集群信息mcp-tool #16445
1 parent 4e7aea6 commit 9da5dc2

File tree

4 files changed

+127
-2
lines changed

4 files changed

+127
-2
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ package-lock.json
2222
.cursorrules
2323
.cursor/
2424
# Claude
25+
CLAUDE.md
2526
.claude/
2627
.history/
2728
dbm-services/.history/
2829
dbm-ui/.history/
2930
# trellis
30-
.trellis
31+
.trellis
32+
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
4+
Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved.
5+
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at https://opensource.org/licenses/MIT
7+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
specific language governing permissions and limitations under the License.
10+
"""
11+
from typing import List
12+
13+
from backend.db_meta.enums import ClusterType
14+
from backend.db_meta.models import Machine, ProxyInstance, StorageInstance
15+
16+
17+
def query_cluster_by_ip(ip_list: List[str], bk_cloud_id: int = 0) -> List[dict]:
18+
"""根据 IP 列表查询关联的集群信息"""
19+
machines = Machine.objects.filter(ip__in=ip_list, bk_cloud_id=bk_cloud_id)
20+
machine_map = {m.ip: m for m in machines}
21+
22+
results = []
23+
seen = set()
24+
25+
for ip in ip_list:
26+
machine = machine_map.get(ip)
27+
if not machine:
28+
continue
29+
30+
for inst in StorageInstance.objects.filter(machine=machine).prefetch_related("cluster"):
31+
for cluster in inst.cluster.all():
32+
key = (ip, cluster.id)
33+
if key in seen:
34+
continue
35+
seen.add(key)
36+
results.append(
37+
{
38+
"ip": ip,
39+
"cluster_id": cluster.id,
40+
"cluster_domain": cluster.immute_domain,
41+
"cluster_type": cluster.cluster_type,
42+
"db_type": ClusterType.cluster_type_to_db_type(cluster.cluster_type),
43+
"machine_type": machine.machine_type,
44+
"bk_sub_zone": machine.bk_sub_zone,
45+
"bk_sub_zone_id": machine.bk_sub_zone_id,
46+
"bk_city": machine.bk_city.bk_idc_city_name,
47+
}
48+
)
49+
50+
for inst in ProxyInstance.objects.filter(machine=machine).prefetch_related("cluster"):
51+
for cluster in inst.cluster.all():
52+
key = (ip, cluster.id)
53+
if key in seen:
54+
continue
55+
seen.add(key)
56+
results.append(
57+
{
58+
"ip": ip,
59+
"cluster_id": cluster.id,
60+
"cluster_domain": cluster.immute_domain,
61+
"cluster_type": cluster.cluster_type,
62+
"db_type": ClusterType.cluster_type_to_db_type(cluster.cluster_type),
63+
"machine_type": machine.machine_type,
64+
"bk_sub_zone": machine.bk_sub_zone,
65+
"bk_sub_zone_id": machine.bk_sub_zone_id,
66+
"bk_city": machine.bk_city.bk_idc_city_name,
67+
}
68+
)
69+
70+
return results
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
4+
Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved.
5+
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at https://opensource.org/licenses/MIT
7+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
specific language governing permissions and limitations under the License.
10+
"""
11+
from django.utils.translation import gettext_lazy as _
12+
from rest_framework import serializers
13+
14+
15+
class QueryClusterByIpInputSerializer(serializers.Serializer):
16+
ip_list = serializers.ListField(child=serializers.CharField(), help_text=_("主机 IP 列表"))
17+
bk_cloud_id = serializers.IntegerField(help_text=_("云区域 ID"), required=False, default=0)
18+
19+
20+
class ClusterInfoByIpSerializer(serializers.Serializer):
21+
cluster_id = serializers.IntegerField(help_text=_("集群 ID"))
22+
cluster_domain = serializers.CharField(help_text=_("集群域名"))
23+
cluster_type = serializers.CharField(help_text=_("集群类型"))
24+
db_type = serializers.CharField(help_text=_("主机的 DB 类型"))
25+
machine_type = serializers.CharField(help_text=_("主机的机器类型"))
26+
ip = serializers.CharField(help_text=_("主机 IP"))
27+
bk_sub_zone = serializers.CharField(help_text=_("子 Zone"), allow_null=True)
28+
bk_sub_zone_id = serializers.IntegerField(help_text=_("子 Zone ID"))
29+
bk_city = serializers.CharField(help_text=_("IDC 城市名"))
30+
31+
32+
class QueryClusterByIpOutputSerializer(serializers.Serializer):
33+
clusters = serializers.ListSerializer(child=ClusterInfoByIpSerializer(), help_text=_("集群信息列表"))

dbm-ui/backend/dbm_aiagent/mcp_tools/mysql/views/mysql_query_mcp.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
)
2626
from backend.dbm_aiagent.mcp_tools.mysql.impl.cluster_topo import mysql_cluster_topo
2727
from backend.dbm_aiagent.mcp_tools.mysql.impl.explain_sql import explain_sql
28+
from backend.dbm_aiagent.mcp_tools.mysql.impl.query_cluster_by_ip import query_cluster_by_ip
2829
from backend.dbm_aiagent.mcp_tools.mysql.impl.show_create_table import show_create_table
2930
from backend.dbm_aiagent.mcp_tools.mysql.impl.show_priv_template import show_biz_mysql_privilege_template
3031
from backend.dbm_aiagent.mcp_tools.mysql.impl.show_processlist import show_cluster_processlist_summary
@@ -38,6 +39,10 @@
3839
ExplainSQLInputSerializer,
3940
ExplainSQLOutputSerializer,
4041
)
42+
from backend.dbm_aiagent.mcp_tools.mysql.serializers.query_cluster_by_ip import (
43+
QueryClusterByIpInputSerializer,
44+
QueryClusterByIpOutputSerializer,
45+
)
4146
from backend.dbm_aiagent.mcp_tools.mysql.serializers.show_create_table import (
4247
ShowCreateTableInputSerializer,
4348
ShowCreateTableOutputSerializer,
@@ -62,7 +67,7 @@
6267
from backend.dbm_aiagent.mcp_tools.mysql.serializers.usefully_choices import MySQLProcessListInstanceGroupType
6368
from backend.dbm_aiagent.mcp_tools.views import McpToolsViewSet
6469
from backend.iam_app.handlers.drf_perm.base import DBManagePermission
65-
from backend.iam_app.handlers.drf_perm.mcp import McpClusterManagePermission
70+
from backend.iam_app.handlers.drf_perm.mcp import McpClusterManagePermission, McpIsDbaPermission
6671

6772
logger = logging.getLogger("root")
6873

@@ -275,6 +280,21 @@ def show_biz_mysql_privilege_template(self, request, *args, **kwargs):
275280
}
276281
)
277282

283+
@mcp_tools_api_decorator(
284+
description=str(_("根据 IP 列表查询所属集群信息,返回集群域名、集群ID和主机DB类型,仅 DBA 可调用")),
285+
request_slz=QueryClusterByIpInputSerializer,
286+
response_slz=QueryClusterByIpOutputSerializer,
287+
permission_classes=[McpIsDbaPermission],
288+
tags=[DBMMCPTags.READ],
289+
mcp=[DBMMcpTools.MYSQL_QUERY],
290+
name_prefix="mysql_query",
291+
)
292+
def query_cluster_by_ip(self, request, *args, **kwargs):
293+
ip_list = self.get_param("ip_list")
294+
bk_cloud_id = self.get_param("bk_cloud_id")
295+
296+
return Response({"clusters": query_cluster_by_ip(ip_list=ip_list, bk_cloud_id=bk_cloud_id)})
297+
278298

279299
def _validate_and_get_machine(bk_cloud_id: int | None, address: str) -> Machine:
280300
"""验证并获取机器对象"""

0 commit comments

Comments
 (0)