Multi-Level Interface Customization for Products
更新时间: 2025/07/21
在Gitcode上查看源码

The Redfish, CLI, and SNMP interfaces in the openUBMC community are implemented through Interface Mapping Configuration, achieving separation between service processes and interface configuration.

The general interface configuration provided by the community can satisfy the requirements of most scenarios, but it is difficult to quickly meet customization needs for specific models or exclusive customer scenarios. Therefore, the interface mapping configuration needs a mechanism to support extension, tailoring, and renaming at the interface or property level to ensure that differentiated code is minimized as much as possible.

Three-Level Customization Capability

openUBMC Community Edition

General basic capabilities provided by the community edition, applicable to most general community scenarios.

Product Commercial Edition

Provides the capability for different hardware forms of models to differentiate from the platform. Categorized by model product series, platform configurations and model customization configurations are merged during the model product .

Customer Customization Edition

Provides the capability for end-user differentiation customization. The HPM firmware contains all customer customization content, categorized by customer, and customization configurations are merged according to the customized customer name during the

Typical Scenario Cases

ScenarioType
Differentiated configurations for racks, cabinets, and management boardsIntegration of interface components of the corresponding openUBMC community edition
OEM URI accepted by the communityIntegration of interface components of the corresponding openUBMC community edition
Intelligent computing models requiring specialized XPU O&M interfacesDifferentiated customization of product commercial editions
Removing the corresponding URI from a model without the USB functionDifferentiated customization of product commercial editions
Replacement of the OEM vendor for the Redfish interfaceBatch field replacement for product commercial editions
Replacement of the OEM OID prefix for the OID of the SNMP interfaceBatch field replacement for product commercial editions
Web APIs starting with special characters required by a customer customized modelDifferentiated customization of customer customized editions
Certain fields to be added to the standard interface for a customer customized modelDifferentiated customization of customer customized editions

Interface Configuration Strategy

IMPORTANT

Although the current mechanism provides product customization and customer customization capabilities to satisfy most usage scenarios, the long-term maintainability is poor. It is recommended that customization requirements be abstracted into general features and that community acceptance be sought whenever possible.

Customization Configuration Syntax

General Format

The main configuration file in the interface_config directory is config.json. The configuration format is as follows:

json
{
    "Uri.Actions": {
        "Remove": [],
        "Copy": [],
        "Rename": []
    },
    "Property.Actions": [
        {
            "Target": "./Managers/NICs/NICs.json",
            "Uri": "/redfish/v1/Managers/:managerid/NICs",
            "Method": "GET",
            "Remove": [],
            "Modify": {},
            "Rename": {}
        }
    ],
    "GlobalVariable": {
        "OemIdentifier": "openUBMC"
    }
}
  • Uri.Actions: interface-level customization
    • Remove: Interface tailoring
    • Copy: interface extension
    • Rename: interface renaming
  • Property.Actions: property-level customization
    • Target: target file
    • Uri: target URI
    • Method: target method
    • Remove: property tailoring
    • Modify: property extension
    • Rename: property renaming
  • GlobalVariable: replacement relationships for batch field replacement
    • Custom key: internal variable to be replaced
    • Custom value: string value to replace with

Interface-Level Customization

Remove: Interface Tailoring

json
"Remove": [
    {
        "Target": "ipmcget/sol.json",
        "Uri": "/cli/v1/sol/info",
        "Method": ["GET"]
    }
]

Remove is an object array, where each object identifies an instance to be tailored. Interface tailoring involves four scenarios:

  • Tailoring all interface configurations in the entire directory

    Target indicates the directory to be tailored. The Uri and Method fields are empty.

  • Tailoring interface configurations in a single file

    This scenario is similar to scenario 1 except that Target is a file path.

  • Tailoring a specific interface in a file

    Target is a file path, Uri specifies the interface, and Method is empty.

  • Tailoring a specific method of a specific interface in a file

    Target is a file path, Uri specifies the interface, and Method can specify multiple methods.

NOTE

Target uses relative paths. For example, Target of a CLI interface is relative to the basic configuration path xxx/opt/bmc/apps/cli/interface_config.

Source is similar, relative to the customization configuration path.


Copy: Interface Extension

json
"Copy": [
    {
        "Source": "ipmcset/user.json",
        "Target": "ipmcset/user.json"
    }
]

Copy is an object array, where each object identifies an extension instance. It copies the path from Source to Target. Source and Target can be both files or directories. Assuming "Source": "aa/bb/cc", "Target": "xx/yy/zz", whether the paths are files or directories, the meaning is to copy cc from the aa/bb directory to the xx/yy directory as zz.


Rename: Interface Renaming

json
"Rename": [
    {
        "Target": "ipmcset/dft.json",
        "OriginUri": "/cli/v1/maintenance/download",
        "NewUri": "/cli/v1/maintenance/download2"
    }
]

Rename is an object array, where each object identifies a rename instance. It renames the OriginUri interface in the Target path to NewUri. In the preceding configuration, the interface is changed to /cli/v1/maintenance/download2.


Property-Level Customization

json
"Property.Actions": [
    {
        "Target": "ipmcget/target.json",
        "Uri": "/cli/v1/_/bootdevice",
        "Method": "GET",
        "Remove": [
            "RspBody/BootSourceOverrideTarget"
        ],
        "Modify": {
            "RspBody": {
                "Version": "${Statements/GetVersion()}"
            },
            "Statements": {
                "GetVersion": {
                    "Input": "${ProcessingFlow[1]/Destination/Version}",
                    "Steps": [
                        {
                            "Type": "Convert",
                            "Formula": "StringToNumber"
                        }
                    ]
                }
            },
            "ProcessingFlow": [
                {
                    "Type": "Property",
                    "Path": "/bmc/kepler/Systems/1/Bios",
                    "Interface": "bmc.kepler.Systems.Bios",
                    "Destination": {
                        "Version": "Version"
                    }
                }
            ],
            "Rename": {
                "Usage": "Instruction"
            }
        }
    }
]

Property.Actions is an object array, where each object represents an instance of property-level customization. Target, Uri, and Method are used to specify the file, interface, and method to be customized. Note the following:

  • Properties here are not just request body or response body properties, but also properties of the interface JSON object to be customized.
  • Property-level customization should be kept as simple as possible so that changes are obvious at a glance. For complex changes, interface-level customization is recommended.

Remove: Property Tailoring

Remove is a string array, where each element indicates the property to be tailored. It can be a multi-level property where each level is separated by /. For example, RspBody/BootSourceOverrideTarget will delete the BootSourceOverrideTarget property of the RspBody subobject.


Modify: Property Extension

Modify is an object that needs to be merged with the original interface configuration object. It is essentially a merge of two JSON objects, with the following strategies:

  1. For nodes with complex types, including objects and arrays, an append approach is used.
  2. For nodes with simple types, an overwrite approach is used.
  3. ProcessingFlow: When an appended ProcessingFlow elements is referenced, its index needs to be incremented by the size of the ProcessingFlow array of the original object. (This operation is automatically performed by the script.)

Rename: Property Renaming

Rename is an object, where each pair of key-value represents the original and new property names. The original property name can be a multi-level property where each level is separated by /.


Comparison Before and After Customization

The preceding configuration is used as an example. Assume that the original interface is as follows:

json
{
    "Resources": [
        {
            "Uri": "/cli/v1/_/bootdevice",
            "Interfaces": [
                {
                    "Type": "GET",
                    "Description": "Get boot device",
                    "Usage": "ipmcget -d bootdevice",
                    "RspBody": {
                        "BootSourceOverrideTarget": "${ProcessingFlow[1]/Destination/value1}",
                        "BootSourceOverrideEnabled": "${ProcessingFlow[1]/Destination/value2}"
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/Systems/1/BootOptions",
                            "Interface": "bmc.kepler.Systems.BootOptions",
                            "Destination": {
                                "BootSourceOverrideTarget": "value1",
                                "BootSourceOverrideEnabled": "value2"
                            }
                        }
                    ],
                    "Echoes": [
                        "ipmcget/_bootdevice"
                    ]
                }
            ]
        }
    ]
}

The configuration after customization is:

json
{
    "Resources": [
        {
            "Uri": "/cli/v1/_/bootdevice",
            "Interfaces": [
                {
                    "Type": "GET",
                    "Description": "Get boot device",
                    "Usage": "ipmcget -d bootdevice",
                    "RspBody": {
                        "BootSourceOverrideEnabled": "${ProcessingFlow[1]/Destination/value2}",
                        "Version": "${Statements/GetVersion()}"
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/Systems/1/BootOptions",
                            "Interface": "bmc.kepler.Systems.BootOptions",
                            "Destination": {
                                "BootSourceOverrideTarget": "value1",
                                "BootSourceOverrideEnabled": "value2"
                            }
                        },
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/Systems/1/Bios",
                            "Interface": "bmc.kepler.Systems.Bios",
                            "Destination": {
                                "Version": "Version"
                            }
                        }
                    ],
                    "Statements": {
                        "GetVersion": {
                            "Input": "${ProcessingFlow[1]/Destination/Version}",
                            "Steps": [
                                {
                                    "Type": "Convert",
                                    "Formula": "StringToNumber"
                                }
                            ]
                        }
                    },
                    "Echoes": [
                        "ipmcget/_bootdevice"
                    ]
                }
            ]
        }
    ]
}

Batch Field Replacement

The mapper introduces the {{var}} usage, where a string surrounded by two pairs of consecutive curly braces represents an internal variable. Based on the mapping relationship configured in the main configuration file config.json, the mapper replaces these internal variables with specified strings during interface initialization (batch field replacement for Redfish schemas occurs during interface access). The replacement scope includes JSON configuration files in mapping_config, Lua scripts and plugins in script and plugins, and schema files for Redfish interfaces.


Replacement Relationship Configuration

In the main configuration file config.json in the interface_config directory, there is a GlobalVariable property at the same level as the preceding interface/property-level customizations, used to represent the replacement relationship for batch field replacement of the current interface. Configuration reference: The configuration is as follows:

json
"GlobalVariable": {
    "OemIdentifier": "openUBMC"
}

This configuration indicates that {{OemIdentifier}} in the mapper configuration is replaced with openUBMC.

Configurations can be set for the openUBMC community edition, product commercial edition, and customer customization edition. The customer customization edition takes highest priority, followed by the product commercial edition and, finally, the openUBMC community edition. The openUBMC community edition must ensure all internal variables have a default replacement relationship. During the build, bingo merges the configurations of the openUBMC community edition and product commercial edition. During interface initialization, the mapper merges the customer customization edition with the openUBMC community edition/product commercial edition configuration based on the current customization customer to obtain the final replacement relationship and replaces all mapper configurations for that interface type.

IMPORTANT

Since batch field replacement occurs after interface/property-level customization is completed, fields designed for replacement in the interface/property-level customization configuration must also be represented using the {{var}} format to ensure that batch field replacement after multi-level customization works correctly.


Current Default Configuration

The following uses some default configurations of the current openUBMC community edition as an example to describe some configurations of the Redfish interface in the openUBMC community edition:

json
"GlobalVariable": {
    "OemIdentifier": "openUBMC"
}

Some openUBMC community edition configurations of the SNMP interface:

json
"GlobalVariable": {
    "SnmpOemIdentifier": "2011.2.235.1.1"
}

The openUBMC field in existing mapper configurations for Redfish interfaces has been rectified to {{OemIdentifier}}, and 2011.2.235.1.1 in SNMP interface OIDs has been replaced with {{SnmpOemIdentifier}}. During subsequent incremental development of Redfish and SNMP interfaces, note that the openUBMC string should be replaced with {{OemIdentifier}}, and 2011.2.235.1.1 in SNMP interface OIDs should be replaced with {{SnmpOemIdentifier}}. In addition, when developing Lua code for plugins and scripts, do not use variable names and function names containing sensitive fields.


Precautions

The Redfish interface itself has a vendor name replacement mechanism for OEM fields, specifically by setting a customization vendor name through the BMCSet_RedfishCustomManuName equipment customization item. Its effectiveness takes precedence over the batch field replacement function of multi-level customization. Simultaneously, the priority of vendor replacement is:

  1. Manufacturer customized during the equipment customization stage (BMCSet_RedfishCustomManuName) has the highest priority.
  2. If Manufacturer is not customized (empty or openUBMC), the next priority is OemIdentifier in config.json of the customer customization edition configuration enabled by customer customization (BMCSet_PackageCustomer);
  3. If Customer is also not customized, OemIdentifier in config.json of the openUBMC community edition/product commercial edition configuration takes effect.
  4. If none of them takes effect, the openUBMC configuration is used by default.

Obtaining Multi-Level Customization Configuration Files

openUBMC Community and Product Commercial Level Interface Configuration Files

Perform a personal build in manifest (without the -t option or adding -t personal). The generated compressed interface configuration file is in the output/packet/inner/interface_config directory. After decompression, you can obtain the interface configuration equivalent to that in the running environment. The Product file is for the product type specified during the build, and other files are interface configurations generated after adding customer customizations under that product type.