北向接口映射器适配指导
更新时间: 2025/11/06
在Gitcode上查看源码

北向接口映射器适配指导

认识北向接口映射器模型

模型设计目标

北向接口是BMC对外提供的标准化管理接口,其核心设计目标是实现硬件资源的抽象化服务化,并支撑上层管理协议与生态伙伴的灵活对接 北向接口映射器是把 BMC 内部的数据映射成BMC对外提供的标准化接口的rackmount模块

主要内容

北向接口映射器提供的北向接口包括:redfish、web-backend、cli、snmp、ipmi 等

代码获取方式:rackmount

配置北向接口方法

配置新接口,需要先获取当前版本对应的代码,首先需要在 manifest.yaml 中找到当前产品使用的是哪个节点的 rackmount 库,下载相应节点代码。

Redfish 接口新增配置方法

Redfish 接口在 rackmount\interface_config\redfish 路径下

举例:需要新增一个社区已有例子 my_app 的 WelcomeMessage 属性的查询接口,当前已包含如下dbus,里面有 WelcomeMessage 属性

text
~ ~ $  busctl --user introspect bmc.kepler.my_app /bmc/demo/MyMDSModel/1 | cat
NAME                                TYPE      SIGNATURE   RESULT/VALUE   FLAGS
bmc.demo.OpenUBMC.Community         interface -           -              -
.GetRepoURL                         method    a{ss}u      s              -
.WelcomeMessage                     property  s           "hello"        emits-change writable
bmc.kepler.Object.Properties        interface -           -              -
...
org.freedesktop.DBus.Introspectable interface -           -              -
.Introspect                         method    -           s              -
org.freedesktop.DBus.ObjectManager  interface -           -              -
.GetManagedObjects                  method    -           a{oa{sa{sv}}}  -
org.freedesktop.DBus.Peer           interface -           -              -
.GetMachineId                       method    -           s              -
.Ping                               method    -           -              -
org.freedesktop.DBus.Properties     interface -           -              -
.Get                                method    ss          v              -
.GetAll                             method    s           a{sv}          -
.Set                                method    ssv         -              -
.PropertiesChanged                  signal    sa{sv}as    -              -

期待的新增路径是 /redfish/v1/Chassis/1/Myapp,需要做如下步骤:

1: 在已有的interface_config/redfish/mapping_config/Chassis/Chassis.json文件中搜索ThresholdSensors,在附近增加

json
    "MyApp": {
        "@odata.id": "/redfish/v1/Chassis/${Uri/chassisid}/MyApp"
    },

目的是在访问 /redfish/v1/Chassis/1 路径时,会显示 MyApp 的链接

2: 在 interface_config\redfish\mapping_config\AccountService\PrivilegeMap\PrivilegeMap.json 文件中搜索 ThresholdSensors,在附近增加

json
{
    "Entity": "MyApp",
    "OperationMap": {
        "GET": [
            {
                "Privilege": [
                    "Login"
                ]
            }
        ]
    }
},

不增加编译时会报错:PrivilegeMap:GET 接口:/redfish/v1/Chassis/{id}/MyApp,类型:MyApp 未配置 PrivilegeMap

3: 新增 interface_config\redfish\mapping_config\Chassis\MyApp.json文件,内容如下

json
{
    "Resources": [
        {
            "Uri": "/redfish/v1/Chassis/:chassisid/MyApp",
            "Interfaces": [
                {
                    "Type": "GET",
                    "ResourceExist": {
                        "${Statements/IsValidChassisId()}": true
                    },
                    "RspBody": {
                        "@odata.context": "/redfish/v1/$metadata#MyApp.MyApp",
                        "@odata.id": "/redfish/v1/Chassis/${Uri/chassisid}/MyApp",
                        "@odata.type": "#MyApp.MyApp",
                        "Id": "MyApp",
                        "Name": "New MyApp Interface",
                        "WelcomeMessage": "${ProcessingFlow[1]/Destination/WelcomeMessage}"

                    },
                    "Statements": {
                        "IsValidChassisId": {
                            "Steps": [
                                {
                                    "Type": "Plugin",
                                    "Formula": "utils.is_valid_chassis_id(Uri.chassisid)"
                                }
                            ]
                        }
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/demo/MyMDSModel/1",
                            "Interface": "bmc.demo.OpenUBMC.Community",
                            "Destination": {
                                "WelcomeMessage": "WelcomeMessage"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

在调用到 /redfish/v1/Chassis/1/MyApp 接口时,会返回 RspBody 里面的内容,根据 ProcessingFlow 里面的 dbus 属性获取 WelcomeMessage 属性的值 其中的 WelcomeMessage 属性的获取来源是 bmc.demo.OpenUBMC.Community 里面的 WelcomeMessage 属性 此处的 @odata 的相关属性是新的,需要新增配置,配置方法见下面步骤

4: 在 interface_config\redfish\static_resource\redfish\v1\jsonschemas\ 路径下,新增 myapp 文件夹,新建 index.json 文件

json
{
    "@odata.context": "/redfish/v1/$metadata#JsonSchemaFile.JsonSchemaFile",
    "@odata.id": "/redfish/v1/JSONSchemas/MyApp",
    "@odata.type": "#JsonSchemaFile.v1_0_2.JsonSchemaFile",
    "Id": "MyApp",
    "Description": "MyApp Schema File Location",
    "Name": "MyApp",
    "Languages": [
        "en"
    ],
    "Schema": "#MyApp.MyApp",
    "Location": [
        {
        "Language": "en",
        "Uri": "/redfish/v1/SchemaStore/en/MyApp.json"
        }
    ]
}

编译MyApp.json时需要找到对应 odata 的静态资源文件,此处的Uri路径要配正确,最后的文件对应的json都是小写的,这里不影响

5: 在 interface_config\redfish\static_resource\redfish\v1\schemastore\en\ 路径下,新增 myapp.json 文件

json
{
    "$schema": "http://redfish.dmtf.org/schemas/v1/redfish-schema.v1_1_0.json",
    "title": "#MyApp.MyApp",
    "$ref": "#/definitions/MyApp",
    "definitions": {
        "MyApp": {
            "anyOf": [
                {
                    "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/idRef"
                },
                {
                    "type": "object",
                    "patternProperties": {
                        "^([a-zA-Z_][a-zA-Z0-9_]*)?@(odata|Redfish|Message|Privileges)\\.[a-zA-Z_][a-zA-Z0-9_.]+$": {
                            "type": [
                                "array",
                                "boolean",
                                "number",
                                "null",
                                "object",
                                "string"
                            ],
                            "description": "This property shall specify a valid odata or Redfish property."
                        }
                    },
                    "additionalProperties": false,
                    "properties": {
                        "@odata.context": {
                            "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/context"
                        },
                        "@odata.id": {
                            "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/id"
                        },
                        "@odata.type": {
                            "$ref": "http://redfish.dmtf.org/schemas/v1/odata.4.0.0.json#/definitions/type"
                        },
                        "Description": {
                            "anyOf": [
                                {
                                    "$ref": "http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Description"
                                },
                                {
                                    "type": "null"
                                }
                            ],
                            "readonly": true
                        },
                        "Name": {
                            "$ref": "http://redfish.dmtf.org/schemas/v1/Resource.json#/definitions/Name",
                            "readonly": true
                        },
                        "WelcomeMessage": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "readonly": true,
                            "description": "The value of this property shall be the name of WelcomeMessage."
                        }
                    }
                }
            ],
            "updatable": false,
            "insertable": false,
            "deletable": false,
            "uris": [
                "/redfish/v1/Chassis/:chassisid/MyApp"
            ],
            "description": "This is myapp resource."
        }
    },
    "copyright": "Copyright © xxx Technologies Co., Ltd. 2018. All rights reserved."
}

WelcomeMessage 属性需要和源接口的属性一致 uris 里面需要填上对应的源接口的 uri

6: 在 interface_config\redfish\static_resource\redfish\v1\schemastore\en\oem\huawei_chassis.json 文件中搜索 ThresholdSensors,在附近增加

json
"MyApp": {
    "$ref": "http://redfish.dmtf.org/schemas/v1/MyApp.json#/definitions/MyApp",
    "readonly": true,
    "description": "A list of MyApp objects.",
    "longDescription": "Show all of the MyApp objects."
},

Chassis.json 文件会关联到 huawei_chassis.json,所以这里也需要添加,否则编译会报错。

7: 编译,在设备上运行后,访问https://ip/redfish/v1/Chassis/1/MyApp就可以得到结果了

json
{
    "@odata.context": "/redfish/v1/$metadata#MyApp.MyApp",
    "@odata.id": "/redfish/v1/Chassis/1/MyApp",
    "@odata.type": "#MyApp.MyApp",
    "Id": "MyApp",
    "Name": "New MyApp Interface",
    "WelcomeMessage": "hello"
}
  • 在访问 /redfish/v1/Chassis/1 路径时,会显示 /redfish/v1/Chassis/1/MyApp 的链接
json
{
    "@odata.context": "/redfish/v1/$metadata#Chassis.Chassis",
    "@odata.id": "/redfish/v1/Chassis/1",
    "@odata.type": "#Chassis.v1_15_7.Chassis",
    "Id": "1",
    "Name": "Computer System Chassis",
    ...
    "Oem": {
        "openUBMC": {
            "ChassisID": null,
            ...
            "ThresholdSensors": {
                "@odata.id": "/redfish/v1/Chassis/1/ThresholdSensors"
            },
            "MyApp": {
                "@odata.id": "/redfish/v1/Chassis/1/MyApp"
            },
            "DiscreteSensors": {
                "@odata.id": "/redfish/v1/Chassis/1/DiscreteSensors"
            },
    ...
        },
    ...
}

Web 接口新增配置方法

Web 接口在 rackmount\interface_config\web_backend 路径下

举例:需要新增一个社区已有的 my_app 的 WelcomeMessage 属性的查询接口,在 System 路径下,期待路径是 /UI/Rest/System/Myapp,需要做如下步骤:

1: 在 interface_config\web_backend\mapping_config\System 目录下,增加 MyApp.json 文件

json
{
    "Resources": [
        {
            "Uri": "/UI/Rest/System/MyApp",
            "Interfaces": [
                {
                    "Type": "GET",
                    "Authentication": {
                        "Condition": false
                    },
                    "RspBody": {
                        "WelcomeMessage": "${ProcessingFlow[1]/Destination/WelcomeMessage}"
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/demo/MyMDSModel/1",
                            "Interface": "bmc.demo.OpenUBMC.Community",
                            "Destination": {
                                "WelcomeMessage": "WelcomeMessage"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

RspBody 中的 WelcomeMessage 和 busctl --user introspect bmc.kepler.my_app /bmc/demo/MyMDSModel/1 | cat 中查询到的 WelcomeMessage 值一致

2: WebUI 验证,使用 postman 访问https://ip/UI/Rest/System/MyApp,使用postman访问时,需要在header页面下添加参数key列下面添加 cookie,对应的value 列填写 cookie 值,这里的cookie 值可以通过浏览器的F12工具查看对应的接口获取, 可以得到正常的结果

json
{
"WelcomeMessage": "Hello"
}

CLI 接口新增配置方法

举例:需要新增一个社区例子里面 my_app 的 WelcomeMessage 属性的查询接口,在 ipmcget -d version 命令下,需要做如下步骤:

1: 在 interface_config\cli\ipmcget\system.json 文件中,搜索 "Uri": "/cli/v1/_/version"

  • 在 RspBody 中增加 WelcomeMessage 字段
json
"WelcomeMessage": "${ProcessingFlow[13]/Destination/WelcomeMessage}",
  • 在 ProcessingFlow 中增加对应的属性映射
json
{
    "Type": "Property",
    "Path": "/bmc/demo/MyMDSModel/1",
    "Interface": "bmc.demo.OpenUBMC.Community",
    "Destination": {
        "WelcomeMessage": "WelcomeMessage"
    }
}

2: 在 interface_config\cli\echoes\ipmcget_version 文件中,搜索 FirmwareInfo.ActiveBMCSDK.Version,在下方增加

json
MYAPP INFO      Version:         {* WelcomeMessage *}

3: 在 SSH 中,使用 ipmcget -d version,即可看到新增的信息在 Active BMCSDK 下方

json
MYAPP INFO      Version:         Hello

常见问题及解决方案

Zone.Identifier 临时文件问题

当一个目录拷贝文件的时候,经常会生成一个 Zone.Identifier 的临时文件,这个文件也会参与编译,编译时会报错

报错内容类似下方报错:

text
ERROR: rackmount/1.90.222@openubmc/rc: Error in build() method, line 37
    MapperCheck.check()
    JSONDecodeError: Expecting value: line 1 column 2 (char 1)

解决办法是,删除相关的 Zone.Identifier 文件,可以使用 git status 命令,看 Untracked files 里面是否有多余的 Zone.Identifier 文件。

JSON 文件调试方法

如果修改多个 JSON 后不清楚哪个 JSON 报错,可以在 mapper_check\MapperCheck.py 文件中增加调试信息,方便找到哪个 JSON 文件报错,下面是git diff结果,请参考修改

text
-    with open(path, 'r', encoding='utf-8') as fp:
-        return json.load(fp)
+    try:
+        print(f"正在读取JSON文件: {path}")
+        with open(path, 'r', encoding='utf-8') as fp:
+            data = json.load(fp)
+        print(f"✅ 成功读取: {path}")
+        return data
+    except Exception as e:
+        print(f"❌ 读取JSON文件失败: {path}")
+        print(f"❌ 错误信息: {e}")
+        # 检查文件是否存在
+        if not os.path.exists(path):
+            print(f"❌ 文件不存在: {path}")
+        else:
+            # 检查文件内容
+            with open(path, 'r', encoding='utf-8') as fp:
+                content = fp.read()
+                print(f"文件内容: {content}")
+        raise

属性获取处理方法ProcessingFlow

如果正常增加的属性 ProcessingFlow 下面的 Type 是 "Property",如果获取的是多个对象,要使用 "List",使用的是方法,要使用 "Method",一个 ProcessingFlow 可以包含多个对象,每个对象有一个下标,下标是从 1 开始的

json
{
    "Type": "Method",
    "Path": "/bmc/kepler/MdbService",
    "Interface": "bmc.kepler.Mdb",
    "Name": "GetPath",
    "Params": [
        "bmc.kepler.Systems.FruData.Overview",
        {
            "FruId": 0
        },
        false
    ],
    "Destination": {
        "Path": "Path"
    }
},

属性获取处理方法Statements,里面可以再包含

如果 D-Bus 上的数据需要处理,需要使用 Statements,里面可以再包含 ProcessingFlow

json
"Steps": [
    {
        "Type": "Plugin",
        "Formula": "orchestrator.bios.get_registry_version(Uri.systemid)"
    }

Formula 的内容是一段 Lua 脚本,可实现任何复杂逻辑的处理,支持入参,入参可使用 ReqBody 等数据来源。

Plugin 可实现复杂逻辑的业务处理(不推荐与其他处理类型叠加使用)。

以 Redfish 为例,当前 Redfish 插件的存放目录为 /opt/bmc/apps/redfish/interface_config/plugins,那么上述配置要求,在存放目录下有文件 orchestrator\bios.lua,并且文件有函数 get_registry_version。

Redfish URI 配置问题

配置 Redfish 接口时,会遇到 URI 报错,实际上是 "@odata.context","@odata.id","@odata.type" 这几个配置的有问题,需检查修改

结语

参考文档: