From 0427b87412c7bccde5412df79d7e24756fe3a183 Mon Sep 17 00:00:00 2001 From: opsx Date: Mon, 26 Oct 2026 18:30:47 +0000 Subject: [PATCH] =?UTF-8?q?fix(instance):=20access=5Fmode=20=E5=80=BC=20re?= =?UTF-8?q?ad/readonly=20=E4=B8=8D=E4=B8=80=E8=87=B4=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E3=80=8C=E8=AF=BB=E3=80=8D=E5=AE=9E=E4=BE=8B=E8=A2=AB=E8=BF=87?= =?UTF-8?q?=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:instance-groups 里给 MySQL 实例授予「只读查询」权限后, /queries 页面仍然选不到该实例,admin 也无法访问。 根因(枚举值前后端不一致): 前端 CreateInstanceForm「读」按钮写入 access_mode = "read" 后端 AccessibleInstances 只匹配 ["readwrite", "readonly"] → "read" 永远不命中,选了「读」的实例(MySQL)被过滤掉; Redis 实例是 "readwrite" 所以恰好能查,掩盖了该 bug。 修复:后端 readonly 过滤增加 "read",兼容两种历史写法: []string{"readwrite", "readonly", "read"} 写过滤仍为 ["readwrite", "write"]("read" 实例正确地不能写) 验证(admin): GET /instances/accessible?access_type=readonly → 5 个(含 MySQL id=5, access_mode=read) GET /instances/accessible?access_type=write → 4 个(MySQL 正确排除) 镜像:lghost/opsxsql:latest + v0.1 = sha256:6b1a7121da71 --- backend/internal/handler/instance_extra.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/internal/handler/instance_extra.go b/backend/internal/handler/instance_extra.go index 5c009ce..c359ef5 100644 --- a/backend/internal/handler/instance_extra.go +++ b/backend/internal/handler/instance_extra.go @@ -20,8 +20,12 @@ func AccessibleInstances(c *gin.Context) { if role == "admin" || role == "dba" { // admin/dba see all instances, filter by access_mode if needed query := model.DB.Order("id") + // 注意:access_mode 存在两种历史写法—— + // 前端「读」按钮写入 "read"(CreateInstanceForm), + // 另有 "readonly" 的历史值。两者都必须命中,否则选了「读」的实例 + // (尤其 MySQL)会被过滤掉,连 admin 都查不到。 if accessType == "readonly" { - query = query.Where("access_mode IN ? OR access_mode IS NULL", []string{"readwrite", "readonly"}) + query = query.Where("access_mode IN ? OR access_mode IS NULL", []string{"readwrite", "readonly", "read"}) } else { query = query.Where("access_mode IN ? OR access_mode IS NULL", []string{"readwrite", "write"}) }