- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
导读
本文以蓝鲸智云配置平台(BlueKing CMDB,仓库目录bk-cmdb)官方 API 文档 add_cloud_host_to_biz 为骨架,完整讲解"新增云主机到业务空闲机模块"这一云主机管理专用接口的请求参数、字段含义、请求/返回示例,并结合 host_server 场景服务的 Go 源码(cloud_host.go)剖析其底层处理流程:参数校验、云主机标识写入、新增/更新分类、事务化批量创建与空闲机转移。读完本文,你将掌握该接口的完整调用姿势,并理解一批主机"同时成功或同时失败"的原子性保证是如何在源码中实现的。
一、接口概述:定位、版本与权限
该接口用于将云主机批量导入到指定业务的空闲机模块,是云主机管理专用接口,与普通主机导入接口相互独立。
- 功能:新增云主机到业务空闲机模块。
- 版本要求:v3.10.19+(自该版本起提供)。
- 所需权限:业务主机编辑权限。
- 接口路由:源码在 service_initfunc.go 的
initCloudHost中注册,HTTP 方法为POST,路径为/createmany/cloud_hosts。源码注释明确标注:dedicated for cloud host management, do not use them for other use(云主机管理专用,请勿用于其他用途)。
该接口与配套的"删除云主机"接口(DELETE /deletemany/cloud_hosts)共同组成云主机生命周期管理闭环。
二、请求参数详解
接口请求同时包含通用鉴权参数(bk_app_code、bk_app_secret、bk_username、bk_token)与业务参数。
2.1 接口参数
| 字段 | 类型 | 必选 | 描述 |
|---|---|---|---|
| bk_biz_id | int | 是 | 业务ID |
| host_info | array | 是 | 新增的云主机信息,数组长度最多为 200,一批主机仅可同时成功或同时失败 |
- 数量上限 200:对应源码常量
BKWriteOpLimit = 200(定义于 definitions.go)。参数结构体 AddCloudHostToBizParam 的Validate方法会对bk_biz_id <= 0、host_info为空、host_info超过 200 条分别返回校验错误。 - 批次原子性:一批主机仅可同时成功或同时失败,由事务机制保证(详见第四部分源码剖析)。
2.2 host_info 字段
主机信息中,管控区域ID、内网IP、云厂商、云主机实例ID为必填字段;其余字段为主机模型中定义的属性,按需填写。字段表如下:
| 字段 | 类型 | 必选 | 描述 |
|---|---|---|---|
| bk_cloud_id | int | 是 | 管控区域ID |
| bk_host_innerip | string | 是 | IPv4 格式的主机内网IP,多个IP之间用逗号分隔 |
| bk_cloud_vendor | array | 是 | 云厂商 |
| bk_cloud_inst_id | array | 是 | 云主机实例ID |
| bk_addressing | string | 否 | 寻址方式,云主机的寻址方式都是 static |
| bk_host_name | string | 否 | 主机名,也可以为其它属性 |
| operator | string | 否 | 主要维护人,也可以为其它属性 |
| bk_comment | string | 否 | 备注,也可以为其它属性 |
| import_from | string | 否 | 主机导入来源,以 api 方式导入为 3 |
| bk_asset_id | string | 否 | 固资编号 |
| bk_created_at | string | 否 | 创建时间 |
| bk_updated_at | string | 否 | 更新时间 |
| bk_created_by | string | 否 | 创建人 |
| bk_updated_by | string | 否 | 更新人 |
| bk_cloud_host_status | string | 否 | 云主机状态 |
| bk_cpu | int | 否 | CPU 逻辑核心数 |
| bk_cpu_architecture | string | 否 | CPU 架构 |
| bk_cpu_module | string | 否 | CPU 型号 |
| bk_disk | int | 否 | 磁盘容量(GB) |
| bk_host_outerip | string | 否 | 主机外网IP |
| bk_host_innerip_v6 | string | 否 | 主机内网 IPv6 |
| bk_host_outerip_v6 | string | 否 | 主机外网 IPv6 |
| bk_isp_name | string | 否 | 所属运营商 |
| bk_mac | string | 否 | 主机内网 MAC 地址 |
| bk_mem | int | 否 | 主机内存容量(MB) |
| bk_os_bit | string | 否 | 操作系统位数 |
| bk_os_name | string | 否 | 操作系统名称 |
| bk_os_type | string | 否 | 操作系统类型 |
| bk_os_version | string | 否 | 操作系统版本 |
| bk_outer_mac | string | 否 | 主机外网 MAC 地址 |
| bk_province_name | string | 否 | 所在省份 |
| bk_service_term | int | 否 | 质保年限 |
| bk_sla | string | 否 | SLA 级别 |
| bk_sn | string | 否 | 设备 SN |
| bk_state | string | 否 | 当前状态 |
| bk_state_name | string | 否 | 所在国家 |
| bk_bak_operator | string | 否 | 备份维护人 |
关于字段类型的小提示:文档将
bk_cloud_vendor与bk_cloud_inst_id标记为array,但从实现看,源码 cloud_host.go 的parseCloudHostInfo使用util.GetStrByInterface将其按字符串解析,官方测试用例(host_test.go)中也是直接传字符串(如"1"、"000000001")。实际调用时传入字符串即可。
2.3 云主机属性模型说明
bk_cloud_vendor、bk_cloud_inst_id、bk_cloud_host_status是随云主机管理能力一并内置的主机属性,由升级脚本 add_cloud_host_attr.go 在升级时写入主机模型(属性组为 baseInfo,预置属性IsPre = true):
bk_cloud_inst_id:云主机实例ID,单字符类型;bk_cloud_vendor:云厂商,枚举类型;bk_cloud_host_status:云主机状态,枚举取值包括:1未知、2启动中、3运行中、4停止中、5已停止、6已销毁(见同一文件中的cloudInstStatusEnum)。
三、请求参数示例
{ "bk_app_code": "esb_test", "bk_app_secret": "xxx", "bk_username": "xxx", "bk_token": "xxx", "bk_biz_id": 123, "host_info": [ { "bk_cloud_id": 0, "bk_host_innerip": "127.0.0.1", "bk_cloud_vendor": "2", "bk_cloud_inst_id": "45515", "bk_host_name": "host1", "operator": "admin", "bk_comment": "comment" }, { "bk_cloud_id": 0, "bk_host_innerip": "127.0.0.2", "bk_cloud_vendor": "2", "bk_cloud_inst_id": "45656", "bk_host_name": "host2", "operator": "admin", "bk_comment": "comment" } ] }四、返回结果与参数说明
4.1 返回结果示例
{ "result": true, "code": 0, "message": "", "permission": null, "request_id": "e43da4ef221746868dc4c837d36f3807", "data": { "ids": [ 1, 2 ] } }4.2 response 字段说明
| 字段 | 类型 | 描述 |
|---|---|---|
| result | bool | 请求成功与否。true:请求成功;false:请求失败 |
| code | int | 错误编码。0 表示 success,>0 表示失败错误 |
| message | string | 请求失败返回的错误信息 |
| data | object | 请求返回的数据 |
| permission | object | 权限信息 |
| request_id | string | 请求链 id |
4.3 data 字段说明
| 字段 | 类型 | 描述 |
|---|---|---|
| ids | array | 创建成功的主机 ID 数组 |
data.ids的顺序与请求参数host_info中的主机顺序一一对应:对于本次新建的主机返回新生成的bk_host_id,对于命中已有主机而执行更新逻辑的主机则返回其既有bk_host_id。该重排逻辑位于 cloud_host.go,通过createIndexMap与updateParamMap将新建 ID 与更新 ID 按原始下标回填。
五、源码级实现剖析:一次调用背后发生了什么
接口处理器为 cloud_host.go 中的AddCloudHostToBiz,完整流程分为四步:
5.1 第一步:参数预处理(preprocessAddCloudHostParam)
对应源码 cloud_host.go:
- 调用
input.Validate()做结构级校验(业务ID合法、主机数组非空且不超过 200 条); - 为每一台主机写入云主机标识字段
bk_cloud_host_identifier = true(常量定义于 definitions.go,其作用是标记该主机为"不允许跨业务转移"的云主机,后续TransferHostAcrossBusiness等跨业务操作会据此拒绝); - 汇总所有
bk_cloud_id去重后查询bk_cc_base_plat表,确认管控区域均真实存在,否则报参数非法错误。
5.2 第二步:新增/更新分类(classifyHosts)
对应源码 cloud_host.go:
以genExistHostParams构造查询条件,按以下三组键判断主机是否已存在:
- 云厂商 + 云主机实例ID(
bk_cloud_vendor+bk_cloud_inst_id,唯一键格式vendor-instID); - 管控区域 + 内网IP(
bk_cloud_id+bk_host_innerip); - 管控区域 + 内网 IPv6(
bk_cloud_id+bk_host_innerip_v6)。
已存在的主机进入"更新"集合(updateParamMap),不存在的主机进入"新建"集合(needCreateHosts)。这正是该接口天然具备幂等性的原因:重复导入同一批云主机不会产生重复数据,而是转化为对既有主机的属性更新。
5.3 第三步:事务化执行(AutoRunTxn)
对应源码 cloud_host.go,通过CoreService().Txn().AutoRunTxn将两个写操作包裹在统一事务中:
updateCloudHost:对"更新集合"中的主机逐台校验其确实属于目标业务(调用GetDistinctHostIDByTopology),再生成更新审计日志并执行UpdateInstance;addCloudHostToBiz:对"新建集合"中的主机执行创建与归属转移。
这就是文档所述"一批主机仅可同时成功或同时失败"的实现根基——事务内任一环节失败,整批写入回滚,不会出现部分成功部分失败的数据状态。
5.4 第四步:新建主机 + 转移到空闲机模块(addCloudHostToBiz)
对应源码 cloud_host.go,内部依次执行:
- 定位空闲机模块:按
bk_biz_id+bk_default = 1(DefaultResModuleFlag,定义于 definitions.go)查询该业务的空闲机模块 ID,若结果不为 1 条则报参数错误; - 批量创建主机实例:调用
CoreService().Instance().CreateManyInstance创建主机模型实例,若返回结果中存在Repeated(重复)或Exceptions(异常)项则整体失败; - 转移到空闲机模块:构造
TransferHostToInnerModule请求,调用Host().TransferToInnerModule将新建主机挂入空闲机模块,完成"新增到业务空闲机"的语义; - 生成并保存审计日志:调用
auditlog.NewHostAudit生成AuditCreate类型的审计日志并落库,保证每一步变更可追溯。
5.5 客户端调用入口
若在 bk-cmdb 内部以 Go 代码调用该接口,可使用 apimachinery 客户端方法hostServer.AddCloudHostToBiz(apis.go),其内部向/createmany/cloud_hosts发起POST请求并解析返回的CreateBatchResult。
六、测试用例验证:接口行为的边界保证
官方集成测试 host_test.go 覆盖了该接口的主要行为,是理解接口语义的最佳佐证:
| 测试场景 | 预期结果 | 说明 |
|---|---|---|
| 正常导入两台云主机到空闲机 | 返回 2 个 host ID,可用SearchHostWithBiz按内网IP 查到对应主机 | 新建路径 |
| 再次导入同一台云主机(同 vendor+instID) | 不产生重复主机,原主机属性(如bk_host_name)被更新 | 更新路径 / 幂等性 |
| 将云主机转移到资源池 | 失败 | 云主机不允许移入资源池 |
| 跨业务转移云主机 | 失败 | 云主机不允许跨业务转移(bk_cloud_host_identifier标识生效) |
| 向不存在的业务导入 | 失败 | 业务校验 |
| 部分主机缺少云厂商/实例ID | 整批失败 | 必填字段校验 + 批次原子性 |
| 同 vendor+instID 主机导入到另一业务 | 失败 | 云主机唯一性约束(bk_cloud_inst_id字段建索引,见 hostbase.go 的cloudInstID索引) |
未传bk_biz_id或host_info | 失败 | 参数结构校验 |
七、使用注意事项小结
- 必填字段:
bk_cloud_id、bk_host_innerip、bk_cloud_vendor、bk_cloud_inst_id四项缺一不可,且内网IP与内网IPv6 至少填写其一; - 批次上限:单次
host_info不超过 200 条,超出会返回CCErrCommXXExceedLimit(错误码 1199035,见 errInfo.go); - 幂等导入:重复提交同一批云主机不会重复创建,而是更新既有主机属性,可放心用于定时同步场景;
- 专用接口:该接口仅供云主机管理使用,请勿将其用于普通物理机/虚拟机导入;导入后主机带有
bk_cloud_host_identifier标识,无法移入资源池或跨业务转移; - 版本与权限:需要 v3.10.19+ 版本,且调用方需具备对应业务的"主机编辑"权限。
延伸阅读:接口英文文档见 add_cloud_host_to_biz.md;配套的删除云主机接口实现见 cloud_host.go 的DeleteCloudHostFromBiz;云主机属性模型升级逻辑见 add_cloud_host_attr.go。
- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
相关推荐
蓝鲸 CMDB 新增云主机到业务空闲机模块接口实战(add_cloud_host_to_biz)
蓝鲸 CMDB 新增云主机到业务空闲机模块接口实战(add_cloud_host_to_biz) 导读 本文围绕蓝鲸配置平台(bk cmdb)为云主机管理场景专
后端企业应用运维蓝鲸配置平台(bk-cmdb)云主机管理专用接口:新增云主机到业务空闲机模块
蓝鲸配置平台(bk cmdb)云主机管理专用接口:新增云主机到业务空闲机模块 导读 本文基于蓝鲸智云配置平台(BlueKing CMDB,仓库 bk cmdb
后端企业应用运维蓝鲸 CMDB(bk-cmdb)add_host_to_business_idle 接口实战:批量添加主机到业务空闲机
蓝鲸 CMDB(bk cmdb)add_host_to_business_idle 接口实战:批量添加主机到业务空闲机 本文是一篇围绕蓝鲸配置平台(BlueKi
后端企业应用运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考