ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

蓝鲸配置平台 bk-cmdb 云主机接入实战:调用 add_cloud_host_to_biz 接口将云主机批量导入业务空闲机

蓝鲸配置平台 bk-cmdb 云主机接入实战:调用 add_cloud_host_to_biz 接口将云主机批量导入业务空闲机
  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

蓝鲸智云配置平台(BlueKing CMDB)

项目地址:https://gitcode.com/gh_mirrors/bk/bk-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_idint是业务ID
host_infoarray是新增的云主机信息,数组长度最多为 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_idint是管控区域ID
bk_host_inneripstring是IPv4 格式的主机内网IP,多个IP之间用逗号分隔
bk_cloud_vendorarray是云厂商
bk_cloud_inst_idarray是云主机实例ID
bk_addressingstring否寻址方式,云主机的寻址方式都是 static
bk_host_namestring否主机名,也可以为其它属性
operatorstring否主要维护人,也可以为其它属性
bk_commentstring否备注,也可以为其它属性
import_fromstring否主机导入来源,以 api 方式导入为 3
bk_asset_idstring否固资编号
bk_created_atstring否创建时间
bk_updated_atstring否更新时间
bk_created_bystring否创建人
bk_updated_bystring否更新人
bk_cloud_host_statusstring否云主机状态
bk_cpuint否CPU 逻辑核心数
bk_cpu_architecturestring否CPU 架构
bk_cpu_modulestring否CPU 型号
bk_diskint否磁盘容量(GB)
bk_host_outeripstring否主机外网IP
bk_host_innerip_v6string否主机内网 IPv6
bk_host_outerip_v6string否主机外网 IPv6
bk_isp_namestring否所属运营商
bk_macstring否主机内网 MAC 地址
bk_memint否主机内存容量(MB)
bk_os_bitstring否操作系统位数
bk_os_namestring否操作系统名称
bk_os_typestring否操作系统类型
bk_os_versionstring否操作系统版本
bk_outer_macstring否主机外网 MAC 地址
bk_province_namestring否所在省份
bk_service_termint否质保年限
bk_slastring否SLA 级别
bk_snstring否设备 SN
bk_statestring否当前状态
bk_state_namestring否所在国家
bk_bak_operatorstring否备份维护人

关于字段类型的小提示:文档将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 字段说明

字段类型描述
resultbool请求成功与否。true:请求成功;false:请求失败
codeint错误编码。0 表示 success,>0 表示失败错误
messagestring请求失败返回的错误信息
dataobject请求返回的数据
permissionobject权限信息
request_idstring请求链 id

4.3 data 字段说明

字段类型描述
idsarray创建成功的主机 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:

  1. 调用input.Validate()做结构级校验(业务ID合法、主机数组非空且不超过 200 条);
  2. 为每一台主机写入云主机标识字段bk_cloud_host_identifier = true(常量定义于 definitions.go,其作用是标记该主机为"不允许跨业务转移"的云主机,后续TransferHostAcrossBusiness等跨业务操作会据此拒绝);
  3. 汇总所有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将两个写操作包裹在统一事务中:

  1. updateCloudHost:对"更新集合"中的主机逐台校验其确实属于目标业务(调用GetDistinctHostIDByTopology),再生成更新审计日志并执行UpdateInstance;
  2. addCloudHostToBiz:对"新建集合"中的主机执行创建与归属转移。

这就是文档所述"一批主机仅可同时成功或同时失败"的实现根基——事务内任一环节失败,整批写入回滚,不会出现部分成功部分失败的数据状态。

5.4 第四步:新建主机 + 转移到空闲机模块(addCloudHostToBiz)

对应源码 cloud_host.go,内部依次执行:

  1. 定位空闲机模块:按bk_biz_id+bk_default = 1(DefaultResModuleFlag,定义于 definitions.go)查询该业务的空闲机模块 ID,若结果不为 1 条则报参数错误;
  2. 批量创建主机实例:调用CoreService().Instance().CreateManyInstance创建主机模型实例,若返回结果中存在Repeated(重复)或Exceptions(异常)项则整体失败;
  3. 转移到空闲机模块:构造TransferHostToInnerModule请求,调用Host().TransferToInnerModule将新建主机挂入空闲机模块,完成"新增到业务空闲机"的语义;
  4. 生成并保存审计日志:调用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失败参数结构校验

七、使用注意事项小结

  1. 必填字段:bk_cloud_id、bk_host_innerip、bk_cloud_vendor、bk_cloud_inst_id四项缺一不可,且内网IP与内网IPv6 至少填写其一;
  2. 批次上限:单次host_info不超过 200 条,超出会返回CCErrCommXXExceedLimit(错误码 1199035,见 errInfo.go);
  3. 幂等导入:重复提交同一批云主机不会重复创建,而是更新既有主机属性,可放心用于定时同步场景;
  4. 专用接口:该接口仅供云主机管理使用,请勿将其用于普通物理机/虚拟机导入;导入后主机带有bk_cloud_host_identifier标识,无法移入资源池或跨业务转移;
  5. 版本与权限:需要 v3.10.19+ 版本,且调用方需具备对应业务的"主机编辑"权限。

延伸阅读:接口英文文档见 add_cloud_host_to_biz.md;配套的删除云主机接口实现见 cloud_host.go 的DeleteCloudHostFromBiz;云主机属性模型升级逻辑见 add_cloud_host_attr.go。

  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

蓝鲸智云配置平台(BlueKing CMDB)

项目地址:https://gitcode.com/gh_mirrors/bk/bk-cmdb
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进