- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
本文基于 bk-cmdb 官方 API 文档 delete_dynamic_group.md 展开,围绕动态分组(Dynamic Group)删除接口,完整覆盖接口参数、请求/响应示例、错误处理,并结合仓库源码剖析 host_server → coreservice → MongoDB 的完整调用链、权限解析与审计日志机制,帮助读者在真实环境中安全、准确地删除业务下的动态分组。
一、接口概述:删除动态分组的用途与适用前提
动态分组(Dynamic Group)是蓝鲸配置平台(BlueKing CMDB)中基于host/set对象字段条件(如$eq、$ne、$in、$regex等)自动圈定资源集合的一种分组机制。当某个动态分组不再需要时,即可通过本文介绍的delete_dynamic_group接口将其从系统中删除。
| 项目 | 说明 |
|---|---|
| 接口名称 | delete_dynamic_group(删除动态分组) |
| 引入版本 | v3.9.6+ |
| 所需权限 | 动态分组删除权限 |
| 请求方式 | HTTP DELETE(ESB 网关封装) |
| 所属模块 | host_server(动态分组功能归属主机服务) |
需要特别说明的是,该接口只删除"动态分组"这个条件定义本身,不会删除其圈定范围内的主机或集群实例,被圈定的资源不受任何影响。
二、请求参数详解
该接口同时包含 ESB 网关层公共参数与业务层接口参数两部分。
2.1 公共参数(common_args_desc)
所有蓝鲸 ESB 网关接口均需携带以下公共参数,用于认证与身份识别:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| bk_app_code | string | 是 | 应用 ID(开发者中心创建的应用标识) |
| bk_app_secret | string | 是 | 应用密钥,用于应用认证 |
| bk_username | string | 是 | 操作者用户名 |
| bk_token | string | 是 | 登录票据,与 bk_username 配合完成用户身份校验 |
2.2 接口参数
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
| bk_biz_id | int | 是 | 业务 ID,指明动态分组所属的业务 |
| id | string | 是 | 动态分组主键 ID |
其中id由创建接口返回(见 create_dynamic_group.md 的响应data.id),是一个 UUID 字符串。从源码看,该 ID 由NewDynamicGroupID()通过github.com/google/uuid生成(src/common/metadata/dynamic_grouping.go#L470-L477),可通过查询接口获取。
三、请求示例与完整调用方式
3.1 标准请求示例(ESB 网关)
官方文档给出的完整请求参数示例:
{ "bk_app_code": "esb_test", "bk_app_secret": "xxx", "bk_username": "xxx", "bk_token": "xxx", "bk_biz_id": 1, "id": "XXXXXXXX" }3.2 底层 REST 调用方式
该接口在 ESB 网关之上封装,实际落到 CMDB 的 REST 路径为:
DELETE /api/v3/dynamicgroup/{bk_biz_id}/{id}这一路径可由权限解析源码佐证。在 src/ac/parser/host.go#L81 中,删除动态分组的正则定义为:
deleteDynamicGroupRegexp = regexp.MustCompile(`^/api/v3/dynamicgroup/[0-9]+/[^\s/]+/?$`)因此,bk_biz_id必须为纯数字,id为非空字符串(UUID)。对应的 curl 调用示意如下:
curl -X DELETE 'http://{cmdb_host}/api/v3/dynamicgroup/1/XXXXXXXX' \ -H 'Content-Type: application/json' \ -H 'X-Bk-Username: admin'提示:直接调用 CMDB 原生 REST 接口时需要携带鉴权头(如
X-Bk-Username等);经由 ESB 网关调用时则使用bk_app_code/bk_app_secret/bk_token公共参数完成认证。
四、响应示例与响应字段说明
4.1 成功响应示例
{ "result": true, "code": 0, "message": "success", "permission": null, "request_id": "e43da4ef221746868dc4c837d36f3807", "data": null }4.2 响应字段说明
| 字段 | 类型 | 描述 |
|---|---|---|
| result | bool | 请求是否成功。true:成功;false:失败 |
| code | int | 错误码。0 表示成功,>0 表示失败错误码 |
| message | string | 失败时返回的错误信息 |
| permission | object | 权限信息(无权限时会携带具体权限描述) |
| request_id | string | 请求链 ID,用于链路追踪定位问题 |
| data | object | 请求返回数据,删除接口成功后为 null |
删除成功后data为null,即无需返回被删除对象的详情——需要保留原始数据应在删除前通过查询接口预取。
五、源码级解析:删除动态分组的完整调用链
理解底层实现有助于排查"删除失败""权限不足"等实际问题。以下是删除动作在仓库中的完整链路。
5.1 路由注册与入口
在 src/scene_server/host_server/service/service_initfunc.go#L350-L355 中,删除动态分组的路由注册为:
// delete target dynamic group. utility.AddHandler(rest.Action{ Verb: http.MethodDelete, Path: "/dynamicgroup/{bk_biz_id}/{id}", Handler: s.DeleteDynamicGroup, })即 HTTP DELETE 方法 +/dynamicgroup/{bk_biz_id}/{id}路径,处理函数为 host_server 的DeleteDynamicGroup(src/scene_server/host_server/service/dynamic_grouping.go#L284-L345)。
5.2 host_server 层:预查询 + 事务 + 审计
从 src/scene_server/host_server/service/dynamic_grouping.go 的实现可以看到删除动作的三段式设计:
- 路径参数解析:从请求路径中取出
bk_biz_id与id(req.PathParameter); - 删除前预查询:先调用
CoreService().Host().GetDynamicGroup读取目标动态分组完整对象,供后续生成审计日志使用。若查询失败(HTTP 错误或业务错误码),立即返回错误,不继续执行删除; - 事务内执行删除:将"真正删除 + 生成审计日志 + 保存审计日志"整体封装进
AutoRunTxn事务回调函数:
autoRunTxnFunc := func() error { result, err := s.CoreAPI.CoreService().Host().DeleteDynamicGroup(ctx.Kit.Ctx, bizID, targetID, ctx.Kit.Header) ... audit := auditlog.NewDynamicGroupAuditLog(s.CoreAPI.CoreService()) auditParam := auditlog.NewGenerateAuditCommonParameter(ctx.Kit, meta.AuditDelete) auditLogs, err := audit.GenerateAuditLog(auditParam, &dynamicGroup) ... if err := audit.SaveAuditLog(ctx.Kit, auditLogs...); err != nil { ... } return nil } if err := s.Engine.CoreAPI.CoreService().Txn().AutoRunTxn(ctx.Kit.Ctx, ctx.Kit.Header, autoRunTxnFunc); err != nil { ctx.RespAutoError(err) return } ctx.RespEntity(nil)这种设计保证了:数据删除与审计日志写入要么同时成功、要么同时回滚,避免出现"删了记录却丢了审计"的不一致状态。
5.3 coreservice 层:存量校验与数据库删除
真正落库的动作在 coreservice 的 DeleteDynamicGroup:
- 将路径中的
bk_biz_id解析为 int64,解析失败返回参数非法错误(CCErrCommParamsIsInvalid); - 以
{id, bk_biz_id}为过滤条件查询cc_DynamicGroup表,校验目标记录恰好存在 1 条(rowCount != 1时返回"记录不存在或无权限"错误CCErrCommNotFound)——这个双重条件意味着id与bk_biz_id必须配对正确,跨业务的id无法删除; - 删除成功后返回空响应,失败则返回数据库删除错误(
CCErrCommDBDeleteFailed)。
数据表名cc_DynamicGroup定义在 src/common/tablenames.go#L70。
5.4 权限解析:动态分组删除权限
删除请求到达 host_server 前,会先经过 IAM 权限解析。在 src/ac/parser/host.go#L134-L155 中:
if ps.hitRegexp(deleteDynamicGroupRegexp, http.MethodDelete) { ... ps.Attribute.Resources = []meta.ResourceAttribute{ { BusinessID: bizID, Basic: meta.Basic{ Type: meta.DynamicGrouping, Action: meta.Delete, InstanceIDEx: ps.RequestCtx.Elements[4], }, }, } return ps }即解析器会提取请求中的bizID与动态分组id(InstanceIDEx),构建"业务 + 动态分组 + 删除"的资源属性,交给权限中心校验用户是否具备对应实例的删除权限。因此:
- 无权限时会返回
permission信息(响应中的permission字段即由此产生),前端/调用方可根据该字段引导授权; - 权限校验发生在业务维度,跨业务删除同样会被拦截。
5.5 审计日志:删除动作可追溯
删除成功后生成的审计日志由 src/common/auditlog/dynamic_grouping.go#L38-L81 的GenerateAuditLog产出,审计类型为dynamic_grouping、资源类型为dynamic_group(定义见 src/common/metadata/audit.go#L647-L648 与 #L686-L687),记录内容包括:动态分组 ID、名称、所属业务、目标对象类型bk_obj_id、条件info、创建人/修改人、创建时间与最后修改时间,动作标识为AuditDelete。
5.6 相关场景:删除业务时级联清理动态分组
除显式调用本接口外,在删除整个业务时,CMDB 也会级联清理该业务下的动态分组。见 src/scene_server/topo_server/logics/inst/del_business.go#L256:删除业务逻辑内部同样调用了CoreService().Host().DeleteDynamicGroup。也就是说,动态分组并不存在独立的"回收站"恢复机制,删除后如需重建,只能重新调用创建接口并携带原条件。
六、使用注意事项与常见问题
- id 必须与 bk_biz_id 配对:底层以
{id, bk_biz_id}组合条件校验,传入不属于该业务的分组 ID 会得到"记录不存在"错误(code对应CCErrCommNotFound)。 - 删除不可恢复:接口直接物理删除 MongoDB 中的
cc_DynamicGroup记录,不提供回收站;依赖审计日志中的info条件内容可在删除后重建。 - 权限要求:调用方需具备对应业务的"动态分组删除权限",否则响应中的
result为false、permission非空。 - 幂等语义:对已删除的分组再次发起删除,会因存量校验失败返回错误码而非静默成功,调用方可据此判断分组状态。
- 不影响实例:删除动态分组仅移除分组定义,其圈定的主机/集群实例全部保留。
- 错误排查:响应中的
request_id可用于串联 host_server、coreservice 日志(源码中以rid字段贯穿打印),结合 dynamic_grouping.go 与 src/source_controller/coreservice/service/dynamic_grouping.go 中的错误日志快速定位。
七、与其他动态分组接口的关系
| 接口文档 | 作用 | 与删除接口的关系 |
|---|---|---|
| create_dynamic_group.md | 创建动态分组 | 其响应中的data.id即本接口所需的id参数 |
| update_dynamic_group.md | 修改动态分组定义 | 删除与修改共用同一套条件校验模型 |
| search_dynamic_group.md | 查询/列举动态分组 | 可用于删除前确认分组存在性与id |
动态分组全生命周期(创建 → 查询 → 更新 → 删除)围绕 src/common/metadata/dynamic_grouping.go 中定义的DynamicGroup数据结构展开,其中条件操作符白名单($eq/$ne/$in/$nin/$lte/$gte/$regex等,见该文件 L34-L55)在创建与更新时统一校验,删除接口本身不涉及条件校验,仅按主键定位。
综上,delete_dynamic_group 是一个典型的"按主键删除"类管理接口,理解其"预查询 + 事务删除 + 审计落库"的实现模式,以及权限解析与业务归属校验规则,即可在自动化脚本、运维平台集成等场景中安全使用。
- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
相关推荐
蓝鲸配置平台(bk-cmdb)删除动态分组 API 接口详解与实战指南
蓝鲸配置平台(bk cmdb)删除动态分组 API 接口详解与实战指南 导读 本文以蓝鲸智云配置平台(bk cmdb)的 删除动态分组 开放接口( delete
后端企业应用运维蓝鲸 CMDB 管控区域删除接口 delete_cloud_area 详解:API 规范与源码实现
蓝鲸 CMDB 管控区域删除接口 delete_cloud_area 详解:API 规范与源码实现 导读 本文围绕蓝鲸智云配置平台(BlueKing CMDB)
后端企业应用运维蓝鲸 CMDB 批量删除 Kubernetes Pod 接口详解:参数、调用链与源码实现
蓝鲸 CMDB 批量删除 Kubernetes Pod 接口详解:参数、调用链与源码实现 导读 本文围绕蓝鲸智云配置平台(BlueKing CMDB,bk cm
后端企业应用运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考