删除资源组
This commit is contained in:
parent
6aab34a60a
commit
f0e780ae8f
39
.codex_tat_action.py
Normal file
39
.codex_tat_action.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.path.insert(0, "/Users/hy/Documents/hy/deploy-platform")
|
||||||
|
|
||||||
|
from deploy.tencent_tat.hyapp_tat_deploy import build_tat_client, run_tat_shell
|
||||||
|
|
||||||
|
|
||||||
|
with open(
|
||||||
|
"/Users/hy/Documents/环境/haiyi腾讯云临时服务器秘钥.csv",
|
||||||
|
encoding="utf-8-sig",
|
||||||
|
newline="",
|
||||||
|
) as handle:
|
||||||
|
credential = next(csv.DictReader(handle))
|
||||||
|
|
||||||
|
os.environ["TENCENTCLOUD_SECRET_ID"] = credential["SecretId"].strip()
|
||||||
|
os.environ["TENCENTCLOUD_SECRET_KEY"] = credential["SecretKey"].strip()
|
||||||
|
os.environ["TENCENTCLOUD_REGION"] = "me-saudi-arabia"
|
||||||
|
|
||||||
|
client = build_tat_client({"region": "me-saudi-arabia"})
|
||||||
|
script = r'''set -euo pipefail
|
||||||
|
hostname
|
||||||
|
docker system df
|
||||||
|
du -sh /opt/deploy/sources/hyapp-server /var/lib/docker 2>/dev/null || true
|
||||||
|
docker images --format '{{.Repository}}:{{.Tag}} {{.ID}} {{.Size}} {{.CreatedSince}}' | grep 'hyapp/admin-server' | head -n 10 || true
|
||||||
|
'''
|
||||||
|
|
||||||
|
result = run_tat_shell(
|
||||||
|
client,
|
||||||
|
instance_id="ins-ntmpcd3a",
|
||||||
|
script=script,
|
||||||
|
command_name="codex-admin-server-disk-precheck",
|
||||||
|
timeout_seconds=60,
|
||||||
|
poll_seconds=2,
|
||||||
|
)
|
||||||
|
print(result.get("status"))
|
||||||
|
print(result.get("output", ""))
|
||||||
@ -484,6 +484,28 @@ func (h *Handler) UpdateResourceGroup(c *gin.Context) {
|
|||||||
response.OK(c, group)
|
response.OK(c, group)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) DeleteResourceGroup(c *gin.Context) {
|
||||||
|
groupID, ok := parseID(c, "group_id")
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 删除资源组只关闭后续查询与发放入口,历史发放记录和已固化快照仍需保留用于审计与补偿。
|
||||||
|
resp, err := h.wallet.SetResourceGroupStatus(c.Request.Context(), &walletv1.SetResourceGroupStatusRequest{
|
||||||
|
RequestId: middleware.CurrentRequestID(c),
|
||||||
|
AppCode: appctx.FromContext(c.Request.Context()),
|
||||||
|
GroupId: groupID,
|
||||||
|
Status: "deleted",
|
||||||
|
OperatorUserId: actorID(c),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
response.BadRequest(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
group := resourceGroupFromProto(resp.GetGroup())
|
||||||
|
h.auditLog(c, "delete-resource-group", "resource_groups", fmt.Sprintf("%d", group.GroupID), "success", group.GroupCode)
|
||||||
|
response.OK(c, group)
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handler) EnableResourceGroup(c *gin.Context) {
|
func (h *Handler) EnableResourceGroup(c *gin.Context) {
|
||||||
h.setResourceGroupStatus(c, "active")
|
h.setResourceGroupStatus(c, "active")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,6 +31,7 @@ func RegisterRoutes(protected *gin.RouterGroup, h *Handler) {
|
|||||||
protected.PUT("/admin/resource-groups/identity-auto-grant-config", middleware.RequirePermission("resource-group:update"), h.UpdateResourceIdentityAutoGrantConfig)
|
protected.PUT("/admin/resource-groups/identity-auto-grant-config", middleware.RequirePermission("resource-group:update"), h.UpdateResourceIdentityAutoGrantConfig)
|
||||||
protected.GET("/admin/resource-groups/:group_id", middleware.RequirePermission("resource-group:view"), h.GetResourceGroup)
|
protected.GET("/admin/resource-groups/:group_id", middleware.RequirePermission("resource-group:view"), h.GetResourceGroup)
|
||||||
protected.PUT("/admin/resource-groups/:group_id", middleware.RequirePermission("resource-group:update"), h.UpdateResourceGroup)
|
protected.PUT("/admin/resource-groups/:group_id", middleware.RequirePermission("resource-group:update"), h.UpdateResourceGroup)
|
||||||
|
protected.DELETE("/admin/resource-groups/:group_id", middleware.RequirePermission("resource-group:delete"), h.DeleteResourceGroup)
|
||||||
protected.PUT("/admin/resource-groups/:group_id/items", middleware.RequirePermission("resource-group:update"), h.UpdateResourceGroup)
|
protected.PUT("/admin/resource-groups/:group_id/items", middleware.RequirePermission("resource-group:update"), h.UpdateResourceGroup)
|
||||||
protected.POST("/admin/resource-groups/:group_id/enable", middleware.RequirePermission("resource-group:update"), h.EnableResourceGroup)
|
protected.POST("/admin/resource-groups/:group_id/enable", middleware.RequirePermission("resource-group:update"), h.EnableResourceGroup)
|
||||||
protected.POST("/admin/resource-groups/:group_id/disable", middleware.RequirePermission("resource-group:update"), h.DisableResourceGroup)
|
protected.POST("/admin/resource-groups/:group_id/disable", middleware.RequirePermission("resource-group:update"), h.DisableResourceGroup)
|
||||||
|
|||||||
@ -96,7 +96,7 @@ var (
|
|||||||
}
|
}
|
||||||
resourceManage = []string{
|
resourceManage = []string{
|
||||||
"resource:create", "resource:update", "resource:delete", "upload:create",
|
"resource:create", "resource:update", "resource:delete", "upload:create",
|
||||||
"resource-shop:update", "resource-group:create", "resource-group:update",
|
"resource-shop:update", "resource-group:create", "resource-group:update", "resource-group:delete",
|
||||||
"gift:create", "gift:update", "gift:status", "gift:delete",
|
"gift:create", "gift:update", "gift:status", "gift:delete",
|
||||||
"resource-grant:create", "resource-grant:revoke", "emoji-pack:create",
|
"resource-grant:create", "resource-grant:revoke", "emoji-pack:create",
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,6 +69,7 @@ var defaultPermissions = []model.Permission{
|
|||||||
{Name: "资源组查看", Code: "resource-group:view", Kind: "menu"},
|
{Name: "资源组查看", Code: "resource-group:view", Kind: "menu"},
|
||||||
{Name: "资源组创建", Code: "resource-group:create", Kind: "button"},
|
{Name: "资源组创建", Code: "resource-group:create", Kind: "button"},
|
||||||
{Name: "资源组更新", Code: "resource-group:update", Kind: "button"},
|
{Name: "资源组更新", Code: "resource-group:update", Kind: "button"},
|
||||||
|
{Name: "资源组删除", Code: "resource-group:delete", Kind: "button"},
|
||||||
{Name: "资源赠送查看", Code: "resource-grant:view", Kind: "menu"},
|
{Name: "资源赠送查看", Code: "resource-grant:view", Kind: "menu"},
|
||||||
{Name: "资源赠送创建", Code: "resource-grant:create", Kind: "button"},
|
{Name: "资源赠送创建", Code: "resource-grant:create", Kind: "button"},
|
||||||
{Name: "资源赠送撤销", Code: "resource-grant:revoke", Kind: "button"},
|
{Name: "资源赠送撤销", Code: "resource-grant:revoke", Kind: "button"},
|
||||||
|
|||||||
@ -112,7 +112,7 @@ WHERE role.code = 'ops-admin'
|
|||||||
'room-robot:view', 'room-robot:create', 'room-robot:update',
|
'room-robot:view', 'room-robot:create', 'room-robot:update',
|
||||||
'app-config:view', 'app-config:update', 'full-server-notice:send',
|
'app-config:view', 'app-config:update', 'full-server-notice:send',
|
||||||
'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create',
|
'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create',
|
||||||
'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update',
|
'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update', 'resource-group:delete',
|
||||||
'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete',
|
'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete',
|
||||||
'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create',
|
'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create',
|
||||||
'coin-ledger:view', 'coin-seller-ledger:view', 'coin-adjustment:view', 'coin-adjustment:create', 'report:view',
|
'coin-ledger:view', 'coin-seller-ledger:view', 'coin-adjustment:view', 'coin-adjustment:create', 'report:view',
|
||||||
@ -159,7 +159,7 @@ WHERE role.code = 'operations-specialist'
|
|||||||
'room-robot:view', 'room-robot:create', 'room-robot:update',
|
'room-robot:view', 'room-robot:create', 'room-robot:update',
|
||||||
'app-config:view', 'app-config:update', 'full-server-notice:send',
|
'app-config:view', 'app-config:update', 'full-server-notice:send',
|
||||||
'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create',
|
'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create',
|
||||||
'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update',
|
'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update', 'resource-group:delete',
|
||||||
'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete',
|
'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete',
|
||||||
'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create',
|
'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create',
|
||||||
'coin-ledger:view', 'coin-seller-ledger:view', 'report:view',
|
'coin-ledger:view', 'coin-seller-ledger:view', 'report:view',
|
||||||
@ -191,7 +191,7 @@ WHERE role.code = 'product-lead'
|
|||||||
'app-config:view', 'app-config:update', 'app-version:view', 'app-version:create', 'app-version:update', 'app-version:delete',
|
'app-config:view', 'app-config:update', 'app-version:view', 'app-version:create', 'app-version:update', 'app-version:delete',
|
||||||
'full-server-notice:view', 'full-server-notice:send',
|
'full-server-notice:view', 'full-server-notice:send',
|
||||||
'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create',
|
'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create',
|
||||||
'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update',
|
'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update', 'resource-group:delete',
|
||||||
'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete',
|
'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete',
|
||||||
'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create',
|
'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create',
|
||||||
'coin-ledger:view', 'coin-seller-ledger:view', 'report:view', 'gift-diamond:view', 'gift-diamond:update',
|
'coin-ledger:view', 'coin-seller-ledger:view', 'report:view', 'gift-diamond:view', 'gift-diamond:update',
|
||||||
@ -224,7 +224,7 @@ WHERE role.code = 'product-specialist'
|
|||||||
'room:view', 'room-pin:view', 'room-config:view', 'room-whitelist:view', 'room-robot:view', 'room-robot:create', 'room-robot:update',
|
'room:view', 'room-pin:view', 'room-config:view', 'room-whitelist:view', 'room-robot:view', 'room-robot:create', 'room-robot:update',
|
||||||
'app-config:view', 'app-version:view', 'full-server-notice:view',
|
'app-config:view', 'app-version:view', 'full-server-notice:view',
|
||||||
'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create',
|
'resource:view', 'resource:create', 'resource:update', 'resource:delete', 'upload:create',
|
||||||
'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update',
|
'resource-shop:view', 'resource-shop:update', 'resource-group:view', 'resource-group:create', 'resource-group:update', 'resource-group:delete',
|
||||||
'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete',
|
'gift:view', 'gift:create', 'gift:update', 'gift:status', 'gift:delete',
|
||||||
'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create',
|
'resource-grant:view', 'resource-grant:create', 'resource-grant:revoke', 'emoji-pack:view', 'emoji-pack:create',
|
||||||
'coin-ledger:view', 'coin-seller-ledger:view', 'report:view',
|
'coin-ledger:view', 'coin-seller-ledger:view', 'report:view',
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
SET @now_ms = CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED);
|
||||||
|
|
||||||
|
INSERT INTO admin_permissions (name, code, kind, description, created_at_ms, updated_at_ms) VALUES
|
||||||
|
('资源组删除', 'resource-group:delete', 'button', '', @now_ms, @now_ms)
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
name = VALUES(name),
|
||||||
|
kind = VALUES(kind),
|
||||||
|
description = VALUES(description),
|
||||||
|
updated_at_ms = @now_ms;
|
||||||
|
|
||||||
|
INSERT IGNORE INTO admin_role_permissions (role_id, permission_id)
|
||||||
|
SELECT admin_role.id, admin_permission.id
|
||||||
|
FROM admin_roles admin_role
|
||||||
|
JOIN admin_permissions admin_permission
|
||||||
|
WHERE admin_role.code IN ('platform-admin', 'ops-admin', 'operations-specialist', 'product-lead', 'product-specialist')
|
||||||
|
AND admin_permission.code = 'resource-group:delete';
|
||||||
@ -183,7 +183,8 @@ func (r *Repository) SetResourceGroupStatus(ctx context.Context, command resourc
|
|||||||
}
|
}
|
||||||
ctx = contextWithCommandApp(ctx, command.AppCode)
|
ctx = contextWithCommandApp(ctx, command.AppCode)
|
||||||
command.Status = resourcedomain.NormalizeStatus(command.Status)
|
command.Status = resourcedomain.NormalizeStatus(command.Status)
|
||||||
if !resourcedomain.ValidStatus(command.Status) {
|
// deleted 仅供受独立删除权限保护的管理端入口使用;创建、编辑仍只接受 active/disabled。
|
||||||
|
if !resourcedomain.ValidStatus(command.Status) && command.Status != resourcedomain.StatusDeleted {
|
||||||
return resourcedomain.ResourceGroup{}, xerr.New(xerr.InvalidArgument, "status is invalid")
|
return resourcedomain.ResourceGroup{}, xerr.New(xerr.InvalidArgument, "status is invalid")
|
||||||
}
|
}
|
||||||
tx, err := r.db.BeginTx(ctx, nil)
|
tx, err := r.db.BeginTx(ctx, nil)
|
||||||
@ -468,7 +469,8 @@ func scanResourceGroupItem(scanner scanTarget) (resourcedomain.ResourceGroupItem
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resourceGroupWhereSQL(query resourcedomain.ListResourceGroupsQuery) (string, []any) {
|
func resourceGroupWhereSQL(query resourcedomain.ListResourceGroupsQuery) (string, []any) {
|
||||||
where := `WHERE app_code = ?`
|
// 软删除行保留给历史发放、快照和审计链路,任何资源组列表都不能重新暴露这些行。
|
||||||
|
where := `WHERE app_code = ? AND status <> 'deleted'`
|
||||||
args := []any{query.AppCode}
|
args := []any{query.AppCode}
|
||||||
if query.ActiveOnly {
|
if query.ActiveOnly {
|
||||||
where += ` AND status = 'active'`
|
where += ` AND status = 'active'`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user