☰
bk-cmdb 更新进程模板接口(update_proc_template)实战指南:参数详解与源码实现解析
2026/10/14 17:22:40 网站建设 项目流程
  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

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

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

本文基于蓝鲸配置平台(bk-cmdb)官方 API 文档 update_proc_template.md(中文版见 zh_hans),系统讲解"更新进程模板信息"这一接口的请求/响应结构、as_default_value语义、bind_info更新注意事项,并结合仓库源码(proc_server 场景层、coreservice 核心层、metadata 数据结构)剖析其校验逻辑与完整调用链。读完本文,你将能独立构造合规的更新请求、理解每个属性字段的约束边界,并能在排障时快速定位源码位置。

一、功能概述与适用场景

更新进程模板信息是蓝鲸 CMDB 服务模板体系中用于"批量下发进程配置"的关键操作。进程模板(Process Template)隶属于服务模板(Service Template),一个服务模板下可以创建多个进程模板,进程模板再通过服务实例与主机绑定,最终生成真实的进程实例。

本接口完成以下职责:

  • 修改进程模板的通用属性(进程名、功能名、启停命令、进程数量、超时时间等);
  • 修改进程模板的端口绑定信息(bind_info,即 IP/端口/协议绑定规则);
  • 通过as_default_value控制"该字段的值是否以模板为准",从而决定后续由该模板创建的进程实例中,对应字段是否允许被单独修改。

调用本接口需要服务模板编辑权限(Permission: Service Template Editing Permission)。从权限解析器 src/ac/parser/processtemplate.go 可以看到,该接口在访问控制层对应updateProcessTemplatePattern,匹配路径/api/v3/update/proc/proc_template,HTTP 方法为PUT,并通过InstanceIDGetter从请求体中提取process_template_id用于鉴权资源定位;实际鉴权动作由场景层调用AuthorizeByServiceTemplateID(操作类型meta.Update)完成,见 processtemplate.go。

二、接口路由与调用链总览

从路由注册 service.go 可知,本接口对外暴露的路径为:

PUT /api/v3/update/proc/proc_template

完整调用链分为三段:

  1. 场景层(proc_server):PUT /update/proc/proc_template→ UpdateProcessTemplate。该层负责反序列化请求、参数合法性检查(Property非空、ProcessTemplateID > 0)、通过服务模板 ID 做鉴权,并开启事务后调用 coreservice。
  2. 核心层(coreservice):PUT /update/process/process_template/{process_template_id}(见 service_process_initfunc.go)→ processOperation.UpdateProcessTemplate。该层负责读取原模板、合并属性、校验并写库。
  3. 存储层(MongoDB):进程模板数据存储在cc_ProcessTemplate表(common.BKTableNameProcessTemplate)中,更新使用整文档替换方式。

三、请求参数详解

3.1 通用参数(common_args_desc)

所有蓝鲸 CMDB OpenAPI 均需携带鉴权与定位相关的公共参数,本接口与请求示例保持一致,需要传入:

字段类型必选描述
bk_app_codestring是应用 ID,即调用方注册到蓝鲸 ESB 的应用标识
bk_app_secretstring是应用密钥,用于应用级鉴权
bk_usernamestring是用户名,用于用户级鉴权
bk_tokenstring是用户登录态 Token(与bk_username二选一或按环境要求)
bk_biz_idint是业务 ID

3.2 接口参数

字段类型必选描述
process_template_idint是进程模板 ID,必须是业务下已存在的进程模板
process_propertyobject是需要更新的进程模板字段信息,未出现的字段保持不变

其中process_property在元数据结构中对应UpdateProcessTemplateInput.Property,类型为map[string]interface{},见 process.go。process_template_id若小于等于 0,场景层会直接返回CCErrCommHTTPInputInvalid(参数不合法),见 processtemplate.go。

3.3 process_property 可出现的字段

每个字段的值都是如下结构的对象(注意:该结构由value与as_default_value两个子字段构成):

  • value:进程属性的值,不同类型对应不同 Go 类型(数字/字符串/布尔/绑定信息数组);
  • as_default_value:进程的值是否以模板为准。当为true时,由该模板生成的进程实例中该属性不可被单独修改(或只能修改回模板默认值);当为false时,进程实例可以基于此值进行个性化修改。该语义在 PropertyInt64 定义处 有明确的源码注释:如果该属性值被用作默认值,则所有由此进程模板创建的进程实例中该属性都不能被修改,否则只能被修改为这个默认值。
字段类型必选value 类型默认/示例
proc_numobject否number{"value": null, "as_default_value": false},合法范围 [1, 10000]
stop_cmdobject否string{"value": "", "as_default_value": false},停止命令
restart_cmdobject否string{"value": "", "as_default_value": false},重启命令
face_stop_cmdobject否string{"value": "", "as_default_value": false},强制停止命令(源码字段ForceStopCmd,见 process.go)
bk_func_nameobject否string{"value": "a7", "as_default_value": true},进程功能名,必填且不可为空
work_pathobject否string{"value": "", "as_default_value": false},工作目录
priorityobject否number{"value": null, "as_default_value": false},启动优先级,范围 [1, 10000](源码validate:"max=10000,min=1")
reload_cmdobject否string{"value": "", "as_default_value": false},重载命令
bk_process_nameobject否string{"value": "a7", "as_default_value": true},进程别名,必填且不可为空
pid_fileobject否string{"value": "", "as_default_value": false},PID 文件路径
auto_startobject否boolean{"value": null, "as_default_value": null},是否自动启动
auto_time_gapobject否number{"value": null, "as_default_value": false},启动检查间隔;源码中对应字段为StartCheckSecs(JSON 键bk_start_check_secs),范围 [1, 600]
start_cmdobject否string{"value": "", "as_default_value": false},启动命令
bk_func_idobject否string{"value": "", "as_default_value": false},功能 ID。从源码结构看,当前ProcessProperty结构体(process.go)已不包含该字段,传递后不会参与合并,属于历史兼容字段
userobject否string{"value": "", "as_default_value": false},启动用户
timeoutobject否number{"value": null, "as_default_value": false},操作超时时长,范围 [1, 10000]
descriptionobject否string{"value": "1", "as_default_value": true},描述信息
bk_start_param_regexobject否string{"value": "", "as_default_value": false},启动参数正则表达式
bind_infoobject否object{"value":[], "as_default_value": true},端口绑定信息,value 详细见process_property.bind_info.value[n]

说明:上表"默认/示例"列中的取值范围(如proc_num、priority、timeout、auto_time_gap的范围)来自源码中的validate标签与 ProcessProperty.Validate 实现,超出范围将直接返回参数校验错误。

3.4 process_property.bind_info.value[n] 可出现的字段

更新 bind_info 时的重要约束(来自原文档的明确提示):必须先获取原有进程模板的 bind_info 内容,在已有 bind_info 的基础上修改,再将修改后的完整内容传给本接口。因为bind_info是数组型字段,更新时以"整行替换"为粒度,丢失原有行会导致端口绑定信息被覆盖。

字段类型必选value 类型描述
enableobject否boolean{"value": false, "as_default_value": true},该绑定是否启用
ipobject否string{"value": "1", "as_default_value": true},绑定的 IP
portobject否string{"value": "100", "as_default_value": true},绑定的端口(支持单端口、端口区间及逗号分隔多段,格式由正则ProcessPortFormat校验,见 process.go)
protocolobject否string{"value": "1", "as_default_value": true},使用的协议
row_idint否int唯一标识 ID:新加的行可以设置为空(或 0),更新已有行必须保持原值

bind_info在源码中对应ProcPropertyBindInfo结构(process_bind_info.go),其Value数组中的每一行包含RowID、IP、Port、Protocol、Enable五个标准属性。值得注意的是校验逻辑中 row_id 的自动分配规则:若某行RowID为 0,则校验通过后会被自动赋值为当前最大 row_id + 1(见 Validate 实现),因此"新增行时 row_id 可留空"由源码兜底。

四、请求参数完整示例

以下示例来自原文档(原样保留),展示了同时更新进程模板通用属性与绑定信息的完整请求体:

{ "bk_app_code": "esb_test", "bk_app_secret": "xxx", "bk_username": "xxx", "bk_token": "xxx", "bk_biz_id": 1, "process_template_id": 50, "process_property": { "proc_num": { "value": 300, "as_default_value": false }, "stop_cmd": { "value": "", "as_default_value": false }, "restart_cmd": { "value": "", "as_default_value": false }, "face_stop_cmd": { "value": "", "as_default_value": false }, "bk_func_name": { "value": "p1", "as_default_value": true }, "work_path": { "value": "", "as_default_value": false }, "priority": { "value": null, "as_default_value": false }, "reload_cmd": { "value": "", "as_default_value": false }, "bk_process_name": { "value": "p1", "as_default_value": true }, "pid_file": { "value": "", "as_default_value": false }, "auto_start": { "value": false, "as_default_value": false }, "auto_time_gap": { "value": null, "as_default_value": false }, "start_cmd": { "value": "", "as_default_value": false }, "bk_func_id": { "value": null, "as_default_value": false }, "user": { "value": "root100", "as_default_value": false }, "timeout": { "value": null, "as_default_value": false }, "description": { "value": "", "as_default_value": false }, "bk_start_param_regex": { "value": "", "as_default_value": false }, "bind_info": { "value": [ { "enable": { "value": false, "as_default_value": true }, "ip": { "value": "1", "as_default_value": true }, "port": { "value": "100", "as_default_value": true }, "protocol": { "value": "1", "as_default_value": true }, "row_id": 1 } ], "as_default_value": true } } }

五、源码级实现原理:更新是怎么发生的

理解底层实现有助于正确使用本接口,这里剖析 coreservice 层 UpdateProcessTemplate 的五个关键步骤:

  1. 读取原模板:通过GetProcessTemplate按 ID 从cc_ProcessTemplate表读出进程模板(MongoDBFind().One)。若记录不存在返回CCErrCommNotFound。
  2. 反序列化属性:将请求中的process_property(map 类型)通过mapstr.DecodeFromMapStr解码为强类型的ProcessProperty结构,失败返回 JSON 反序列化错误。
  3. 合并字段(Update 方法):调用template.Property.Update(property, rawProperty)。其核心逻辑在 ProcessProperty.Update:
    • 未传递的字段不更新:通过反射检查rawPropertymap 中是否包含该字段的 JSON 键,未包含则直接跳过——这正是"部分更新"能力的来源;
    • 已传递字段整体覆盖:对每个出现的字段,只要value或as_default_value子字段非 nil 就写入新值;
    • bind_info走专门的分支更新(BindInfo.Update),而FuncName(bk_func_name)被放入updateIgnoreField列表跳过——注意这与第 4 步的强制默认值逻辑配合。
  4. 强制模板默认语义:无论请求中bk_process_name、bk_func_name的as_default_value传什么值,代码都会将其强制置为true(isNameDefaultVal := true),保证进程模板的名称类字段始终"以模板为准"(见 process_template.go)。
  5. 唯一性校验并写库:调用processNameUniqueValidate校验"同一服务模板下bk_process_name唯一"以及"bk_func_name+bk_start_param_regex组合唯一",冲突时分别返回CCErrCoreServiceProcessNameDuplicated(错误码 1113019)与CCErrCoreServiceFuncNameDuplicated(错误码 1113020),定义见 errInfo.go;最后整体校验(含必填字段bk_process_name/bk_func_name非空、数值范围、bind_info各行合法性)后整文档更新回 MongoDB,并更新modifier与last_time。

此外,场景层用事务包裹核心层调用(AutoRunTxn),保证更新过程的原子性,见 processtemplate.go。仓库测试 service_template_test.go 中"update process template"用例验证了部分字段更新的行为:仅更新bk_func_name、bk_process_name、bk_start_param_regex时,其余属性保持原值,且bk_func_name/bk_process_name的as_default_value始终为true。

六、返回结果示例

更新成功后返回完整的最新进程模板信息:

{ "result": true, "code": 0, "message": "success", "permission": null, "request_id": "e43da4ef221746868dc4c837d36f3807", "data": { "id": 50, "bk_process_name": "p1", "bk_biz_id": 1, "service_template_id": 51, "property": { "proc_num": { "value": 300, "as_default_value": false }, "stop_cmd": { "value": "", "as_default_value": false }, "restart_cmd": { "value": "", "as_default_value": false }, "face_stop_cmd": { "value": "", "as_default_value": false }, "bk_func_name": { "value": "p1", "as_default_value": true }, "work_path": { "value": "", "as_default_value": false }, "priority": { "value": null, "as_default_value": false }, "reload_cmd": { "value": "", "as_default_value": false }, "bk_process_name": { "value": "p1", "as_default_value": true }, "pid_file": { "value": "", "as_default_value": false }, "auto_start": { "value": false, "as_default_value": false }, "auto_time_gap": { "value": null, "as_default_value": false }, "start_cmd": { "value": "", "as_default_value": false }, "bk_func_id": { "value": null, "as_default_value": false }, "user": { "value": "root100", "as_default_value": false }, "timeout": { "value": null, "as_default_value": false }, "description": { "value": "", "as_default_value": false }, "bk_start_param_regex": { "value": "", "as_default_value": false }, "bind_info": { "value": [ { "enable": { "value": false, "as_default_value": true }, "ip": { "value": "1", "as_default_value": true }, "port": { "value": "100", "as_default_value": true }, "protocol": { "value": "1", "as_default_value": true }, "row_id": 1 } ], "as_default_value": true } }, "creator": "admin", "modifier": "admin", "create_time": "2019-06-19T15:24:04.763+08:00", "last_time": "2019-06-21T16:25:03.962512+08:00", "bk_supplier_account": "0" } }

七、返回结果参数说明

7.1 response 通用结构

字段类型描述
resultbool请求是否成功。true:成功;false:失败
codeint错误编码,0 表示 success,>0 表示失败
messagestring请求失败时返回的错误信息
permissionobject权限信息
request_idstring请求链 ID(可用于链路追踪与排障)
dataobject更新后的进程模板信息

7.2 data 字段说明

data为ProcessTemplate结构(定义见 process.go):

字段类型描述
idint进程模板数据 ID
bk_process_namestring进程别名
bk_biz_idint业务 ID
service_template_idint所属服务模板 ID
propertyobject进程属性(结构与请求process_property一致)
creatorstring本条数据创建者
modifierstring本条数据最后修改人员
create_timestring创建时间
last_timestring更新时间
bk_supplier_accountstring开发商(供应商)账号

八、常见校验失败场景速查

场景源码依据结果
process_property为空 / 缺失processtemplate.go返回参数不合法错误
process_template_id <= 0processtemplate.go返回参数不合法错误
无服务模板编辑权限processtemplate.go返回鉴权失败错误
proc_num/priority/timeout超出 [1, 10000],auto_time_gap超出 [1, 600]process.go校验失败,返回参数错误及具体字段名
bk_process_name/bk_func_name为空process.go校验失败,提示 required 字段
服务模板内进程名重复process_template.go返回CCErrCoreServiceProcessNameDuplicated(1113019)
服务模板内功能名 + 启动参数正则组合重复process_template.go返回CCErrCoreServiceFuncNameDuplicated(1113020)
bind_info中 IP 与协议不匹配 / 端口格式非法process_bind_info.go校验失败,返回具体行号与字段

九、与相邻接口的关系

  • 批量创建进程模板:参考 batch_create_proc_template.md,其bind_info行结构与本接口一致(enable/ip/port/protocol/row_id),创建时 row_id 即为模板行索引;
  • 查询/删除进程模板:分别见 get_proc_template.md、delete_proc_template.md。更新前建议先通过查询接口获取完整的bind_info原文,再按第四节注意事项修改后提交,可有效避免误覆盖端口绑定配置。

十、小结

更新进程模板接口是蓝鲸 CMDB 以"模板驱动实例"模型中的核心写操作:它通过process_property的"未传字段不更新"机制实现精确部分更新,通过as_default_value控制模板默认值对进程实例的约束力,通过bind_info+row_id管理端口绑定行的增量维护。理解其场景层鉴权、coreservice 合并逻辑与数据校验边界后,你既能构造高效、合规的更新请求,也能在异常返回时依据错误码与源码快速定位问题根因。

  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

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

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

相关推荐

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询