产品多层级接口定制
更新时间:2025/07/21
在Gitcode上查看源码

openUBMC社区的Redfish、CLI、SNMP接口是通过接口映射配置实现,实现业务流程和接口配置的分离。

社区提供的通用接口配置,可以满足绝大部分场景的诉求,但针对部分机型、专有客户场景的定制化诉求难以快速满足。因此接口映射配置需要一种机制支持接口级或属性级的扩展、裁剪、重命名处理,确保差异化代码尽可能最小化。

三层定制能力

openUBMC社区发行版

社区发行版提供的通用基础能力,适用于社区大部份通用场景。

产品商用发行版

提供不同硬件形态的机型相对平台进行差异化定制的能力,按机型产品系列分类,在机型产品合并平台配置和机型定制配置。

客户定制发行版

提供最终用户差异化定制的能力,HPM固件包含所有客户定制内容,按客户分类,在根据定制客户名合并定制配置。

典型场景案例

场景类型
机架、机柜、管理板的接口差异配置集成对应的openUBMC社区发行版接口组件
被社区接纳的OEM Uri集成对应的openUBMC社区发行版接口组件
智算机型,需要专门XPU运维接口产品商用发行版差异化定制
某款无USB功能的机型,移除对应Uri产品商用发行版差异化定制
Redfish接口需要将OEM厂商名进行替换产品商用发行版批量字段替换
SNMP接口的oid需要将OEM oid前缀替换产品商用发行版批量字段替换
某客户定制机型,需要特殊字符开头的Web API接口客户专属定制发行版差异化定制
某客户定制机型,需要在标准接口中新增某些字段客户专属定制发行版差异化定制

接口配置策略

IMPORTANT

虽然目前机制提供了产品定制、客户定制能力,能满足大部分场景使用,但长期可维护性较差。推荐尽可能将定制诉求抽象为特性并寻求社区接纳。

定制配置语法

通用格式

interface_config目录下的主配置文件为config.json,其配置格式为:

json
{
    "Uri.Actions": {
        "Remove": [],
        "Copy": [],
        "Rename": []
    },
    "Property.Actions": [
        {
            "Target": "./Managers/NICs/NICs.json",
            "Uri": "/redfish/v1/Managers/:managerid/NICs",
            "Method": "GET",
            "Remove": [],
            "Modify": {},
            "Rename": {}
        }
    ],
    "GlobalVariable": {
        "OemIdentifier": "openUBMC"
    }
}
  • Uri.Actions: 接口层级的定制
    • Remove: 接口裁剪
    • Copy: 接口拓展
    • Rename: 接口重命名
  • Property.Actions: 属性层级的定制
    • Target: 目标文件
    • Uri: 目标Uri
    • Method: 目标方法
    • Remove: 属性裁剪
    • Modify: 属性拓展
    • Rename: 属性重命名
  • GlobalVariable: 批量字段替换的替换关系
    • 自定义key: 被替换的内部变量
    • 自定义value: 替换为的字符串取值

接口层级定制

接口裁剪 Remove

json
"Remove": [
    {
        "Target": "ipmcget/sol.json",
        "Uri": "/cli/v1/sol/info",
        "Method": ["GET"]
    }
]

Remove为对象数组,每个对象标识裁剪的实例,接口裁剪分四种场景:

  • 裁剪整个目录下所有的接口配置

    Target为待裁剪的目录,UriMethod字段为空

  • 裁剪单个文件下接口配置

    与场景1类似,不同的是Target为文件路径

  • 裁剪文件下的指定接口

    Target为文件路径,Uri指定接口,Method为空

  • 裁剪文件下的指定接口的确定方法

    Target为文件路径,Uri指定接口,Method可指定多个方法

NOTE

Target均采用相对路径的方式,例如cli接口是相对基础配置路径xxx/opt/bmc/apps/cli/interface_config,下同。

Source类似,相对定制配置路径。


接口拓展 Copy

json
"Copy": [
    {
        "Source": "ipmcset/user.json",
        "Target": "ipmcset/user.json"
    }
]

Copy为对象数组,每个对象标识拓展的实例,是将Source的路径复制到TargetSourceTarget可同时为文件或者目录 假设"Source": "aa/bb/cc", "Target": "xx/yy/zz",不管是文件还是目录,表征的意义都是将cc从目录aa/bb复制到xx/yy目录,并且重命名为zz


接口重命名 Rename

json
"Rename": [
    {
        "Target": "ipmcset/dft.json",
        "OriginUri": "/cli/v1/maintenance/download",
        "NewUri": "/cli/v1/maintenance/download2"
    }
]

Rename为对象数组,每个对象标识重命名的实例,是将Target路径下的OriginUri接口重命名为NewUri,如上述配置,接口变成/cli/v1/maintenance/download2


属性层级定制

json
"Property.Actions": [
    {
        "Target": "ipmcget/target.json",
        "Uri": "/cli/v1/_/bootdevice",
        "Method": "GET",
        "Remove": [
            "RspBody/BootSourceOverrideTarget"
        ],
        "Modify": {
            "RspBody": {
                "Version": "${Statements/GetVersion()}"
            },
            "Statements": {
                "GetVersion": {
                    "Input": "${ProcessingFlow[1]/Destination/Version}",
                    "Steps": [
                        {
                            "Type": "Convert",
                            "Formula": "StringToNumber"
                        }
                    ]
                }
            },
            "ProcessingFlow": [
                {
                    "Type": "Property",
                    "Path": "/bmc/kepler/Systems/1/Bios",
                    "Interface": "bmc.kepler.Systems.Bios",
                    "Destination": {
                        "Version": "Version"
                    }
                }
            ],
            "Rename": {
                "Usage": "Instruction"
            }
        }
    }
]

Property.Actions是对象数组,每个对象表示属性层级定制的实例。TargetUriMethod用于确认待定制的指定文件、指定接口、指定方法 这里需要特别强调:

  • 这里的属性不仅是请求体属性、响应体属性,应该是指待定制的接口JSON对象的属性
  • 属性层级的定制应尽可能简单,一眼就能看出变化,复杂的推荐直接使用接口层级定制

属性裁剪 Remove

Remove是字符串数组,每个元素表征待裁剪的属性,可以是多级属性,用/分隔,例如RspBody/BootSourceOverrideTarget,会删除子对象RspBodyBootSourceOverrideTarget属性


属性拓展 Modify

Modify是对象,需要与原接口配置对象做合并,本质是两个JSON对象的合并,策略如下:

  1. 节点是复杂类型,包括对象、数组,采用追加方式
  2. 节点是简单类型,采用覆盖方式
  3. 特殊的ProcessingFlow: 对于引用追加的ProcessingFlow元素时,其下表需要加上原始对象的ProcessingFlow数组大小(脚本会自动处理,无需配置者处理)

属性重命名 Rename

Rename是对象,每对key-value表示待重命名的原属性名和新属性名,原属性名可以是多级属性,一样是/分隔


定制前后对比

以上述配置为例,假设原接口为:

json
{
    "Resources": [
        {
            "Uri": "/cli/v1/_/bootdevice",
            "Interfaces": [
                {
                    "Type": "GET",
                    "Description": "Get boot device",
                    "Usage": "ipmcget -d bootdevice",
                    "RspBody": {
                        "BootSourceOverrideTarget": "${ProcessingFlow[1]/Destination/value1}",
                        "BootSourceOverrideEnabled": "${ProcessingFlow[1]/Destination/value2}"
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/Systems/1/BootOptions",
                            "Interface": "bmc.kepler.Systems.BootOptions",
                            "Destination": {
                                "BootSourceOverrideTarget": "value1",
                                "BootSourceOverrideEnabled": "value2"
                            }
                        }
                    ],
                    "Echoes": [
                        "ipmcget/_bootdevice"
                    ]
                }
            ]
        }
    ]
}

定制后的配置为:

json
{
    "Resources": [
        {
            "Uri": "/cli/v1/_/bootdevice",
            "Interfaces": [
                {
                    "Type": "GET",
                    "Description": "Get boot device",
                    "Usage": "ipmcget -d bootdevice",
                    "RspBody": {
                        "BootSourceOverrideEnabled": "${ProcessingFlow[1]/Destination/value2}",
                        "Version": "${Statements/GetVersion()}"
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/Systems/1/BootOptions",
                            "Interface": "bmc.kepler.Systems.BootOptions",
                            "Destination": {
                                "BootSourceOverrideTarget": "value1",
                                "BootSourceOverrideEnabled": "value2"
                            }
                        },
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/Systems/1/Bios",
                            "Interface": "bmc.kepler.Systems.Bios",
                            "Destination": {
                                "Version": "Version"
                            }
                        }
                    ],
                    "Statements": {
                        "GetVersion": {
                            "Input": "${ProcessingFlow[1]/Destination/Version}",
                            "Steps": [
                                {
                                    "Type": "Convert",
                                    "Formula": "StringToNumber"
                                }
                            ]
                        }
                    },
                    "Echoes": [
                        "ipmcget/_bootdevice"
                    ]
                }
            ]
        }
    ]
}

批量字段替换

映射器引入{{var}}的用法,用两对连续大括号包围的字符串,表示是内部变量。根据在主配置文件config.json中配置的映射关系,映射器在初始化接口时将这些内部变量替换为指定的字符串(Redfish schema的批量字段替换是在访问接口时)。替换范围包括mapping_config的JSON配置文件,script和plugins的lua脚本和插件,以及Redfish接口的schema文件


替换关系配置

interface_config目录下的主配置文件config.json中,有一个GlobalVariable属性与上述接口/属性层级定制平级,用于表示当前接口的批量字段替换的替换关系。配置参考如下:

json
"GlobalVariable": {
    "OemIdentifier": "openUBMC"
}

该配置即表示将映射器配置中的{{OemIdentifier}}替换为openUBMC

openUBMC社区发行版、产品商用发行版、客户定制发行版均可配置,其中配置关系为客户定制发行版 > 产品商用发行版 > openUBMC社区发行版。openUBMC社区发行版需要保证所有内部变量有一个默认的替换关系,在构建时,bingo会将openUBMC社区发行版和产品商用发行版的配置合并;接口初始化时,映射器会根据当前定制的客户将客户定制发行版与openUBMC社区发行版/产品商用发行版的配置合并得到最终的替换关系,并对该接口类型的所有映射器配置进行替换。

IMPORTANT

由于批量字段替换在接口/属性层级定制完成后进行,因此接口/属性层级定制的配置中需要设计替换的字段也要使用{{var}}格式的内部变量表示,确保层级定制后的批量字段替换正常。


当前部分默认配置

以当前openUBMC社区发行版的部分默认配置为例,Redfish接口的部分openUBMC社区发行版配置:

json
"GlobalVariable": {
    "OemIdentifier": "openUBMC"
}

snmp接口的部分openUBMC社区发行版配置:

json
"GlobalVariable": {
    "SnmpOemIdentifier": "2011.2.235.1.1"
}

当前已将存量映射器配置中的Redfish接口的openUBMC字段整改为{{OemIdentifier}}snmp接口的oid中的2011.2.235.1.1替换为{{SnmpOemIdentifier}}。后续增量开发Redfish接口和snmp接口时需要注意,涉及openUBMC字样的替换为{{OemIdentifier}}snmp接口的oid中的2011.2.235.1.1替换为{{SnmpOemIdentifier}}。另外开发插件、脚本的lua代码时注意不要使用带敏感字段的变量名和函数名


使用注意事项

Redfish接口自身存在厂商名替换机制替换OEM字段,具体是通过BMCSet_RedfishCustomManuName装备定制化项设置替换的厂商名,生其生效优先级高于多层级定制的批量字段替换功能,同时使用时需要注意厂商替换生效的优先级是:

  1. 装备定制化阶段(BMCSet_RedfishCustomManuName)定制的Manufacturer优先级最高;
  2. Manufacturer未定制(为空或openUBMC),次优先级为Customer定制(BMCSet_PackageCustomer)生效的客户定制发行版配置的config.json内的OemIdentifier
  3. 若客户Customer也未定制,则构建openUBMC社区发行版/产品商用发行版配置的config.json内的OemIdentifier生效;
  4. 若都未生效,默认使用openUBMC.

多层级定制配置文件获取

openUBMC社区、产品商用层级接口配置文件获取

在manifest下执行个人构建(不加-t参数或添加-t personal),生成的接口配置压缩文件在目录output/packet/inner/interface_config下,解压后获取与环境中运行状态等效的接口配置。 Product文件为构建时指定的产品类型,其他文件为该产品类型下,添加客户定制化后生成的接口配置。