Redfish定制指南(开发中)
更新时间: 2025/07/22
在Gitcode上查看源码本文主要介绍如何在定制仓定制Redfish服务相关内容
目前Redfish的插件机制主要用于以下两种场景:
- 定制Redfish接口的响应内容,包括响应体和响应头;
- 定制Redfish接口的请求参数,包括请求体、请求头和查询参数。
构建过程搭建
NOTE
下述说明中用<>包裹起来的是变量,变量定义如下:
CUSTOMER: 定制的产商名称
确保定制仓中存在custom_request_response.lua文件,且该文件在bmc上位于:
shell
/opt/bmc/extend/<CUSTOMER>/apps/<CUSTOMER>/plugins/redfish/custom_request_response.lua可参考如下步骤实现:
- 在定制仓中,在
src目录下建立plugins/redfish/custom_request_response.lua文件 - 在
CMakeLists.txt文件中,添加如下命令,用于将定制仓中plugins文件夹以及下面的文件放到/opt/bmc/extend/<CUSTOMER>/apps/<CUSTOMER>/中:
cmake
set(APP_INSTALL_DIR opt/bmc/extend/<CUSTOMER>/apps/<CUSTOMER>)
install(DIRECTORY src/plugins DESTINATION ${APP_INSTALL_DIR} OPTIONAL)定制Redfish接口的响应内容
在custom_request_response.lua文件中返回rsp_postprocess函数,该函数用于实现响应内容定制。
传入参数
| 参数名称 | 参数类型 | 参数说明 |
|---|---|---|
| code | int | HTTP响应码 |
| body | string | 响应体 |
| header | table | 响应头 |
| manufacture | string | 定制化产商名称 |
返回值
NOTE
返回顺序从上往下
| 参数名称 | 参数类型 | 参数说明 |
|---|---|---|
| rsp_body | string | 定制后的响应体 |
| rsp_header | table | 定制后的响应头 |
具体示例
在Redfish响应体里:
- 新增
Status属性; - 在header里面删除
charset=utf-8。
custom_request_response.lua文件示例如下:
lua
local cjson = require 'cjson'
local http = require 'http'
local function rsp_postprocess(code, body, header, manufacture)
local rsp_body
-- 将body转化为table进行定制
if body ~= nil and body ~= '' then
rsp_body = cjson.json_object_ordered_decode(body)
else
rsp_body = cjson.json_object_new_object()
end
if not rsp_body.Oem then
rsp_body.Oem = cjson.json_object_new_object()
end
if not rsp_body.Oem[manufacture] then
rsp_body.Oem[manufacture] = cjson.json_object_new_object()
end
-- 假设-1表示url执行失败
local status = -1
-- 判断响应码是否为2xx,若为2xx且响应体没有错误则设置status的值为0,即成功
if code >= http.HTTP_OK and code < http.HTTP_SPECIAL_RESPONSE then
-- 若是patch接口设置多个请求体,在部分成功时会返回200,同时返回@Message.ExtendedInfo字段展现错误信息。此时也视为失败。
if not rsp_body['@Message.ExtendedInfo'] then
status = 0
end
end
-- 在oem中加上status
rsp_body.Oem[manufacture].Status = status
-- 在响应头中修改Content-Type
local rsp_header = header ~= nil and header or {}
rsp_header['Content-Type'] = 'application/json'
-- 返回时记得将响应体转化为string类型
return cjson.json_object_ordered_encode(rsp_body), rsp_header
end
return {
...
['rsp_postprocess'] = rsp_postprocess
}定制前:
json
// 响应体:
{
...
"oem": {
"openubmc": {
"xxxx": yyyy
}
}
}
// header:
{
"Content-Type": "application/json;charset=utf-8"
}定制后:
json
// 响应体:
{
...
"oem": {
"openubmc": {
"xxxx": yyyy,
"Status": 0
}
}
}
// header:
{
"Content-Type": "application/json"
}定制Redfish接口的请求参数
在custom_request_response.lua文件中返回get_req_param函数,该函数用于实现请求参数定制。具体属性见下表
传入参数
| 参数名称 | 参数类型 | 参数说明 |
|---|---|---|
| req | table | 请求内容,包含body、header、query、url、method和path |
req数据体的定义:
| 参数名称 | 参数类型 | 参数说明 |
|---|---|---|
| body | string | 请求体 |
| header | table | 请求头 |
| query | string | 查询参数 |
| url | string | 资源标识,包含路径和查询参数 |
| method | string | 请求方法 |
| path | string | 路径参数,本次请求的资源路径(不含查询参数) |
返回值
NOTE
返回顺序从上往下
| 参数名称 | 参数类型 | 参数说明 |
|---|---|---|
| req_body | string | 定制后的请求体 |
| req_header | table | 定制后的请求头 |
| req_query | table | 定制后的查询参数 |
具体示例
在Redfish请求体里:
- 修改
DeliveryRetryAttempts属性的输入; - header里面修改
Authorization; - 在查询参数中添加
"$Expand=."。
custom_request_response.lua文件示例如下:
lua
local cjson = require 'cjson'
local urllib = require 'http.url'
local function build_query(params)
local parts = {}
for key, value in pairs(params) do
if type(value) == 'table' then
for _, v in ipairs(value) do
table.insert(parts, tostring(key) .. "=" .. tostring(v))
end
else
table.insert(parts, tostring(key) .. "=" .. tostring(value))
end
end
return table.concat(parts, "&")
end
local function get_req_param(req)
-- 若是请求体中含有DeliveryRetryAttempts属性,则修改为5
local req_body
if req.body == nil or req.body == '' then
req_body = cjson.json_object_new_object()
else
req_body = cjson.json_object_ordered_decode(req.body)
end
if req_body.DeliveryRetryAttempts then
req_body.DeliveryRetryAttempts = 5
end
req_body = cjson.json_object_ordered_encode(req_body)
-- 向请求头中添加Authorization
local req_header = req.header
req_header['Authorization'] = 'Basic xxxxxxxxxx'
-- 向查询参数中添加"$Expand=."
local req_query = req.query
local params = urllib.parse_query(req_query or '')
params['$Expand'] = '.'
req_query = build_query(params)
return req_body, req_header, req_query
end
return {
...
['get_req_param'] = get_req_param
}定制前:
json
// 请求URL:"https://ip/redfish/v1"
//请求体
{
"DeliveryRetryAttempts": 3
}
// header
{
"Authorization": "Basic yyyyyyyyyy"
}定制后:
json
// 请求URL:"https://ip/redfish/v1?$Expand=."
//请求体
{
"DeliveryRetryAttempts": 5
}
// header
{
"Authorization": "Basic xxxxxxxxxx"
}