- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
导读
本文基于蓝鲸智云配置平台(bk-cmdb)的 API 文档docs/apidoc/cc/zh_hans/delete_cloud_host_from_biz.md,完整讲解「从业务空闲机集群删除云主机」这一云主机管理专用接口:包括接口能力与适用版本、请求/响应参数定义、参数校验规则、底层实现原理与权限模型,并结合仓库源码(src/scene_server/host_server/service/cloud_host.go、src/common/metadata/hostserver.go、src/test/host_server/host_test.go等)给出可复现的调用示例与验证方法。读完本文,你将掌握该接口的完整调用姿势、bk_cloud_host_identifier云主机标识的判定机制,以及它与普通主机删除接口的本质区别。
一、接口概述
| 项 | 说明 |
|---|---|
| 接口名称 | Delete Cloud Host From Biz(从业务空闲机集群删除云主机) |
| 协议 | HTTP |
| 方法 | DELETE |
| 路径 | /api/v3/deletemany/cloud_hosts |
| 引入版本 | v3.10.19+ |
| 所需权限 | 业务主机编辑权限 |
| 适用范围 | 云主机管理专用,不允许用于普通主机 |
该接口是 bk-cmdb 云主机管理体系中的配套接口:云主机通过add_cloud_host_to_biz(新增云主机到业务的空闲机模块)进入空闲机集群后,可通过本接口批量从业务中删除(物理移除主机实例,而非仅移出模块)。二者在 host_server 服务初始化 中被同时注册:
// initCloudHost init cloud host related api, **dedicated for cloud host management, do not use them for other use** func (s *Service) initCloudHost(web *restful.WebService) { utility := rest.NewRestUtility(rest.Config{...}) utility.AddHandler(rest.Action{Verb: http.MethodPost, Path: "/createmany/cloud_hosts", Handler: s.AddCloudHostToBiz}) utility.AddHandler(rest.Action{Verb: http.MethodDelete, Path: "/deletemany/cloud_hosts", Handler: s.DeleteCloudHostFromBiz}) utility.AddToRestfulWebService(web) }代码注释明确提示:该组接口为云主机管理专用,请勿挪作他用。
二、请求参数详解
1. 公共参数
接口请求需携带蓝鲸网关(API Gateway/ESB)公共参数(common_args_desc),典型包括:
bk_app_code:应用编码;bk_app_secret:应用密钥;bk_username:当前用户;bk_token:用户登录态令牌。
2. 接口参数
| 字段 | 类型 | 必选 | 描述 |
|---|---|---|---|
bk_biz_id | int | 是 | 业务 ID |
bk_host_ids | array | 是 | 待删除的云主机 ID 数组,数组长度最多为 200,一批主机仅可同时成功或同时失败 |
两条关键约束:
- 数量上限 200:参数校验在 DeleteCloudHostFromBizParam.Validate 中实现,超过上限返回
CCErrCommXXExceedLimit。仓库中常量定义为BKWriteOpLimit = 200(见 src/common/definitions.go#L104),即单次批量写操作上限。 - 全有或全无(All-or-Nothing):一批主机的删除在同一事务内完成,要么全部成功,要么全部失败回滚,保证数据一致性。
3. 云主机标识约束(重点)
接口只能删除云主机。若传入普通主机 ID,会报「主机不存在」错误。判定依据是主机属性bk_cloud_host_identifier:
- 云主机的该字段为
true; - 普通主机的该字段为
false。
该字段在 src/common/definitions.go#L817-L818 中定义:
// BKCloudHostIdentifierField defines if the host is a cloud host that doesn't allow cross biz transfer BKCloudHostIdentifierField = "bk_cloud_host_identifier"该属性由系统在 v3.10 升级脚本中自动创建:src/scene_server/admin_server/upgrader/y3.10.202209231617/add_cloud_host_related_attr.go中的addCloudHostIdentifierAttr会向主机对象模型插入名为「云主机标识」的布尔型属性,并标记为只读、不可编辑、系统内置(IsReadOnly: true、IsSystem: true、IsAPI: true)。
该标识在新增云主机时自动写入:AddCloudHostToBiz的预处理函数preprocessAddCloudHostParam会为每台新主机强制设置host[common.BKCloudHostIdentifierField] = true(见 src/scene_server/host_server/service/cloud_host.go#L98)。因此,凡是通过add_cloud_host_to_biz录入的云主机,天然满足本接口的删除条件。
三、请求参数示例
{ "bk_app_code": "esb_test", "bk_app_secret": "xxx", "bk_username": "xxx", "bk_token": "xxx", "bk_biz_id": 123, "bk_host_ids": [ 1, 2 ] }调用说明
- 完整网关调用路径为
POST /api/v3/deletemany/cloud_hosts(方法为 DELETE,路径中的deletemany表明是批量操作语义)。 - 内部 client 封装见 src/apimachinery/hostserver/apis.go#L816-L840:
// DeleteCloudHostFromBiz delete cloud hosts from biz func (hs *hostServer) DeleteCloudHostFromBiz(ctx context.Context, header http.Header, option *metadata.DeleteCloudHostFromBizParam) errors.CCErrorCoder { resp := new(metadata.CreateBatchResult) subPath := "/deletemany/cloud_hosts" err := hs.client.Delete(). WithContext(ctx). Body(option). SubResourcef(subPath). WithHeaders(header). Do(). Into(resp) ... }四、返回结果示例与参数说明
1. 返回结果示例
{ "result": true, "code": 0, "data": null, "message": "success", "permission": null, "request_id": "e43da4ef221746868dc4c837d36f3807" }删除成功后data为null(无返回实体)。
2. 返回结果参数说明
response
| 字段 | 类型 | 描述 |
|---|---|---|
result | bool | 请求成功与否。true请求成功;false请求失败 |
code | int | 错误编码。0表示 success,>0表示失败错误 |
message | string | 请求失败返回的错误信息 |
permission | object | 权限信息 |
request_id | string | 请求链 id,可用于全链路日志追踪与排障 |
五、源码级实现原理:删除流程拆解
接口入口为 DeleteCloudHostFromBiz,处理流程如下:
第 1 步:参数解码与校验
input := new(metadata.DeleteCloudHostFromBizParam) if err := ctx.DecodeInto(input); err != nil { ... } if err := s.validateDeleteCloudHostParam(ctx.Kit, input); err != nil { ... }validateDeleteCloudHostParam(cloud_host.go#L565-L599)执行三层校验:
- 基础参数校验:调用
input.Validate(),检查bk_biz_id > 0、bk_host_ids非空且长度不超过 200; - 空闲机集群归属校验:通过
ValidateHostInModule确认主机当前位于业务空闲机集群(bk_default字段等于DefaultFlagDefaultValue,常量值 0,见 src/common/definitions.go#L937-L938),非空闲机集群的主机无法通过本接口删除; - 云主机属性校验:按
bk_host_ids IN (...)且bk_cloud_host_identifier != true的条件统计主机数量,若存在普通主机则返回CCErrCommParamsIsInvalid,报错字段为bk_host_ids。这印证了文档「填写其它普通主机的 id 会报主机不存在」的说明——校验逻辑是反向匹配普通主机,命中即拒绝。
第 2 步:事务内执行删除
txnErr := s.CoreAPI.CoreService().Txn().AutoRunTxn(ctx.Kit.Ctx, ctx.Kit.Header, func() error { // 删除主机全部实例关联 asstCond := &metadata.InstAsstDeleteOption{ ... } _, err := s.CoreAPI.CoreService().Association().DeleteInstAssociation(...) // 生成主机删除审计日志 audit := auditlog.NewHostAudit(s.CoreAPI.CoreService()) auditLogs, err := audit.GenerateAuditLogByCond(auditParam, input.BizID, auditCond) // 从系统中删除主机 delReq := &metadata.DeleteHostRequest{ ApplicationID: input.BizID, HostIDArr: input.HostIDs, } err = s.CoreAPI.CoreService().Host().DeleteHostFromSystem(...) // 保存审计日志 ... })事务内依次完成:
- 清理实例关联:删除主机作为源对象(
bk_obj_id = host)或目标对象(bk_asst_obj_id = host)的全部关联关系; - 生成审计日志:通过
auditlog.NewHostAudit生成AuditDelete类型的审计记录; - 物理删除主机:调用 coreservice 的
DeleteHostFromSystem真正删除主机实例; - 落库审计:删除成功后保存审计日志。
得益于AutoRunTxn,任一环节失败都会整体回滚,从而保证「一批主机仅可同时成功或同时失败」。
第 3 步:响应
ctx.RespEntity(nil) // data 为 null六、权限模型:业务主机编辑权限
接口权限在 src/ac/parser/host.go#L1540-L1601 的cloudHost解析器中定义。命中DELETE /api/v3/deletemany/cloud_hosts后:
ps.Attribute.Resources = []meta.ResourceAttribute{ { Basic: meta.Basic{ Type: meta.HostInstance, Action: meta.UpdateMany, }, BusinessID: bizID, Layers: meta.Layers{{ Type: meta.Business, InstanceID: bizID, }}, }, }即删除云主机被映射为对**业务下主机实例(HostInstance)的批量更新(UpdateMany)**动作,需要「业务主机编辑权限」,并按照请求体中的bk_biz_id做资源归属鉴权。src/ac/parser/host.go中的注释也明确说明:创建与删除云主机的操作均复用「更新业务主机」的鉴权模型。
七、云主机标识(bk_cloud_host_identifier)与云主机生命周期
理解本接口,需要把握云主机在 bk-cmdb 中的完整生命周期:
- 新增:调用
add_cloud_host_to_biz(POST /api/v3/createmany/cloud_hosts)将云主机加入业务空闲机模块,系统自动为其打上bk_cloud_host_identifier = true标识; - 管理:云主机属性中
bk_cloud_host_identifier为true,普通主机为false; - 删除:调用本接口
delete_cloud_host_from_biz(DELETE /api/v3/deletemany/cloud_hosts)从业务空闲机集群删除云主机。
此外,从src/common/definitions.go#L817的注释「hosts with the cloud host identifier attribute set cannot be transferred across biz」可知,带云主机标识的主机不允许跨业务转移,这一特性也强化了「云主机由独立专用接口管理」的设计边界。
八、测试验证:接口行为与约束的实证
仓库中的集成测试 src/test/host_server/host_test.go#L2058-L2136(delete cloud host from biz idle set test)覆盖了该接口的完整行为链:
| 测试场景 | 预期结果 | 对应约束 |
|---|---|---|
删除非目标业务中的云主机(bizID1) | 报错 | 主机必须属于bk_biz_id指定的业务 |
| 用非法主机 ID 调用 | 报错 | 只能删除云主机 |
将云主机转移至业务普通模块后调用MoveHostToResourcePool回收 | 返回 false | 云主机不允许转移到资源池 |
将云主机转移到空闲机模块(MoveHost2FaultModule) | 成功 | 删除前置条件:主机须位于空闲机集群 |
| 从空闲机集群删除云主机 | 成功 | 正常删除路径 |
| 删除后按业务搜索主机 | Count = 0 | 主机已被物理删除 |
测试用例完整印证了文档中的两个约束:只能删除空闲机集群中的云主机,以及删除是彻底的物理删除。
九、常见错误与排障指引
| 场景 | 现象 | 排查建议 |
|---|---|---|
| 传入了普通主机 ID | 返回主机不存在(CCErrCommParamsIsInvalid,字段bk_host_ids) | 确认主机bk_cloud_host_identifier为true;若为false说明是普通主机,应使用常规主机删除/转移接口 |
| 主机不在空闲机集群 | 校验失败 | 先用transfer host to idle set类接口将主机移至空闲机集群 |
bk_host_ids超过 200 | 返回超限错误CCErrCommXXExceedLimit | 拆分批量,每次不超过 200 台 |
| 缺少业务主机编辑权限 | 权限校验失败 | 为调用方账号在 IAM 中授予目标业务的「业务主机编辑权限」 |
| 一批主机中混有异常主机 | 整批失败(回滚) | 事务保证全有或全无,需先剔除异常主机后重试 |
十、总结
delete_cloud_host_from_biz是 bk-cmdb v3.10.19+ 云主机管理体系中的专用删除接口,其核心设计可归纳为三点:
- 身份限定:通过
bk_cloud_host_identifier布尔属性严格区分云主机与普通主机,普通主机无法通过该接口删除; - 位置限定:仅允许删除业务空闲机集群中的云主机,删除前会校验主机模块归属;
- 事务保证:单次最多 200 台,一批主机在事务中全有或全无,删除前自动清理实例关联并生成审计日志。
实际使用中,建议与add_cloud_host_to_biz配套阅读,并参考 接口文档目录 中的云主机相关文档,形成「新增→管理→删除」的完整闭环认知。
- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
相关推荐
蓝鲸 CMDB delete_cloud_host_from_biz 接口实战指南:从业务空闲机集群删除云主机
蓝鲸 CMDB delete_cloud_host_from_biz 接口实战指南:从业务空闲机集群删除云主机 导读 delete_cloud_host_fro
后端企业应用运维蓝鲸 CMDB 接口详解:delete_cloud_host_from_biz 从业务空闲机集群删除云主机
蓝鲸 CMDB 接口详解:delete_cloud_host_from_biz 从业务空闲机集群删除云主机 本文聚焦蓝鲸智云配置平台(BlueKing CMDB
后端企业应用运维蓝鲸配置平台(bk-cmdb)delete_cloud_host_from_biz 接口详解:从业务空闲机集群删除云主机
蓝鲸配置平台(bk cmdb)delete_cloud_host_from_biz 接口详解:从业务空闲机集群删除云主机 导读 delete_cloud_hos
后端企业应用运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考