news 2026/10/13 12:15:28

蓝鲸 CMDB 动态分组更新接口实战:update_dynamic_group 请求参数、条件校验与返回解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
蓝鲸 CMDB 动态分组更新接口实战:update_dynamic_group 请求参数、条件校验与返回解析
  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

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

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

本文基于蓝鲸智云配置平台(BlueKing CMDB,即 bk-cmdb)开源仓库中「更新动态分组(Update Dynamic Group)」接口文档,系统讲解update_dynamic_group的接口定义、请求参数结构(bk_biz_id/id/bk_obj_id/info)、条件类型(锁定条件condition与变量条件variable_condition)以及响应约定,并结合仓库源码深入剖析更新时的参数校验逻辑、算子约束与底层调用链。读者读完可独立完成动态分组的更新请求编写,理解各类校验失败的根因,并掌握该接口在 host_server 与 coreservice 之间的完整流转过程。

接口概述

动态分组(Dynamic Group)是 CMDB 提供的“按条件动态圈定主机/集群资源”的能力:通过一组可复用的查询条件,自动筛选出满足条件的资源实例,并随资源数据变化实时生效。update_dynamic_group用于修改某个业务(bk_biz_id)下已存在的动态分组,包括其目标资源对象类型(bk_obj_id)、查询条件(info)与名称(name)。

  • 接口版本:v3.9.6
  • 所需权限:动态分组编辑权限(Dynamic group editing permission)
  • 请求方式:PUT(见 路由注册,PUT /dynamicgroup/{bk_biz_id}/{id})

从路由注册代码可以确认,同一组动态分组相关动作还包括创建(POST /dynamicgroup)、查询详情(GET /dynamicgroup/{bk_biz_id}/{id})、删除(DELETE /dynamicgroup/{bk_biz_id}/{id})、列表查询(POST /dynamicgroup/search/{bk_biz_id})与执行(POST /dynamicgroup/data/{bk_biz_id}/{id}),更新接口与它们共用同一套 REST 规范。

请求参数详解

公共参数

接口文档以{{ common_args_desc }}占位符表示公共参数,调用时需携带蓝鲸应用标识与用户身份信息,典型字段包括:

字段说明
bk_app_code应用编码,用于标识调用方应用
bk_app_secret应用密钥,与bk_app_code配合完成鉴权
bk_username操作用户名
bk_token用户登录票据(与bk_username可二选一使用,视接入网关配置而定)

接口参数

字段类型必填说明
bk_biz_idint是业务 ID,标识动态分组所属业务
idstring是动态分组主键 ID(创建时由系统生成的 UUID,见后文)
bk_obj_idstring否动态分组目标资源对象类型,目前支持host(主机)与set(集群);当更新规则(info)时,本字段必须与info同时提供
infoobject否通用查询条件,即动态分组的核心条件集合
namestring否动态分组名称

从源码看,bk_biz_id与id会以 URL 路径参数形式传入(核心服务实现 中通过req.PathParameter("bk_biz_id")与req.PathParameter("id")取出),bk_biz_id还会被strconv.ParseInt强转为 int64,非法值会直接报参数错误。

info 字段结构

info是动态分组的条件容器,包含两组条件:

字段类型必填说明
conditionobject否动态分组锁定条件(锁定条件与变量条件至少提供一个)
variable_conditionobject否动态分组变量条件(变量条件与锁定条件至少提供一个)

对应源码中的数据结构为 DynamicGroupInfo:Condition []DynamicGroupInfoCondition与VariableCondition []DynamicGroupInfoCondition。锁定条件与变量条件的核心区别在于:锁定条件在动态分组中固定不变;而变量条件在“执行”动态分组时,允许调用方通过 ExecuteOption 传入新的变量条件值覆盖默认值,实现同一分组针对不同变量取值反复查询,适合“按参数动态筛选”的场景。

info.condition / info.variable_condition

两组条件内部的元素结构完全一致,均为DynamicGroupInfoCondition:

字段类型必填说明
bk_obj_idstring是条件对象资源类型。host 类型动态分组支持set、module、host三类条件对象;set 类型动态分组仅支持set
conditionarray是查询条件数组

源码中DynamicGroupConditionTypes(dynamic_grouping.go)精确复刻了该约束:

  • host动态分组:条件对象集合为{set, module, host};
  • set动态分组:条件对象集合仅为{set}。

若传入不在此集合内的条件对象类型,校验会报错not support condition type[%s] for %s dynamic group。

查询条件元素(condition 数组项)

condition数组中的每一项都是一个字段级查询条件:

字段类型必填说明
fieldstring是对象字段(如bk_host_innerip、bk_parent_id、default等)
operatorstring是比较算子,取值可为$eq(等于)/$ne(不等于)/$in(属于)/$nin(不属于)/$regex(模糊匹配)
valueobject是字段对应的值

对应源码结构 DynamicGroupCondition(Field/Operator/Value)。值得注意的是,仓库源码实际支持的算子比接口文档列举的更多,DynamicGroupOperators(dynamic_grouping.go)中还包含$lte(小于等于)、$gte(大于等于)、$contains与$contains_sensitive等;接口文档所列 5 个算子是最基础、最通用的子集。

更新语义与参数校验规则

更新接口与创建接口不同,采用**部分更新(partial update)**语义:请求体允许只携带需要修改的字段。但 updateGroupParamCheck 的实现定义了明确的规则:

  1. 更新info时必须同时携带bk_obj_id:请求体中若出现info,则bk_obj_id必须存在且为字符串,否则报错bk_obj_id is required in update info condition action;
  2. 只更新bk_obj_id而不带info是不允许的,会报info.condition is required in update bk_obj_id action,即二者必须成对出现;
  3. 仅更新名称:请求体只含name时合法,info与bk_obj_id均不出现即可;
  4. 空更新不被允许:info、bk_obj_id、name都没有时,报empty update content。

更新时,info会被序列化为meta.DynamicGroupInfo并调用dynamicGroupInfo.Validate(objectID, validatefunc)校验,该校验的核心逻辑(ValidDynamicGroupCond)包含:

  • 算子合法性:每个条件项的operator必须位于DynamicGroupOperators中;
  • 字段合法性:field必须是对应条件对象模型上真实存在的属性,否则报not support condition field;
  • 算子与字段类型匹配(Validate 与validateByOperator):
    • 布尔类型(bool)字段只支持$eq;
    • 日期类型(date)字段只支持$gte与$lte;
    • $in/$nin的值必须是数组,且数组元素类型需与字段属性类型一致;
    • $lte/$gte的值必须为数值;
    • $regex的值必须为字符串,且会调用regexp.Compile验证正则表达式合法性(VerifyRegexValidity),非法正则直接拒绝;
    • 服务模板字段(bk_service_template_id)只支持$in算子;
  • 字段类型映射:字符串类属性(单行/多行字符、枚举、时区、用户、列表等)映射为stringType,数值类(int/float/组织/枚举引用)映射为numericType,另有boolType与dateType(getAttributeType);
  • 锁定条件与变量条件字段去重:变量条件中的字段不能与锁定条件重复(cannot set the same field),保证两组条件语义边界清晰;
  • 条件对象类型约束:如前文所述,host分组条件对象只能是set/module/host,set分组只能是set。

请求参数示例(完整可运行)

以下 JSON 为接口文档给出的标准请求示例,更新业务bk_biz_id=1下 ID 为XXXXXXXX的动态分组,将其名称改为my-dynamic-group、目标对象类型明确为host,并同时更新锁定条件与变量条件:

{ "bk_app_code": "esb_test", "bk_app_secret": "xxx", "bk_username": "xxx", "bk_token": "xxx", "bk_biz_id": 1, "id": "XXXXXXXX", "bk_obj_id": "host", "name": "my-dynamic-group", "info": { "condition": [ { "bk_obj_id": "set", "condition": [ { "field": "default", "operator": "$ne", "value": 1 } ] }, { "bk_obj_id": "module", "condition": [ { "field": "default", "operator": "$ne", "value": 1 } ] }, { "bk_obj_id": "host", "condition": [ { "field": "bk_host_innerip", "operator": "$eq", "value": "127.0.0.1" } ] } ], "variable_condition": [ { "bk_obj_id": "set", "condition": [ { "field": "bk_parent_id", "operator": "$ne", "value": 1 } ] }, { "bk_obj_id": "module", "condition": [ { "field": "bk_parent_id", "operator": "$ne", "value": 1 } ] }, { "bk_obj_id": "host", "condition": [ { "field": "bk_host_outerip", "operator": "$eq", "value": "127.0.0.1" } ] } ] } }

示例要点解读:

  • 主机动态分组同时圈定了set、module、host三类对象的条件,三者是“与”关系;
  • default字段的$ne 1表示排除“默认集群/模块”,避免把系统默认资源纳入分组;
  • 锁定条件(condition)与变量条件(variable_condition)字段各不相同(内网 IP vs 外网 IP 等),符合“同对象同字段不可重复设置”的校验规则;
  • 条件对象类型(set/module/host)完全落在 host 动态分组允许的范围内。

返回结果说明

返回结果示例

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

返回参数解释

字段类型说明
resultbool请求是否成功:true 成功;false 失败
codeint错误码:0 表示成功,>0 表示失败对应的错误码
messagestring失败时返回的错误信息
permissionobject权限信息(鉴权失败或无权限时用于引导申请权限)
request_idstring请求链 ID,用于全链路日志追踪排障
dataobject请求返回的数据,更新成功时为空对象{}

源码视角:更新请求的完整调用链

从仓库源码可以完整还原一次动态分组更新的处理链路:

  1. host_server 入口:PUT /dynamicgroup/{bk_biz_id}/{id}由 Service.UpdateDynamicGroup 处理,先解析路径参数bk_biz_id、id,再将请求体DecodeInto为map[string]interface{};
  2. 参数校验:调用updateGroupParamCheck完成上文所述的部分更新语义检查与info条件校验;
  3. 审计日志(前置生成):通过auditlog.NewDynamicGroupAuditLog在事务内生成并保存更新审计日志(审计资源类型为dynamic_group,见 audit.go);
  4. 跨服务调用:经 API 网关客户端(apimachinery 层)向 coreservice 发起PUT /dynamicgroup/{bk_biz_id}/{id}请求;
  5. coreservice 落库:coreService.UpdateDynamicGroup 按{bk_biz_id, id}过滤条件执行 MongoDB 更新,并将modify_user(取自请求头用户)与last_time(UTC 当前时间)自动写入更新数据;数据表为cc_DynamicGroup(见 tablenames.go),其上建有id唯一索引与bk_biz_id + name唯一索引(dynamicgroup.go),因此同一业务下动态分组名称不可重复——这是创建与更新时都需要注意的约束;
  6. 事务保障:步骤 3、4、5 整体由AutoRunTxn包裹,审计与数据更新保持一致性。

常见校验失败场景与排查建议

  • not support operator:operator不在$eq/$ne/$in/$nin/$regex(或源码扩展的$lte/$gte/$contains/$contains_sensitive)范围内,检查拼写与大小写;
  • not support condition field:field不是bk_obj_id指定对象模型上存在的属性,注意区分set/module/host各自的合法字段;
  • operator $in only support array value:$in/$nin的value必须传数组,例如["127.0.0.1","127.0.0.2"];
  • cannot set the same field:变量条件字段与锁定条件字段在“同一条件对象”下重复;
  • not support condition type:对set类型动态分组传入了module或host条件对象;
  • bk_obj_id is required in update info condition action:更新了info却未同时提供bk_obj_id;
  • 正则非法($regex):value无法通过regexp.Compile编译,检查正则语法。

上述大部分错误由 dynamic_grouping.go 中的校验函数直接返回,错误信息与代码一一对应,可在日志中结合request_id快速定位。

相关源码与文档索引

  • 接口文档:update_dynamic_group.md(本文原始依据)
  • 动态分组数据结构与校验:src/common/metadata/dynamic_grouping.go
  • host_server 更新实现:src/scene_server/host_server/service/dynamic_grouping.go
  • coreservice 落库实现:src/source_controller/coreservice/service/dynamic_grouping.go
  • HTTP 路由注册:src/scene_server/host_server/service/service_initfunc.go、src/source_controller/coreservice/service/service_initfunc.go
  • API 网关客户端封装:src/apimachinery/hostserver/apis.go、src/apimachinery/coreservice/host/api.go
  • 数据表与索引:src/common/tablenames.go、src/common/index/collections/dynamicgroup.go
  • 审计类型定义:src/common/metadata/audit.go
  • 前端动态分组表单(提交info.condition/variable_condition结构参考):src/ui/src/views/dynamic-group/form/form.vue
  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

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

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

相关推荐

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

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

MyBatis多表查询:@One/@Many分步查询与延迟加载源码解析

做业务系统久了,你会觉得多表查询这关是真的绕不过去。以前写 JDBC,两个表字段一多,手动一个字段一个字段 set 进对象,能累到怀疑人生。后来换成 MyBatis,用 Map 接收结果集倒是快,可一旦遇到嵌套对象、集合…

作者头像 李华
网站建设 2026/10/13 12:12:01

工厂园区监控安装报价全解析:从点位设计到13%专票

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 12:11:38

Excel SUM函数全解析:从基础求和高阶应用

1. SUM函数本质解析与基础应用在数据处理领域,SUM函数就像会计手中的算盘,是每个数据分析师最先掌握的"生存技能"。这个看似简单的求和工具,实际上蕴含着Excel最基础也最强大的计算逻辑。我至今记得第一次用SUM函数替代手工计算时&…

作者头像 李华
网站建设 2026/10/13 12:10:30

Flask后端工程化实践:从选型到部署的完整指南

每次有人让我推荐 Python 后端框架,我几乎都会先说一句:如果项目没有大到需要一个全家桶框架替你做决定,Flask 会是那个最省心的选择。我自己这几年用 Flask 做过内部管理后台、给前端提供数据的 JSON API、设备上报的数据接收服务&#xff0…

作者头像 李华
网站建设 2026/10/13 12:10:30

纯Native层OpenGL ES实现PNG贴图:从解码到渲染全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华