- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
本文基于 bk-cmdb(蓝鲸智云配置平台)API 网关开放接口文档find_host_by_topo,系统讲解“查询拓扑节点下的主机”这一接口的完整入参、响应结构与权限模型,并结合 host_server 的源码实现,剖析该接口从网关路由到核心服务查询的内部调用链与参数校验规则,帮助开发者正确集成并调试该接口。
一、接口概述
find_host_by_topo是 bk-cmdb 通过 API 网关(apigw)对外暴露的主机查询接口,用于查询指定业务下某一拓扑节点下的主机列表。根据接口文档 find_host_by_topo.md:
- 功能描述:查询拓扑节点下的主机;
- 接口版本:v3.8.13(自该版本起通过 API 网关开放);
- 权限要求:业务访问权限(即调用方需要对目标业务具有主机资源的访问权限)。
从网关资源定义 bk_apigw_resources_bk-cmdb.yaml 可以看到,该接口对应的网关路由为:
POST /api/v3/findmany/hosts/by_topo/biz/{bk_biz_id}其中operationId为find_host_by_topo,isPublic: false、allowApplyPermission: true,表示该资源不公开、需要申请权限后方可调用;同时配置了bk-rate-limit限流插件(默认速率 100 tokens/秒)。在权限授权清单 definition.yaml 中,find_host_by_topo被列入按resource维度授权的资源名列表,即权限粒度细化到具体接口资源。
在 bk-cmdb 服务端,该路由由 host_server 注册:见 service_initfunc.go 中/findmany/hosts/by_topo/biz/{bk_biz_id}到处理函数FindHostsByTopo的映射。
二、输入参数
接口入参完整继承自接口文档,共 5 个必选参数:
| 参数名称 | 参数类型 | 必选 | 描述 |
|---|---|---|---|
| bk_biz_id | int | 是 | 业务ID(位于 URL 路径参数中) |
| bk_obj_id | string | 是 | 拓扑节点模型ID,如集群(set)、模块(module)或其他 topo 节点上的模型,不可为 biz、host |
| bk_inst_id | int | 是 | 拓扑节点实例ID |
| fields | array | 是 | 主机属性列表,控制返回结果的主机里有哪些字段,能够加速接口请求和减少网络流量传输 |
| page | object | 是 | 分页信息 |
page 字段说明
| 参数名称 | 参数类型 | 必选 | 描述 |
|---|---|---|---|
| start | int | 是 | 记录开始位置 |
| limit | int | 是 | 每页限制条数,最大500 |
参数校验规则(源码印证)
服务端对请求体的解析结构为 FindHostsByTopoOpt,其Validate()方法明确了各参数的校验规则,可归纳为:
| 校验项 | 规则 | 不满足时的错误 |
|---|---|---|
| bk_obj_id | 不能为空 | CCErrCommParamsNeedSet(参数缺失) |
| bk_obj_id | 不能传业务节点(源码中显式拒绝common.BKInnerObjIDApp;文档同时说明不可为 biz、host) | CCErrCommParamsInvalid(参数非法) |
| bk_inst_id | 必须大于 0 | CCErrCommParamsInvalid |
| fields | 不能为空数组 | CCErrCommParamsNeedSet |
| page | 分页信息必须合法(start、limit有效) | CCErrCommParamsInvalid |
此外,URL 路径中的bk_biz_id会在处理函数入口处被单独解析,要求为合法整数且大于 0,否则返回CCErrCommParamsInvalid(见 FindHostsByTopo)。
关于fields的使用建议:fields决定响应中每台主机返回哪些属性字段。只请求必要的字段(例如仅bk_host_id、bk_host_innerip)可以显著减少查询与传输开销,这在批量拉取大业务主机列表时尤为重要;响应中未列出的内置字段不会返回,用户自定义字段则取决于用户自己定义的属性字段是否包含在fields中。
三、调用示例
按接口文档给出的调用示例(POST 请求体,bk_biz_id=5位于 URL 中):
{ "bk_obj_id": "xxx", "bk_inst_id": 10, "fields": [ "bk_host_id", "bk_cloud_id" ], "page": { "start": 0, "limit": 10 } }说明:接口文档示例中将
bk_biz_id写在请求体中是为了直观展示全部入参;在 API 网关路由POST /api/v3/findmany/hosts/by_topo/biz/{bk_biz_id}下,bk_biz_id以 URL 路径参数形式传入(如/api/v3/findmany/hosts/by_topo/biz/5),服务端从路径参数中解析业务 ID。
其中bk_obj_id: "xxx"应替换为实际的拓扑节点模型 ID,如集群set、模块module,或业务自定义的其他拓扑模型;bk_inst_id为对应节点的实例 ID。
四、响应结构与响应参数说明
响应示例:
{ "result": true, "code": 0, "message": "success", "permission": null, "data": { "count": 2, "info": [ { "bk_cloud_id": 0, "bk_host_id": 1 }, { "bk_cloud_id": 0, "bk_host_id": 2 } ] } }顶层响应参数
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| result | bool | 请求成功与否。true:请求成功;false请求失败 |
| code | int | 错误编码。 0表示success,>0表示失败错误 |
| message | string | 请求失败返回的错误信息 |
| permission | object | 权限信息 |
| data | object | 请求返回的数据 |
data
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| count | int | 记录条数 |
| info | array | 主机实际数据 |
data.info(主机属性字段)
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| bk_host_name | string | 主机名 |
| bk_host_innerip | string | 内网IP |
| bk_host_id | int | 主机ID |
| bk_cloud_id | int | 管控区域 |
| import_from | string | 主机导入来源,以api方式导入为3 |
| bk_asset_id | string | 固资编号 |
| bk_cloud_inst_id | string | 云主机实例ID |
| bk_cloud_vendor | string | 云厂商 |
| bk_cloud_host_status | string | 云主机状态 |
| bk_comment | 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 | 所在国家 |
| operator | string | 主要维护人 |
| bk_bak_operator | string | 备份维护人 |
注意:上表仅对系统内置的属性字段做了说明,其余返回值取决于用户自己定义的属性字段;info中实际返回哪些字段,由请求中的fields决定。
五、源码实现:从拓扑节点到主机列表的完整链路
find_host_by_topo的服务端处理函数为 FindHostsByTopo(host_server),整体流程可以概括为:参数解析 → 校验 → 权限鉴权 → 拓扑节点归一化到 set 层级 → 查询拓扑关系去重主机 ID → 内存分页 → 按 fields 回查主机信息。
5.1 拓扑节点的归一化:set / module / 其他节点
从源码结构看(findhost.go),接口内部将拓扑节点按模型归一化为可直接查询主机拓扑关系的条件DistinctHostIDByTopoRelationRequest:
bk_obj_id为set(集群):直接使用SetIDArr = [bk_inst_id]查询;bk_obj_id为module(模块):直接使用ModuleIDArr = [bk_inst_id]查询;- 其他拓扑模型:调用
Logic.GetSetIDsByTopo沿拓扑向下遍历子节点直到 set(集群)层级,收集该节点下属的全部集群 ID 后作为SetIDArr查询。源码注释也明确了这一意图:“if node is not a set or a module, we need to traverse its child topo to the set level to get hosts by relation”。若遍历后未找到任何 set,则直接返回空结果(count=0、info为空)。
这一设计解释了为什么bk_obj_id可以传“其他 topo 节点上的模型”:只要该节点在拓扑上能下钻到集群,接口就能取到其下挂载的主机;而 biz、host 不满足该前提,故文档明确禁止。
5.2 主机 ID 的去重、分页与字段回查
去重主机 ID 与分页逻辑集中在 findDistinctHostInfo:
- 通过
CoreService().Host().GetDistinctHostIDByTopology从核心服务获取该拓扑条件下的去重主机 ID 全量列表(同一主机在集群下挂多个模块时只计一次); - 对 ID 列表排序后,按
page.start/page.limit做内存分页切片:若start >= 总数则只返回count、info为空;若start + limit越界则收敛到总数; - 用切片出的主机 ID 集合构造条件
bk_host_id IN [...],仅按请求的fields字段回查主机详细信息(SearchHostInfo)。
由此可以明确两个行为细节:响应中的count是该拓扑节点下的主机总数(而非当前页条数),可用于翻页计算;排序按主机 ID 进行,保证多次分页结果的稳定性。
5.3 权限鉴权:业务访问权限如何生效
接口文档标注的“权限:业务访问权限”在源码中的落点是 authHostUnderBiz:处理函数在解析出bk_biz_id后,以“主机实例 + Find 动作 + 业务 ID”构造资源属性,交由AuthManager.Authorize完成业务级(空间级)权限校验,校验失败则返回无权限响应(RespNoAuth)。
该鉴权逻辑适用于一组同族接口(find_module_host_relation、find_host_by_service_template、find_host_by_set_template、list_biz_hosts、list_biz_hosts_topo、find_host_by_topo、list_host_total_mainline_topo),源码注释说明:空间级权限版本中,这几个上 ESB/网关的接口可以通过配置变量决定是否鉴业务访问权限——当配置项authServer.skipViewBizAuth为true时跳过业务访问权限校验(见 findhost.go 鉴权注释 与 init.py 中的对应说明)。集成方若遇到“无权限”响应,可先确认:1)调用方凭据对应的应用是否被授予目标业务的主机访问权限;2)该部署是否通过authServer.skipViewBizAuth调整了鉴权策略。
5.4 网关层的限流与授权
在网关侧(bk_apigw_resources_bk-cmdb.yaml),该资源默认限流为 100 次/秒;allowApplyPermission: true表示未授权应用可走权限申请流程。批量大规模拉取主机时(例如limit=500逐页翻页),建议控制请求节奏并缓存结果,避免触发限流。
六、使用要点与注意事项
- 适用前提:接口自 v3.8.13 起通过 API 网关开放,需要申请“业务访问权限”;请求需携带合法的 bk-app-code / 鉴权凭证,由网关完成认证后转发至 host_server。
- bk_obj_id 约束:可传 set、module 或能下钻到 set 的其他拓扑模型;不可传 biz、host,服务端会对 biz 显式报错。
- fields 必选且影响返回:
fields为空会被Validate()直接拒绝;建议按最小必要字段请求以降低流量。 - 分页上限:
page.limit最大 500,start为记录开始位置;data.count是总数,可据此计算总页数。 - 返回字段:仅请求的
fields中的内置字段会出现在data.info;自定义字段的返回取决于业务自定义属性是否被请求。 - 同族接口:如需主机与拓扑关系的组合信息,可关注同一路由族下的
find_host_relations_with_topo(主机与主线路径拓扑关系)、count_by_topo_node(拓扑节点主机计数)等接口,其注册位置与鉴权策略均与本文接口一致(见 service_initfunc.go)。
七、参考资料(仓库内路径)
- 接口文档:docs/apidoc/apigw/open/zh/find_host_by_topo.md
- 网关资源定义:docs/apidoc/apigw/open/bk_apigw_resources_bk-cmdb.yaml
- 网关授权清单:docs/apidoc/apigw/definition.yaml
- 路由注册:src/scene_server/host_server/service/service_initfunc.go
- 处理函数与分页实现:src/scene_server/host_server/service/findhost.go
- 入参结构与校验:src/common/metadata/hostserver.go
- 后端
- 企业应用
- 运维
【免费下载链接】bk-cmdb
蓝鲸智云配置平台(BlueKing CMDB)
相关推荐
蓝鲸配置平台 bk-cmdb 按拓扑节点查询主机(find_host_by_topo)接口实战指南
蓝鲸配置平台 bk cmdb 按拓扑节点查询主机(find_host_by_topo)接口实战指南 导读 find_host_by_topo 是蓝鲸配置平台(b
后端企业应用运维蓝鲸配置平台 bk-cmdb find_host_relations_with_topo 接口详解:按业务拓扑节点分页查询主机关系
蓝鲸配置平台 bk cmdb find_host_relations_with_topo 接口详解:按业务拓扑节点分页查询主机关系 导读 find_host_r
后端企业应用运维bk-cmdb 业务主线拓扑节点简要关系查询接口(find_brief_biz_topo_node_relation)实战指南
bk cmdb 业务主线拓扑节点简要关系查询接口(find_brief_biz_topo_node_relation)实战指南 导读 本文围绕蓝鲸智云配置平台(
后端企业应用运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考