Interface,用户接口层,处于BMC架构层次的最上层,属于直接与用户交互的模块。提供对外的接口,涉及的主要有Redfish、Web-Rest、CLI、SNMP、IPMI
接口。
Redfish、Web-Rest、CLI、SNMP接口定制
当前openUBMC接口使用接口映射配置实现,通过配置json文件的方式实现接口,框架解析配置,将接口请求转发到资源协作接口,拼装返回对应格式的数据。该方案有效减少代码开发量,大大提高开发效率。
下面以Redfish接口的配置为例说明如何进行接口定制,更多的配置需求可以参考《接口映射配置》。
配置文件位置
使用接口映射配置定制接口的的配置文件统一放在rackmount代码仓,根据接口类型不同(Redfish、Web-Rest、CLI、SNMP)
,配置文件位于interface_config
目录下不同的接口的文件夹中的mapping_config
目录下,本例示范的Redfish接口配置文件在rackmount/interface_config/redfish/mapping_config
中。实际环境上配置文件的路径为/opt/bmc/apps/redfish/interface_config/mapping_config
。
配置示例
如下接口配置其文件路径为rackmount/interface_config/redfish/mapping_config/AccountService/AccountLockout.json
将实现一个Redfish接口用于查询系统的登录失败锁定(失败次数)和锁定时长(分钟)
{
"Resources": [
{
"Uri": "/redfish/v1/AccountService/AccountLockout",
"Interfaces": [
{
"Type": "GET",
"RspBody": {
"AccountLockoutThreshold": "${ProcessingFlow[1]/Destination/AccountLockoutThreshold}",
"AccountLockoutDuration": "${Statements/GetDurationMinutes()}"
},
"Statements": {
"GetDurationMinutes": {
"Steps": [
{
"Type": "Script",
"Formula": "return ProcessingFlow[1].Destination.AccountLockoutDuration // 60"
}
]
}
}
"ProcessingFlow": [
{
"Type": "Property",
"Path": "/bmc/kepler/AccountService/Authentication",
"Interface": "bmc.kepler.AccountService.Authentication",
"Destination": {
"AccountLockoutThreshold": "AccountLockoutThreshold",
"AccountLockoutDuration": "AccountLockoutDuration"
}
}
]
}
]
}
]
}
字段说明
Resources 接口映射配置的通用字段, Uri配置对象数组
Uri 用于指定接口, 外部将通过Uri访问对应接口,此例中外部可通过访问
https://{IP}/redfish/v1/AccountService/AccountLockout
获取系统的登录失败锁定(失败次数)和锁定时长(分钟)
Interfaces Uri所对应的接口配置,由于存在多种Type的请求(支持
GET、PATCH、POST、DELETE
),所以是个对象数组RspBody 响应体配置,作为外部访问接口时的回显,
${ProcessingFlow[1]/Destination/AccountLockoutThreshold}
表示数据需要从资源协作接口获取,详细规则可见《接口映射配置》。Statements 数据处理:拿到数据之后,需要做一些加工操作,才能使用,本例中在资源协作接口中得到了系统锁定时长,但单位为秒,为了将单位转化为分钟,需要进行数据处理。数据处理可以分成多步,对应
Steps
字段表示的数组。接口映射配置机制设置了多种通用机制,例如类型转换,计数,增加前缀和后缀等处理逻辑,对应数组每个元素的Type
字段,本例中的Script
表示自定义处理方式,Formula
的内容是一段Lua脚本,可实现复杂逻辑的处理。ProcessingFlow 数据来源,资源协作接口数据映射配置,
Type
字段表示映射类型,当前支持Property/Method/List/Task/Paging
。Path
字段表示具体资源协作接口中的对象。Interface
字段表示具体对象的接口。Destination
表示返回值配置
接口测试
可以使用curl
进行Redfish接口的访问和调试,可在Ubuntu环境中运行sudo apt-get install curl
进行curl
的安装 对于如上配置示例中新增的接口,可以使用如下命令验证其配置
> curl -u *{Account}*:*{Password}* https://*{IP}*/redfish/v1/AccountService/AccountLockout -k
注:此处的-k
选项为跳过SSL 检测,防止因证书过期等原因导致接口访问失败 接口访问正确回显为
{"AccountLockoutThreshold": 5, "AccountLockoutDuration": 5}
IPMI接口定制
配置文件位置
OpenUBMC的IPMI接口在各个业务组件内配置实现并实现资源协作接口对象创建。
配置示例
IPMI接口的开发流程为如下三个步骤
- 配置业务组件仓的
mds/ipmi.json
文件 - 自动代码生成
bingo gen
- 编写并注册回调函数
如下的示例将新增接口实现与上述返回Redfish接口相似的功能,返回系统的登录失败锁定次数和锁定时长
配置mds/ipmi.json
文件
在mds/ipmi.json
文件中“cmd"
字段中新增内容
{
"package": "AccountIpmiCmds",
"cmds": {
......
"GetAccountDuration": {
"netfn": "0x30",
"cmd": "0x93",
"priority": "Default",
"role": "User",
"privilege": ["ReadOnly"],
"req": [
{
"data": "ManufactureId",
"baseType": "U32",
"len": "3B",
"customizedRule": "Manufacturer"
},
{
"data": "SubCmd",
"baseType": "U8",
"len": "1B",
"value": "0x23"
}
],
"rsp": [
{
"data": "CompletionCode",
"baseType": "U32",
"len": "1B"
},
{
"data": "ManufactureId",
"baseType": "U32",
"len": "3B",
"customizedRule": "Manufacturer"
},
{
"data": "Threshold",
"baseType": "U8",
"len": "1B"
},
{
"data": "Duration",
"baseType": "U16",
"len": "2B"
}
]
}
}
}
自动代码生成
在组件仓目录下运行bingo gen
, 会在组件仓的gen/*{app_name}*/ipmi
下ipmi_message.lua
和ipmi.lua
两个文件中新增内容,并生成一个名字与接口名称对应的文件,在此例中新增了文件GetAccountDuration.lua
编写并注册回调函数
为实现回调函数对如下文件新增内容:
user/src/lualib/interface/ipmi/account_service_ipmi.lua
文件中新增回调函数
function account_service_ipmi:get_account_duration(req, ctx)
local threshold, duration = self.m_account_service:get_ipmi_account_threshold_duration(req, ctx)
local rsp = ipmi_cmds.GetAccountDuration.rsp.new()
rsp.CompletionCode = ipmi_types.Cc.Success
rsp.ManufactureId = utils.get_manufacture_id()
rsp.Threshold = threshold
rsp.Duration = duration
return rsp
end
user/src/lualib/service/account_service.lua
文件中业务函数获取登录失败锁定次数threshold和锁定时长duration
function AccountService:get_ipmi_account_threshold_duration(req, ctx)
local manufacture_id = req.ManufactureId
self.m_account_collection:check_ipmi_host_user_mgnt_enabled(ctx)
if manufacture_id ~= utils.get_manufacture_id() then
error(err:invalid_parameter())
end
-- 从数据库中读取threshold和duration
return 5, 300
end
正常这两个值需要在业务中读取数据库获取,但业务代码与接口配置无关,这里为了简要证明证明接口配置正确,直接硬编码返回值。
user/src/lualib/account_app.lua
文件中注册回调函数
function app:register_ipmi_methods()
......
self:register_ipmi_cmd(ipmi_cmds.GetAccountDuration, function(req, ctx)
return self.account_service_ipmi:get_account_duration(req, ctx)
end)
接口测试
通常使用ipmitool
进行IPMI命令的输入, 可在Ubuntu环境中运行sudo apt install ipmitool
进行ipmitool
的安装
IPMI命令格式
ipmitool -H <hostname> -I <interface> -p <port> -U <username> -P <password> <command> -C <ciphersuite>
I
: 选择使用的IPMI接口- lan, IPMI 1.5版本使用的接口,在网络上使用UDP协议进行数据传输,如果命令行中带有密码,密码会被明文传输.
- lanplus, IPMI 2.0版本使用的接口,在网络上也使用UDP协议进行数据传输,但它可以对密码进行加密处理,安全性较lan高。
H
: 远程服务地址,可以为IP地址或者主机名U
: 远程服务用户名P
: 在命令行中指定远程服务密码p
: 端口h
: 获取帮助信息C
: 密码套件, 用于IPMIv2 lanplus的远程服务器身份验证、完整性和加密算法
本例IPMI命令
> ipmitool -H *{IP}* -I lanplus -p 623 -U *{Account}* -P *{Password}* -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x23
raw
代表发送一个RAW(未加工的)IPMI请求
接口访问正确回显为
db 07 00 05 2c 01
其中05
为十六进制表示登录失败锁定次数threshold为5,2c 01
表示十六进制012C
即表示锁定时长duration为300秒