- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
本文围绕蓝鲸智云配置平台(bk-cmdb)对外开放的批量删除项目接口(
batch_delete_project,内部路由/deletemany/project)展开,完整介绍其版本要求、权限前提、请求参数、调用与响应示例,并结合仓库源码剖析参数校验、事务删除与权限点定义等底层实现。读完本文,你将能够正确构造请求体完成项目批量删除,并在出错时依据错误码与源码快速定位原因。
一、接口概述:版本、权限与调用路径
批量删除项目接口用于一次性删除配置平台(CC)中的多个项目(Project)记录。根据接口文档 batch_delete_project.md 的说明,该接口具备以下约束:
| 约束项 | 说明 |
|---|---|
| 版本要求 | v3.10.23+ |
| 权限要求 | 需要“项目的删除权限”(项目删除) |
| 请求方法 | DELETE |
| 网关路径 | /api/v3/deletemany/project |
| 内部路由 | /deletemany/project |
在蓝鲸 API 网关的资源定义文件 bk_apigw_resources_bk-cmdb.yaml 中,该资源被标记为operationId: batch_delete_project、description: 批量删除项目,其后端以HTTP delete方式透传到 CMDB 内部路径/api/v3/deletemany/project。值得注意的是,该资源isPublic: false(非公共资源)、allowApplyPermission: true,意味着调用方需要申请并获得对应权限后才能调用。
二、请求参数说明
该接口仅有一个请求参数,全部参数均放在请求体中:
| 参数名称 | 参数类型 | 必选 | 描述 |
|---|---|---|---|
| ids | array | 是 | 项目在 CC 中的 id 唯一标识数组,一次请求最多传 200 个 |
请求体的 Go 结构体定义位于 src/common/metadata/toposerver.go:
// DeleteProjectOption delete project option type DeleteProjectOption struct { IDs []int64 `json:"ids"` }其中ids是int64类型的数组,对应配置平台内部为项目生成的数值型唯一标识(即项目实例的bk_inst_id)。结构体上还提供了Validate()校验方法,其校验规则与文档中的“一次最多 200 个”完全对应:
// Validate validate DeleteProjectOption func (p *DeleteProjectOption) Validate() ccErr.RawErrorInfo { if len(p.IDs) == 0 { return ccErr.RawErrorInfo{ ErrCode: common.CCErrCommParamsNeedSet, Args: []interface{}{"ids"}, } } if len(p.IDs) > common.BKWriteOpLimit { return ccErr.RawErrorInfo{ ErrCode: common.CCErrCommXXExceedLimit, Args: []interface{}{"ids", common.BKWriteOpLimit}, } } return ccErr.RawErrorInfo{} }可以看到源码中做了两道硬性校验:
ids为空数组时直接报错,错误码为CCErrCommParamsNeedSet(参数必填缺失);ids数量超过BKWriteOpLimit时报错,错误码为CCErrCommXXExceedLimit(参数超限)。
其中BKWriteOpLimit的取值在 src/common/definitions.go 中定义:
// BKWriteOpLimit default write operation limit BKWriteOpLimit = 200即单次批量写入/删除操作的默认上限为 200,这与文档“一次限制最大传 200 个”的说明完全吻合。
三、请求示例
3.1 请求体 JSON
{ "ids":[ 1, 2, 3 ] }即同时删除 id 为 1、2、3 的三个项目。
3.2 完整调用示例(curl)
通过蓝鲸 API 网关调用该接口时,典型的请求如下(请将示例中的网关地址与鉴权信息替换为你的实际部署值):
curl -X DELETE 'https://{apigw_host}/api/v3/deletemany/project' \ -H 'Content-Type: application/json' \ -H 'X-Bkapi-Authorization: {"bk_app_code":"{your_app_code}","bk_app_secret":"{your_app_secret}","bk_username":"{operator}"}' \ -d '{"ids":[1,2,3]}'四、响应示例与响应参数说明
4.1 响应示例
删除成功时,接口返回如下 JSON:
{ "result": true, "code": 0, "data": null, "message": "success", "permission": null, }4.2 响应参数说明
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| result | bool | 请求成功与否。true表示请求成功;false表示请求失败 |
| code | int | 错误编码。0表示成功,>0表示失败错误码 |
| message | string | 请求失败时返回的错误信息 |
| permission | object | 权限信息 |
| data | object | 请求返回的数据 |
关于响应结构,从源码层面可以进一步确认:
- 删除成功后
data恒为null。在处理器 project.go 中,删除成功分支直接调用ctx.RespEntity(nil)返回,不再携带任何数据。 - 响应的通用字段结构定义在 src/common/metadata/result.go 的
BaseResp中:
// BaseResp common result struct type BaseResp struct { Result bool `json:"result" bson:"result" mapstructure:"result"` Code int `json:"bk_error_code" bson:"bk_error_code" mapstructure:"bk_error_code"` ErrMsg string `json:"bk_error_msg" bson:"bk_error_msg" mapstructure:"bk_error_msg"` Permissions *IamPermission `json:"permission" bson:"permission" mapstructure:"permission"` }值得说明的是,底层 SDK 响应结构中成功/错误字段的 JSON 标签为bk_error_code与bk_error_msg,而本文档(及网关对外输出)以code、message命名呈现,调用方解析时应以实际网关返回的字段为准;permission字段对应 IAM 权限信息,在权限校验失败等场景下会被填充。
五、源码级实现原理:从路由注册到事务删除
5.1 路由注册
该接口的处理器在 src/scene_server/topo_server/service/project.go 中实现为Service.DeleteProject,路由注册位于 src/scene_server/topo_server/service/service_initfunc.go:
utility.AddHandler(rest.Action{Verb: http.MethodDelete, Path: "/deletemany/project", Handler: s.DeleteProject})即 HTTPDELETE方法 + 路径/deletemany/project。
5.2 处理器执行流程
DeleteProject处理器的完整逻辑如下(src/scene_server/topo_server/service/project.go#L154-L182):
- 请求体解码:将请求体反序列化为
metadata.DeleteProjectOption,解码失败直接返回错误; - 参数校验:调用
opt.Validate()执行上文所述的两道校验; - 事务执行:通过
s.Engine.CoreAPI.CoreService().Txn().AutoRunTxn(...)将删除操作包裹在事务中执行,保证删除过程的一致性; - 实际删除:在事务内调用
s.Logics.InstOperation().DeleteInstByInstID(ctx.Kit, common.BKInnerObjIDProject, opt.IDs, false),对BKInnerObjIDProject(项目对象)按 id 列表执行删除。
其中事务的使用意味着:批量删除多个项目时,若中间某个删除步骤失败,整个事务会回滚,避免出现“删了一半”的中间状态。
5.3 底层删除逻辑
DeleteInstByInstID的实现位于 src/scene_server/topo_server/logics/inst/inst.go:
func (c *commonInst) DeleteInstByInstID(kit *rest.Kit, objectID string, instID []int64, needCheckHost bool) error { if len(instID) == 0 { blog.Errorf("inst id array is empty, rid: %s", kit.Rid) return nil } cond := map[string]interface{}{ common.GetInstIDField(objectID): map[string]interface{}{common.BKDBIN: instID}, } if metadata.IsCommon(objectID) { cond[common.BKObjIDField] = objectID } return c.DeleteInst(kit, objectID, cond, needCheckHost) }其本质是构造{bk_inst_id: {$in: [id1, id2, ...]}}的 Mongo 查询条件,再调用DeleteInst完成条件删除。因此该接口执行的是实例的直接删除(物理删除),一旦删除成功,项目数据不可找回,调用前务必确认ids列表的准确性。
5.4 SDK 客户端封装
对于 Go 调用方,apimachinery 中提供了对应的客户端封装 src/apimachinery/toposerver/inst/project.go:
// DeleteProject delete project func (t *instanceClient) DeleteProject(ctx context.Context, h http.Header, opt *metadata.DeleteProjectOption) errors.CCErrorCoder { resp := new(metadata.Response) subPath := "/deletemany/project" err := t.client.Delete(). WithContext(ctx). Body(opt). SubResourcef(subPath). WithHeaders(h). Do(). Into(resp) if err != nil { return errors.CCHttpError } return resp.CCError() }内部以DELETE方法、Body(opt)携带请求体调用/deletemany/project,并通过resp.CCError()将网关响应统一转换为 error 返回。
六、权限与限流
6.1 权限点定义(IAM)
接口文档要求调用方具备“项目的删除权限”,该权限点在 IAM 初始化代码 src/ac/iam/initial_actions.go 中被注册为资源操作:
actions = append(actions, ResourceAction{ ID: DeleteProject, Name: ActionIDNameMap[DeleteProject], NameEn: "Delete Project", Type: Delete, RelatedResourceTypes: []RelateResourceType{projectResource}, RelatedActions: nil, Version: 1, })其中DeleteProject操作点 ID 的定义在 src/ac/iam/types.go:
// DeleteProject delete project action id DeleteProject ActionID = "delete_project"对应的中文名称在 src/ac/iam/initial_actions.go 中为“项目删除”。因此调用方需要先在蓝鲸权限中心申请“项目删除”操作点(关联项目资源类型)的权限。
6.2 网关限流
在网关资源定义 bk_apigw_resources_bk-cmdb.yaml 中,该接口挂载了bk-rate-limit限流插件:
pluginConfigs: - type: bk-rate-limit yaml: | rates: __default: - period: 1 tokens: 100即默认限流策略为每秒 100 个 token(令牌桶),高频调用时需要注意触发限流。
七、集成测试佐证
仓库的 topo_server 集成测试 src/test/topo_server/project_test.go 覆盖了该接口的完整调用链路:
It("delete project", func() { deleteOpt := metadata.DeleteProjectOption{ IDs: []int64{id1, id2}, } err := topoServerClient.Instance().DeleteProject(ctx, header, &deleteOpt) Expect(err).NotTo(HaveOccurred()) })测试先通过CreateProject创建两个项目并取得返回的 id,再通过DeleteProject批量删除,验证了“创建 → 删除”的完整闭环可用性,可作为二次开发或自测的参考样例。
八、调用注意事项
- 单次数量上限:
ids一次最多传 200 个,超限会返回参数超限错误(CCErrCommXXExceedLimit); - 参数不可为空:
ids为空数组会直接返回参数必填错误(CCErrCommParamsNeedSet); - 操作不可恢复:从 inst.go 的实现看,该接口为直接条件删除,无软删除/回收机制,误删后无法通过本接口恢复,请先通过
list_project查询确认待删除的项目 id; - 权限前置:需要具备“项目删除”(
delete_project)权限点,且网关侧该资源为非公共资源(isPublic: false),需申请后方可调用; - 事务一致性:删除过程在事务内执行,任一步骤失败整体回滚,无需担心部分删除的中间态;
- 限流约束:网关默认限流为每秒 100 次调用,批量场景建议合并请求而非高频并发调用。
九、相关接口延伸
项目(Project)的管理接口在网关文档中成组出现,与批量删除配套的常用接口还包括:
- 批量创建项目:
POST /api/v3/createmany/project,对应处理器CreateProject; - 批量更新项目:
PUT /api/v3/updatemany/project,对应处理器UpdateProject; - 查询项目列表:
POST /api/v3/findmany/project,对应处理器SearchProject。
三者与批量删除共同构成项目生命周期的完整管理闭环,且共享同一套DeleteProjectOption/UpdateProjectOption等参数结构与 IAM 项目资源权限体系,掌握本文的删除接口后,可举一反三理解其余项目接口的调用方式。
- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
相关推荐
蓝鲸配置平台(bk-cmdb)批量删除 Pod 接口调用与源码级实现解析
蓝鲸配置平台(bk cmdb)批量删除 Pod 接口调用与源码级实现解析 导读 本文围绕蓝鲸配置平台(BlueKing CMDB)对外 API 网关中的「批量删
后端企业应用运维蓝鲸 CMDB 批量删除 Kubernetes Workload 接口详解:参数、调用示例与源码实现
蓝鲸 CMDB 批量删除 Kubernetes Workload 接口详解:参数、调用示例与源码实现 本篇文章以蓝鲸智云配置平台(BlueKing CMDB,b
后端企业应用运维蓝鲸配置平台 bk-cmdb 批量删除 Kubernetes Workload 接口(batch_delete_kube_workload)实战指南
蓝鲸配置平台 bk cmdb 批量删除 Kubernetes Workload 接口(batch_delete_kube_workload)实战指南 本篇技术指
后端企业应用运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考