蓝鲸配置平台 ESB 接口实战:transfer_host_to_resourcemodule 上交主机至资源池

原创2026-10-14 22:02:081,655 阅读
文章标签:后端企业应用微服务

蓝鲸配置平台 ESB 接口实战:transfer_host_to_resourcemodule 上交主机至资源池

本篇技术指南聚焦蓝鲸智云配置平台(BlueKing CMDB)ESB 组件 transfer_host_to_resourcemodule 接口的完整用法:如何将业务空闲机池下的主机上交(回收)至资源池,包括请求参数语义、默认转移目录规则、返回结构、权限模型,以及从 ESB 网关到 coreservice 底层的完整调用链与关键校验逻辑。读完本文,你将能够准确构造请求、解读响应与错误码,并理解该操作在"业务主机池 → 资源池"生命周期管理中的位置与限制。

该接口属于早期由 ESB 维护并封装的 CMDB 组件文档(见 docs/apidoc/esb-cc/README.md,该目录内容需保留、不新增接口),文档同时提供英文版本(docs/apidoc/esb-cc/en/transfer_host_to_resourcemodule.md)。

接口概览:功能与适用场景

功能描述:上交主机至资源池,操作权限为"主机归还主机池"权限。

在 CMDB 的资源管理中,主机在"业务"与"资源池(主机池)"之间流转是常见的生命周期操作:

  • 业务侧维护的待分配主机通常存放在业务的空闲机池(内置模块)中;
  • 当主机不再属于任何业务时,需要将其上交/回收至资源池,由资源池统一纳管,后续可再分配到其他业务。

transfer_host_to_resourcemodule 正是完成"业务主机 → 资源池"这一方向转移的 ESB 接口。仓库中与之对应的前端行为描述为"主机回收至主机池"(见 src/ui/src/store/modules/api/host-relation.js)。

接口有一个重要使用前提(原文档强调的注意项):

只能上交业务空闲机池下的主机

也就是说,并非业务中的任意主机都可以上交;只有位于业务空闲机池(广义上还包括故障机、待回收等内置模块)中的主机才满足上交条件。

请求参数详解

接口公共参数({{ common_args_desc }} 模板展开)与接口参数如下。

公共参数

原文档通过 {{ common_args_desc }} 引用 ESB 公共参数模板,从请求示例可以还原出实际调用时必须携带的网关公共参数:

字段 类型 必选 描述
bk_app_code string 是 应用标识(应用 ID)
bk_app_secret string 是 应用密钥
bk_username string 是 操作用户名
bk_token string 是 登录态 Token

接口参数

字段 类型 必选 描述
bk_supplier_account string 否 开发商账号
bk_biz_id int 是 业务ID
bk_module_id int 否 转移到的主机池目录ID,默认转移到主机池的空闲机目录
bk_host_id array 是 主机ID

参数说明与源码对应关系如下:

  • bk_biz_id:必填,指主机当前所属的业务 ID。在 CMDB 内部统一使用字段常量 BKAppIDField = "bk_biz_id"(见 src/common/definitions.go);
  • bk_host_id:必填的数组类型,即待上交主机的 ID 列表。源码中对应的请求结构体为 DefaultModuleHostConfigParams,字段为 HostIDs <a href="https://link.gitcode.com/i/134bc2ab6e172999e864ec50197bd708" target="_blank">]int64 \json:"bk_host_id"`(见 [src/common/metadata/common.go</a>),内部常量同样定义为 BKHostIDField = "bk_host_id"`(见 src/common/definitions.go);
  • bk_module_id:选填,指定上交到资源池中的具体目录 ID;不传时默认转移到主机池的空闲机目录。从实现看,当 ModuleID == 0 时,会按资源池业务中 DefaultResModuleFlag(值为 1,见 src/common/definitions.go)标记查找默认资源目录,即"主机池的空闲机目录"(见 src/scene_server/host_server/logics/module.go);
  • bk_supplier_account:开发商账号,蓝鲸多租户(开发商)体系下的账号标识。

请求参数示例

原文档给出的完整 Python 格式请求示例(含公共参数):

{
    "bk_app_code": "esb_test",
    "bk_app_secret": "xxx",
    "bk_username": "xxx",
    "bk_token": "xxx",
    "bk_supplier_account": "123456789",
    "bk_biz_id": 1,
    "bk_module_id": 3,
    "bk_host_id": [
        9,
        10
    ]
}

该示例表示:将业务 bk_biz_id=1 下的主机 9、10 上交至资源池目录 bk_module_id=3。若省略 bk_module_id,则主机将默认进入资源池的空闲机目录。

返回结果示例


{
    "result": true,
    "code": 0,
    "message": "success",
    "permission": null,
    "request_id": "e43da4ef221746868dc4c837d36f3807",
    "data": null
}

返回结果参数说明

response

名称 类型 描述
result bool 请求成功与否。true:请求成功;false请求失败
code int 错误编码。 0表示success,>0表示失败错误
message string 请求失败返回的错误信息
data object 请求返回的数据
permission object 权限信息
request_id string 请求链id

其中 code=0 表示成功;request_id 为请求链 ID,用于全链路日志追踪;permission 在无权限校验问题时为 null,当用户缺少"主机归还主机池"权限时会返回相应的权限申请信息。

底层实现原理:从 ESB 到 coreservice 的调用链

该 ESB 组件最终会调用 host_server 的 /hosts/modules/resource 接口,完整调用链可以从仓库源码逐层还原。

1. 路由注册

host_server 服务初始化时注册了该路由(见 src/scene_server/host_server/service/service_initfunc.go):

utility.AddHandler(rest.Action{Verb: http.MethodPost, Path: "/hosts/modules/resource",
    Handler: s.MoveHostToResourcePool})

与之相邻的路由还包括:转移到空闲机 MoveHost2IdleModule、故障机 MoveHost2FaultModule、待回收 MoveHost2RecycleModule 以及资源池主机分配到业务空闲机(/hosts/modules/resource/idle)等,共同构成主机在业务与资源池之间双向流转的接口族。

2. 服务层 Handler

MoveHostToResourcePool 处理器解析请求体为 DefaultModuleHostConfigParams(见 src/scene_server/host_server/service/module.go):

  • 若 bk_host_id 列表为空,直接返回成功(空操作不报错);
  • 在事务(AutoRunTxn)内调用 Logic.MoveHostToResourcePool 执行实际转移;
  • 转移失败时返回异常明细 ExceptionResult 列表,成功则返回空 data。

3. 核心业务逻辑

Logics.MoveHostToResourcePool 是上交操作的核心实现(见 src/scene_server/host_server/logics/module.go),其关键步骤为:

  1. 获取资源池业务 ID(GetDefaultAppID),资源池本身也是一个特殊业务;
  2. 校验业务合法性与归属:ApplicationID == 0 时返回资源池不存在错误;若 ownerAppID == conf.ApplicationID,说明主机已在资源池中,直接返回"主机已在主机池"错误;
  3. 解析目标目录:bk_module_id 为 0 时按默认资源目录(空闲机目录)查找,否则按指定目录 ID 查找资源池模块;
  4. 校验主机来源(对应文档的"只能上交业务空闲机池下的主机"):通过条件 bk_default != 普通模块(0) 且 bk_biz_id = 业务ID 查询该业务下的内置模块(空闲机/故障机/待回收),再调用 notExistAppModuleHost 逐一确认待上交主机确实属于这些模块(见 src/scene_server/host_server/logics/module.go)。若有主机不在其中,返回"主机不属于空闲机模块"错误;
  5. 构造跨业务转移参数并执行:将主机从原业务转移到资源池业务的目标目录,参数为 TransferHostsCrossBusinessRequest(源业务、目标业务、目标模块、主机 ID 列表);
  6. 写入操作审计日志(auditlog.NewHostModuleLog + SaveAudit),保证主机模块关系变更可追溯。

4. coreservice 底层转移

跨业务转移最终落到 coreservice 的 TransferToAnotherBusiness(见 src/source_controller/coreservice/core/host/transfer/manager.go)。从源码结构看,该实现的核心是:

  • 构建跨业务主机模块转移器(SetCrossBusiness 标记源业务列表);
  • 校验参数后,清理主机在原业务下的业务私有字段(clearLegacyPrivateField,将私有属性置空并更新 cc_HostBase 表),随后通过 MongoDB 的 unset 更新移除遗留数据,确保主机上交后不带原业务的私有属性进入资源池。

5. 客户端封装

若在 Go 服务间直接调用,可复用 apimachinery 封装的客户端方法 hostServer.MoveHostToResourcePool(见 src/apimachinery/hostserver/apis.go),它向 /hosts/modules/resource 发起 POST 请求,请求体为 DefaultModuleHostConfigParams。

权限控制:主机归还主机池

接口要求调用者具备"主机归还主机池"权限,该权限在权限中心(IAM)的初始动作定义中明确注册:

BusinessHostTransferToResourcePool: "主机归还主机池",

(见 src/ac/iam/initial_actions.go)

从权限解析器(src/ac/parser/host.go)可以还原权限判定逻辑:

  • 命中模式 "/api/v3/hosts/modules/resource"(POST)后,解析 bk_biz_id 与请求体中的 bk_module_id;
  • 若未指定目录 ID,则自动换算为资源池默认目录 ID 用于授权;
  • 最终构造的资源为"业务实例 + 资源池目录实例"两级授权对象,动作类型为 MoveBizHostFromModuleToResPool(主机归还主机池)。

因此,即使 bk_module_id 省略,鉴权时也会基于默认空闲机目录进行,权限模型与实际转移目标保持一致。

常见错误码与排查

接口失败时通过 code(>0)返回错误编码,结合错误码定义(见 src/common/errInfo.go)可快速定位问题:

错误码 常量名 含义与排查方向
1110051 CCErrHostNotResourceFail 资源池不存在:检查资源池业务是否初始化
1110052 CCErrHostBelongResourceFail 主机已在资源池中:所选主机本身已归属资源池业务,无需再次上交
1110056 CCErrHostModuleConfigNotMatch 主机不属于业务空闲机模块:违反"只能上交业务空闲机池下的主机"前提,需先把主机移入业务空闲机池再执行上交
1108044 CCErrHostTransferFinalModuleConflict 转移后模块互斥冲突:目标模块与主机现有模块归属存在冲突(该错误同时用于带服务实例自动清除的通用转移接口)

仓库中的接口测试用例覆盖了上述典型异常场景(见 src/test/host_server/host_abnormal_test.go):转移不存在的主机、不存在的业务主机、非空闲机主机等均返回 result=false,与本文描述的校验逻辑一一对应。

前端调用场景(可选佐证)

Web 端"主机池"转移菜单也复用同一接口(见 src/ui/src/views/resource/transfer/transfer-menu.vue 与 src/ui/src/views/resource/transfer/transfer-menu.vue):

await this.$store.dispatch('hostRelation/transferHostToResourceModule', {
  params: {
    bk_biz_id: HostStore.uniqueBusiness.bk_biz_id,
    bk_host_id: HostStore.getSelected().map(item => item.host.bk_host_id),
    bk_module_id: directoryId
  },
  ...
})

前端在发起前同样会校验"仅支持对空闲机池下的主机进行操作",与接口后端的模块归属校验形成双重保障;所选主机已在主机池中时会直接拦截提示,对应后端错误码 1110052 的场景。

综上,transfer_host_to_resourcemodule 是 CMDB 主机从业务归还至资源池的标准通道:请求参数少、语义清晰,但背后包含业务校验、空闲机归属校验、跨业务转移与私有字段清理、权限鉴权、审计日志等多个环节。开发者在集成时重点把握三点即可:主机必须处于业务空闲机池、bk_module_id 缺省即落到资源池空闲机目录、权限需开通"主机归还主机池",其余行为均由平台保证一致性。

登录后查看全文
bk-cmdb