Interface Customization
更新时间: 2024/11/30
在Gitcode上查看源码

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).

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"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

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, and DELETE are 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 Steps field. The interface mapping configuration uses several common mechanisms, including type conversion, counting, and prefix/suffix addition. Each mechanism corresponds to the Type field of an array element. In this example, Script indicates a customized processing mode, and Formula indicates a Lua script that can implement complex processing logic.

  • ProcessingFlow indicates the data source for data mapping configuration of the resource collaboration interface. The Type field indicates the mapping type. Currently, Property, Method, List, Task, and Paging are supported. The Path field indicates the object in the specific resource collaboration interface. The Interface field indicates the interface of the specific object. The Destination field 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:

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

Note: 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:

shell
{"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:

  1. Configuring the mds/ipmi.json file in the service component repository
  2. Automatic code generation via bingo gen
  3. 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:

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"
                }
            ]
        }
    }
}

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.lua file.
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
  • In the user/src/lualib/service/account_service.lua file, the service function obtains the lockout threshold upon login failures and lockout 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
    -- Read threshold and duration from the database.
    return 5, 300
end

Normally, 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.lua file.
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)

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

shell
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

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

raw indicates that a raw IPMI request is sent.

The correct command output is as follows:

shell
 db 07 00 05 2c 01

05 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.