news 2026/10/23 4:44:37

蓝鲸配置平台(BlueKing CMDB)API 网关 search_objects 模型查询接口详解与源码实现解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
蓝鲸配置平台(BlueKing CMDB)API 网关 search_objects 模型查询接口详解与源码实现解析
  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

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

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

本文围绕蓝鲸智云配置平台(BlueKing CMDB)API 网关开放接口search_objects(查询对象模型,Query models)展开,该接口允许调用方按可选条件(创建人、分类、模型 ID、名称、排序等)检索 CMDB 中的模型元数据,要求具备「模型查看」权限。读完本文,你将掌握该接口的完整请求/响应参数、API 网关侧的限流与鉴权配置,以及从 topo_server 路由到 core service 存储层、再到 IAM 权限校验的完整源码调用链,便于在实际集成中正确调用并排查问题。

一、接口概览

search_objects是 CMDB 通过 API 网关对外暴露的模型查询接口,其基本信息可从网关资源定义文件 bk_apigw_resources_bk-cmdb.yaml 中确认(operationId: search_objects,description 为「查询模型」,descriptionEn: Search objects):

项目取值说明
请求方法POST网关 backend method 为 post
请求路径/api/v3/find/object网关 path 与 backend path 一致
鉴权需要 API 网关鉴权isPublic: false、allowApplyPermission: true,需在网关申请该资源权限
业务权限模型查看权限命中结果后还会做逐模型 IAM 鉴权(见第四节)
限流100 tokens / 1s通过bk-rate-limit插件配置period: 1, tokens: 100
用户实名不强制authConfig.userVerifiedRequired: false

该接口与同目录下其他 150+ 个开放接口文档(如 search_object_topo.md、search_classifications.md)共同构成 CMDB 的开放 API 体系,对应源码实现位于场景服务 topo_server。

二、请求参数

所有请求参数均为可选,参数以 JSON 对象作为请求体提交。官方接口文档(search_objects.md)定义的参数如下:

参数名类型必填说明
creatorstring否数据创建人
modifierstring否数据最后修改人
bk_classification_idstring否模型分类 ID,只能使用字母序列命名
bk_obj_idstring否对象模型 ID,只能使用字母序列命名
bk_obj_namestring否对象模型名称,用于展示,可为任意人类可读语言
obj_sort_numberint否对象模型在对应模型分组内的排序序号

请求示例

{ "creator": "user", "modifier": "user", "bk_classification_id": "test", "bk_obj_id": "biz", "bk_obj_name": "aaa", "obj_sort_number": 1 }

调用示例(通过网关访问):

curl -X POST 'https://{api-gateway-host}/api/v3/find/object' \ -H 'X-Api-Gw-Required: true' \ -H 'Content-Type: application/json' \ -d '{"bk_obj_id": "biz"}'

提示:多个字段同时出现时,服务端将其作为「与(AND)」条件组合过滤;不传任何参数时等同于全量查询(受分页限制,见第四节QueryCondition说明)。

三、响应结构与参数

响应示例

{ "result": true, "code": 0, "message": "", "permission": null, "data": [ { "bk_classification_id": "bk_organization", "create_time": "2018-03-08T11:30:28.005+08:00", "creator": "cc_system", "description": "", "id": 4, "bk_ispaused": false, "ispre": true, "last_time": null, "modifier": "", "bk_obj_icon": "icon-XXX", "bk_obj_id": "XX", "bk_obj_name": "XXX", "position": "{\"test_obj\":{\"x\":-253,\"y\":137}}", "bk_supplier_account": "0", "obj_sort_number": 1 } ] }

响应字段

字段类型说明
resultbool请求是否成功,true成功、false失败
codeint错误码,0表示成功,>0表示失败
messagestring失败时返回的错误信息
permissionobject权限信息(无权限时返回缺少的权限点描述)
dataobject请求返回数据(模型列表)

data 列表元素字段

字段类型说明
idint数据记录 ID
creatorstring数据创建人
modifierstring数据最后修改人
bk_classification_idstring模型分类 ID,只能使用字母序列命名
bk_obj_idstring对象模型 ID,只能使用字母序列命名
bk_obj_namestring对象模型名称,用于展示
bk_supplier_accountstring厂商账号
bk_ispausedbool是否已停用
isprebool是否为预定义(内置)模型,预定义模型一般不允许删除
bk_obj_iconstring对象模型图标信息,供前端展示,取值可参考前端图标资源定义(如icon-XXX)
positionjson object string前端展示用的画布坐标(JSON 字符串,如{"test_obj":{"x":-253,"y":137}})
descriptionstring数据描述
obj_sort_numberint模型在对应模型分组内的排序序号

上述字段与源码中的Object结构体一一对应,见 object.go:

// Object object metadata definition type Object struct { ID int64 `field:"id" json:"id" bson:"id" mapstructure:"id"` ObjCls string `field:"bk_classification_id" json:"bk_classification_id" bson:"bk_classification_id" mapstructure:"bk_classification_id"` ObjIcon string `field:"bk_obj_icon" json:"bk_obj_icon" bson:"bk_obj_icon" mapstructure:"bk_obj_icon"` ObjectID string `field:"bk_obj_id" json:"bk_obj_id" bson:"bk_obj_id" mapstructure:"bk_obj_id"` ObjectName string `field:"bk_obj_name" json:"bk_obj_name" bson:"bk_obj_name" mapstructure:"bk_obj_name"` IsHidden bool `field:"bk_ishidden" json:"bk_ishidden" ...` // 为 true 时前端不展示 IsPre bool `field:"ispre" json:"ispre" ...` IsPaused bool `field:"bk_ispaused" json:"bk_ispaused" ...` Position string `field:"position" json:"position" ...` OwnerID string `field:"bk_supplier_account" json:"bk_supplier_account" ...` Description string `field:"description" json:"description" ...` Creator string `field:"creator" json:"creator" ...` Modifier string `field:"modifier" json:"modifier" ...` CreateTime *Time `field:"create_time" json:"create_time" ...` LastTime *Time `field:"last_time" json:"last_time" ...` ObjSortNumber int64 `field:"obj_sort_number" json:"obj_sort_number" ...` }

可以推断,position与bk_obj_icon、obj_sort_number这类字段主要服务于前端模型管理画布:position记录各模型节点在画布上的坐标,obj_sort_number决定模型在分组中的排列顺序,二者通常由「更新定义」等写接口维护。

四、源码实现链路

4.1 topo_server 路由注册与 SearchObject 处理

topo_server 在 service_business_initfunc.go 中注册该路由:

utility.AddHandler(rest.Action{Verb: http.MethodPost, Path: "/find/object", Handler: s.SearchObject})

SearchObject的完整实现见 object.go:

// SearchObject search some objects by condition func (s *Service) SearchObject(ctx *rest.Contexts) { data := mapstr.New() if err := ctx.DecodeInto(&data); err != nil { ctx.RespAutoError(err) return } query := &metadata.QueryCondition{Condition: data, DisableCounter: true} resp, err := s.Engine.CoreAPI.CoreService().Model().ReadModel(ctx.Kit.Ctx, ctx.Kit.Header, query) if err != nil { ctx.RespAutoError(err) return } // authorize ids := make([]int64, len(resp.Info)) for k, v := range resp.Info { ids[k] = v.ID } authResp, authorized, err := s.AuthManager.HasFindModelAuthUseID(ctx.Kit, ids) if err != nil { ctx.RespAutoError(err) return } if !authorized { ctx.RespNoAuth(authResp) return } ctx.RespEntity(resp.Info) }

从这段实现可以看出几个关键点:

  1. 请求体直接作为精确匹配条件:整个 JSON 请求体被解码进mapstr,再原样塞入QueryCondition.Condition,与「所有参数均为可选、多参数 AND 组合」的接口描述一致;
  2. DisableCounter: true:跳过 count 统计,data直接返回列表而不附带总数;
  3. 先查询、后鉴权:拿到结果后用命中的模型 ID 集合调用 IAM 鉴权,无权限时通过RespNoAuth返回,此时响应中的permission字段会携带缺失的权限信息——这正是响应结构里permission字段的来源。

4.2 到 core service 的 ReadModel 调用

ReadModel是 topo_server 通过 apimachinery 客户端访问 core service 的入口,见 model/api.go:

// ReadModel search object func (m *model) ReadModel(ctx context.Context, h http.Header, input *metadata.QueryCondition) ( *metadata.QueryModelDataResult, error) { resp := new(metadata.ReadModelResult) subPath := "/read/model" err := m.client.Post(). WithContext(ctx). Body(input). SubResourcef(subPath). WithHeaders(h). Do(). Into(resp) ... return &resp.Data, err }

对应地,core service 在 service_initfunc.go 中注册了POST /read/model → SearchModel(实现位于 service/model.go),完成元数据检索。集成测试 model_test.go 也验证了该内部路径的调用方式:client.POST("http://127.0.0.1:3308/api/v3/read/model", ...)。

4.3 QueryCondition:分页与条件语义

QueryCondition定义在 query.go:

type QueryCondition struct { Fields []string `json:"fields"` Page BasePage `json:"page"` Condition mapstr.MapStr `json:"condition"` // 非必填,只能用来查时间,且与Condition是与关系 TimeCondition *TimeCondition `json:"time_condition,omitempty"` DisableCounter bool `json:"disable_counter"` } // IsIllegal limit is illegal, if limit = 0; change to default page size func (qc *QueryCondition) IsIllegal() bool { if qc.Page.Limit == 0 { qc.Page.Limit = common.BKDefaultLimit } if qc.Page.Limit > common.BKMaxPageSize && qc.Page.Limit != common.BKNoLimit { return true } return false }

需要注意:search_objects的公开入参仅支持第二节列出的六个字段,分页参数(page)由QueryCondition框架承载、服务端内部控制,limit为 0 时回落到默认页大小BKDefaultLimit,超过BKMaxPageSize的取值会被判定为非法——也就是说该接口单次返回条数受平台默认分页上限约束,大规模拉取建议按bk_classification_id等条件分批查询。

4.4 权限校验:HasFindModelAuthUseID

search_objects声明的业务权限为「模型查看权限」,其实现位于 ac/extensions/model.go:

// HasFindModelAuthUseID use the id parameter to determine whether you have permission to find the model func (am *AuthManager) HasFindModelAuthUseID(kit *rest.Kit, ids []int64) (*metadata.BaseResp, bool, error) { if !am.Enabled() { return nil, true, nil } if len(ids) == 0 { return nil, true, nil } models, err := am.getSkipFindAttrAuthModelID(kit) ... }

从源码结构看,鉴权流程为:IAM 关闭时直接放行;查询结果为空时直接放行;否则先剔除免鉴权的内置模型 ID,再对剩余 ID 逐个校验「模型查看」权限,任一失败即整体拒绝。因此调用方若看到permission字段非空,通常是申请了对应模型的资源级查看权限即可恢复。

五、使用建议与注意事项

  1. 参数均为精确匹配:bk_obj_name等字段按QueryCondition.Condition的精确匹配语义工作,不是模糊搜索;如需按分类聚合查看,可组合search_classifications(POST /api/v3/find/objectclassification,见 search_classifications.md)先拿到分类再按bk_classification_id过滤。
  2. 命名约束:bk_obj_id、bk_classification_id只能使用字母序列命名,这是模型写接口与读接口的共同约束;bk_obj_name则允许中文等多语言名称,仅用于展示。
  3. ispre字段的实际含义:ispre: true表示预定义(内置)模型,如biz、set、host等核心模型,调用方在消费返回数据时应识别该标记,避免对内置模型做变更类操作。
  4. 网关侧限流:资源级bk-rate-limit配置为每秒 100 tokens(见 bk_apigw_resources_bk-cmdb.yaml),批量任务应控制调用频率,避免触发限流。
  5. 无权限排查:由于鉴权发生在查询之后,code != 0且permission有值时,优先检查调用方账号在 IAM 中是否拥有对应模型的查看权限;permission为空而失败时再考虑参数或网关鉴权问题。

六、相关接口

围绕模型元数据,topo_server 在同一路由文件(service_business_initfunc.go)中还注册了若干近邻接口,可作为search_objects的补充:

接口路径用途
查询模型(含属性)POST /api/v3/find/object/model模型 + 属性一并返回,见 SearchModel
查询对象拓扑POST /api/v3/find/objecttopology查询模型间关联拓扑,见 search_object_topo.md
查询分类POST /api/v3/find/objectclassification查询模型分类列表,见 search_classifications.md
查询属性POST /api/v3/find/objectattr按模型查询其属性定义,见 SearchObjectAttribute

如需查看该接口的权威参数定义,可直接阅读仓库中的接口文档 search_objects.md(英文)与 search_objects.md(中文),二者内容同源。

  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

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

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

相关推荐

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 9:13:18

计算机组成原理存储系统考点拆解:Cache计算与存储器扩展套路

第三章一直是《计算机组成原理》考试的重灾区,也是拉开分数差距的关键章节。白中英这本教材的第三章《存储系统》更是集概念、计算、设计于一体,很多同学卡在这一章的原因,不是看不懂书,而是看到课后题不知道从哪下手。这篇内容不…

作者头像 李华
网站建设 2026/10/23 4:23:14

高通调试工具全攻略:从驱动安装到QFIL烧录与QXDM日志分析

简介:这是一份面向高通平台开发者的调试工具操作手册,围绕QPM、QFIL、Chromatix及ParameterParser等常用工具展开,适合从事高通平台驱动、系统刷机或相机调试的工程师查阅。文档从QPM的官网下载、账号水印文件获取、通行证管理讲起&#xff0…

作者头像 李华
网站建设 2026/10/22 18:18:58

《elisp 每日一练》——文件关联与 Autoload 延迟加载机制

前面的一系列文章中, 我们差不多介绍完了 major mode 相关的一些概念。但是我们还有两个问题没有解决。之前的测试用例需要手动触发mode开启函数,我们需要的是它能根据一定的规则自动开启major mode。而且我们开发的major mode,我只希望在打开对应文件时…

作者头像 李华
网站建设 2026/10/22 12:02:02

关闭主板过载保护?别傻了,试试这招

在 Windows 命令行中,无法直接关闭主板的过载保护功能。主板的过载保护通常由硬件层面(如 BIOS/UEFI)控制,而非操作系统层面。不过,可以通过一些系统设置或命令行操作来尝试缓解因过载保护导致的黑屏问题。 1. 通过命令…

作者头像 李华