The user interface module is at the top layer of the BMC architecture and directly interacts with users. Redfish, Web-Rest, CLI, SNMP, and IPMI interfaces are provided as external interfaces.
Customizing Redfish, Web-Rest, CLI, and SNMP Interfaces
Currently, openUBMC interfaces are implemented using the JSON-based interface mapping configuration. The framework parses the configuration, forwards requests to the resource collaboration interface, and splices and returns the response in the corresponding format. This solution effectively reduces the code development workload and greatly improves the development efficiency.
The following example describes how to customize a Redfish interface. For more configuration requirements, see Interface Mapping Configuration.
Configuration File Location
Configuration files for interfaces customized using the interface mapping configuration are all stored in the rackmount code repository. Based on interface types (Redfish, Web-REST, CLI, or SNMP), the files are located in corresponding subfolders under the mapping_config directory within the interface_config directory. In this example, the Redfish interface configuration files are located at rackmount/interface_config/redfish/mapping_config. The actual path of configuration files is /opt/bmc/apps/redfish/interface_config/mapping_config.
Configuration Example
As shown below, the interface configuration files are located at rackmount/interface_config/redfish/mapping_config/AccountService/AccountLockout.json. The configuration implements a Redfish interface used to query the system's login failure lockout (the lockout threshold upon login failures) and lockout duration (minutes).
{
"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"
}
}
]
}
]
}
]
}Field Description
Resources is a common field for interface mapping configuration. The URI is configured using an array of objects.
URI is used to specify an interface for external access. In this example, external systems can access
https://{IP}/redfish/v1/AccountService/AccountLockout
to query the system's login failure lockout (the lockout threshold upon login failures) and lockout duration (minutes).
Interfaces indicates the interface configuration corresponding to the URI field. It is an object array because multiple request types exist (
GET,PATCH,POST, andDELETEare supported).RspBody indicates the response body configuration, which is the echo when an external system accesses the interface.
${ProcessingFlow[1]/Destination/AccountLockoutThreshold}indicates that data needs to be obtained from the resource collaboration interface. For details, see Interface Mapping Configuration.Statements indicates data processing. The data obtained must be processed before use. In this example, the system lockout duration is retrieved from the resource collaboration interface, but its unit is seconds. Further processing is necessary to convert the unit to minutes. Data processing may be splitted into several steps, corresponding to the array represented by the
Stepsfield. The interface mapping configuration uses several common mechanisms, including type conversion, counting, and prefix/suffix addition. Each mechanism corresponds to theTypefield of an array element. In this example,Scriptindicates a customized processing mode, andFormulaindicates a Lua script that can implement complex processing logic.ProcessingFlow indicates the data source for data mapping configuration of the resource collaboration interface. The
Typefield indicates the mapping type. Currently,Property,Method,List,Task, andPagingare supported. ThePathfield indicates the object in the specific resource collaboration interface. TheInterfacefield indicates the interface of the specific object. TheDestinationfield indicates configuration of the return value.
Interface Test
You can use curl to access and debug Redfish interfaces. In the Ubuntu environment, you can install curl by running sudo apt-get install curl. You can run the following command to verify the configuration of the new interface in the preceding example:
> curl -u *{Account}*:*{Password}* https://*{IP}*/redfish/v1/AccountService/AccountLockout -kNote: The -k option is used to skip SSL detection to prevent interface access failures caused by certificate expiration. The output when the interface is accessed successfully is as follows:
{"AccountLockoutThreshold": 5, "AccountLockoutDuration": 5}IPMI Interface Customization
Configuration File Location
The IPMI interfaces of openUBMC are configured and implemented in each service component to enable object creation for the resource collaboration interface.
Configuration Example
The IPMI interface development process is as follows:
- Configuring the
mds/ipmi.jsonfile in the service component repository - Automatic code generation via
bingo gen - Compiling and registering the callback function
The following example adds an interface to implement the function similar to the Redfish interface in the preceding example, that is, returning the lockout threshold upon login failures and the lockout duration.
Configuring the mds/ipmi.json File
Add the following content to the "cmds" field in the mds/ipmi.json file:
{
"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"
}
]
}
}
}Automatic Code Generation
Run bingo gen in the component repository directory to add content to ipmi_message.lua and ipmi.lua files in gen/*{app_name}*/ipmi of the component repository, and generate a file with the same name as the interface name. In this example, the GetAccountDuration.lua file is added.
Compiling and Registering the Callback Function
Add the following file content to implement callback functions:
- Add a callback function to the
user/src/lualib/interface/ipmi/account_service_ipmi.luafile.
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- In the
user/src/lualib/service/account_service.luafile, the service function obtains the lockout threshold upon login failures and lockout 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
-- Read threshold and duration from the database.
return 5, 300
endNormally, these two values are obtained from the service database. However, since the service code is independent of the interface configuration, the values are hard-coded here for simplicity to demonstrate that the interface configuration works correctly.
- Register the callback function in the
user/src/lualib/account_app.luafile.
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)Interface Test
Generally, ipmitool is used to input IPMI commands. In the Ubuntu environment, you can run sudo apt install ipmitool to install ipmitool.
IPMI Command Format
ipmitool -H <hostname> -I <interface> -p <port> -U <username> -P <password> <command> -C <ciphersuite>I: indicates the IPMI interface.- The lan interface is used by IPMI 1.5. Data is transmitted using UDP on the network. If the command line contains a password, the password will be transmitted in plaintext.
- The lanplus interface is used by IPMI 2.0. Data is transmitted using UDP on the network. If the command line contains a password, the password can be encrypted, which is more secure than the lan interface.
H: indicates a remote service address, which can be an IP address or a host name.U: indicates a remote service username.P: specifies the remote service password in the command line.p: indicates a port.h: obtains help information.C: indicates a cipher suite, which is used for remote server authentication, integrity, and encryption algorithms of IPMIv2 lanplus.
IPMI Command in This Example
> ipmitool -H *{IP}* -I lanplus -p 623 -U *{Account}* -P *{Password}* -C 17 raw 0x30 0x93 0xdb 0x07 0x00 0x23raw indicates that a raw IPMI request is sent.
The correct command output is as follows:
db 07 00 05 2c 0105 is a hexadecimal value, indicating that the lockout threshold upon login failures is 5. 2c 01 represents the hexadecimal value 012C, which corresponds to a lockout duration of 300 seconds.