接口定制
更新时间:2024/11/30
在Gitcode上查看源码

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接口用于查询系统的登录失败锁定(失败次数)和锁定时长(分钟)

json
{
    "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/PagingPath字段表示具体资源协作接口中的对象。Interface字段表示具体对象的接口。Destination表示返回值配置

接口测试

可以使用curl进行Redfish接口的访问和调试,可在Ubuntu环境中运行sudo apt-get install curl进行curl的安装 对于如上配置示例中新增的接口,可以使用如下命令验证其配置

shell
> curl -u *{Account}*:*{Password}* https://*{IP}*/redfish/v1/AccountService/AccountLockout -k

注:此处的-k选项为跳过SSL 检测,防止因证书过期等原因导致接口访问失败 接口访问正确回显为

shell
{"AccountLockoutThreshold": 5, "AccountLockoutDuration": 5}

IPMI接口定制

配置文件位置

OpenUBMC的IPMI接口在各个业务组件内配置实现并实现资源协作接口对象创建。

配置示例

IPMI接口的开发流程为如下三个步骤

  1. 配置业务组件仓的mds/ipmi.json文件
  2. 自动代码生成 bingo gen
  3. 编写并注册回调函数

如下的示例将新增接口实现与上述返回Redfish接口相似的功能,返回系统的登录失败锁定次数和锁定时长

配置mds/ipmi.json文件

mds/ipmi.json文件中“cmd"字段中新增内容

json
{
    "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}*/ipmiipmi_message.luaipmi.lua两个文件中新增内容,并生成一个名字与接口名称对应的文件,在此例中新增了文件GetAccountDuration.lua

编写并注册回调函数

为实现回调函数对如下文件新增内容:

  • user/src/lualib/interface/ipmi/account_service_ipmi.lua文件中新增回调函数
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
lua
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文件中注册回调函数
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命令格式

shell
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命令

shell
> ipmitool -H *{IP}* -I lanplus -p 623 -U *{Account}* -P *{Password}* -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x23

raw代表发送一个RAW(未加工的)IPMI请求

接口访问正确回显为

shell
 db 07 00 05 2c 01

其中05为十六进制表示登录失败锁定次数threshold为5,2c 01表示十六进制012C即表示锁定时长duration为300秒