Interface Mapping Configuration
更新时间: 2024/12/19
在Gitcode上查看源码

Considering the interconnection with resource collaboration interfaces based on interface definitions, configuration and mapping are introduced to design northbound interfaces (Redfish, Web-backend, CLI, and SNMP) in openUBMC, where an interface mapping configuration mechanism is used. The mechanism parses interface configuration frameworks, maps interface requests to resource collaboration interfaces, and assembles the returned data in corresponding formats. The interface mapping configuration mechanism has the following features:

  1. Easy customization: Encapsulate interface protocols and use standard resource collaboration interfaces to implement interface configuration.
  2. Efficient expansion: Use abstract interface data models, establish mapping rules, and modify configurations to expand interfaces.
  3. Service decoupling: Decouple interfaces from function logic to prevent incorrect interface invocation from affecting service functions.

This document describes configuration rules for common interface mapping. Some rules apply only to a single interface. For details, see the corresponding interface configuration guide.

Interface Support

InterfaceDescription
RedfishMachine-machine interface, used to connect to the upper-layer network management system (NMS)
Web_backendProvides backend service support for the web frontend.
SNMPMachine-machine interface, used to connect to early NMS and gradually replaced by Redfish
CLIMan-machine interface, used by users to directly operate devices

Keywords

Mapping Keywords

KeywordTypeScope of ApplicationDescription
ResourcesarrayAllResource collection. Each element in an array describes a resource.
Resources.UristringAll1. Redfish/Web_backend: The original URI remains unchanged.
2. CLI: The URI starts with /cli/v1. The parameters following -t and -d are the third and fourth segments of the route, respectively. If -t does not exist, use _ instead.
3. SNMP: The URI starts with /snmp/v1. The OID is the third segment, the command name is the fourth segment, and the read-write mode is the fifth segment.
Resources.IgnoreEtagsarrayRedfishProperty collection without ETag validation. This field has to be used for shielding when frequently changing properties. Otherwise, the PATCH execution will fail due to property changes.
Resources.ResourceExistobjectAllConfiguration of resource existence validation process, validating whether dynamic fields in a URI are valid.
The key is the data source definition, and the value is the expected validation result.
If the value is #WITH, the expected result is that the data exists. If the value is #WITHOUT, the expected result is that the data does not exist. Other fields indicate the actual expected results.
Resources.SequencearraySNMPSequence field configuration, used to define data in the object scenario of the SNMP interface
Sequence.NamestringSNMPName of an object property. The value is the same as that defined in the MIB file.
Sequence.TypestringSNMPType of an object property, which is the same as that defined in the MIB file. The value can be string, number, integer, object, array or boolean.
Sequence.AccessstringSNMPAccess permission of an object property, which is the same as that defined in the MIB file. The value can be Readonly or Readwrite.
Sequence.PrimarybooleanSNMPIndicates whether an object property is the primary key. Multiple properties in the same object may be set as primary keys. The configuration information of this field is the same as that in the MIB file.
Resources.InterfacesarrayAllResource method collection, including GET, PATCH, POST, and DELETE. The method mapping type of a single resource is configured as required. Only one method can be configured for each resource.
Interfaces.TypestringAllMethod type. The value can be GET, PATCH, POST or DELETE (case insensitive). The details are as follows:
1. Redfish/Web_backend: GET, PATCH, POST and DELETE
2. CLI: GET and PATCH. ipmcget corresponds to GET, and ipmcset corresponds to PATCH.
3. SNMP: GET and PATCH, corresponding to the obtaining and setting operations, respectively
Interfaces.LockdownAllowbooleanAllIndicates whether setting interfaces (PATCH/POST/DELETE) can be executed when the system is locked. After the system is locked, operations can only be performed when the value of this configuration is true.
Interfaces.UsagestringCLIIf the entered CLI command can uniquely match a specified command, but the parameter following -v does not match, the usage method of the command has to be displayed. This field describes the correct command format.
Interfaces.BriefstringCLIIf the entered CLI command can uniquely match a specified command, but the parameter following -v does not match, the brief description of the command has to be displayed. The description has to be configured in this field, or it will not be displayed.
Interfaces.ExamplesarrayCLIIf the entered CLI command can uniquely match a specified command, but the parameter following -v does not match, the usage example of the command has to be displayed. The example information has to be configured in this field (configuration of multiple examples supported), or it will not be displayed.
Interfaces.DescriptionstringCLIIf the entered CLI command does not match any specified command, commands that are closest to the current input are listed. The description of each command comes from this field.
Interfaces.EchoesarrayCLITemplate path for displaying data on a client
Interfaces.ReqBodystringAllRequest body definition of a method. Nested configuration is supported for properties, and the next-level properties are described using the keyword Properties.
ReqBody.NamestringAllProperty name in a request message body, which is the same as that defined in the external interface.
ReqBody.Type[string, array]AllProperty type in a request message body, which is the same as that defined in the external interface. The value of this field can be string, number, integer, object, array, boolean, or null.
If the field type is array, the property value can be of multiple types.
ReqBody.Items[object, array]AllDefines array elements when a request message body property is an array.
The list validation mode array (with a same definition for array elements) can use the object type. The definition takes effect for all properties in the array.
The tuple validation mode array (with various definitions for array elements) can use the array type. The definition index corresponds to each index in the request message body property.
ReqBody.maxItemsnumberAllDefines the maximum number of array elements when a request message body property is an array.
ReqBody.minItemsnumberAllDefines the minimum number of array elements when a request message body property is an array.
ReqBody.uniqueItemsbooleanAllDefines that each array element is unique when a request message body property is an array. By default, arrays can contain duplicate elements.
ReqBody.PropertiesobjectAllCollection of the next-level properties of the current property in a request message body
ReqBody.LockdownAllowbooleanAllFunctions the same as the Interfaces.LockdownAllow field. This field modifies a single property in the PATCH interface, instead of the entire interface.
ReqBody.RequiredbooleanAllIndicates whether a request message body property is mandatory.
ReqBody.DescriptionstringCLIIf the entered CLI command can uniquely match a specified command, but the parameter following -v does not match, the description of the parameter following -v has to be displayed. The description has to be configured in this field, or it will not be displayed.
ReqBody.SensitivebooleanAllIndicates whether a request message body property is sensitive. Sensitive information is replaced by ****** in error information.
ReqBody.ValidatorarrayAllValidation rules for a request message body property. The property value is valid only when all validation rules in an array are met.
Interfaces.QueryobjectAllConfigures default query parameters.
There are restrictions on using Redfish query parameters.
Interfaces.RspBodyobjectAllResponse body of a method
Interfaces.StatementsobjectAllDefinition of statements for data processing
Statements.x.Input[string, array]AllSource definition of the data to be processed
Statements.x.StepsarrayAllProcessing process definition, executed in the defined sequence in an array. The execution result of the previous step is the input of the next step.
Interfaces.ProcessingFlowarrayAllEntry of the resource collaboration interface, executed in the defined sequence in an array.
ProcessingFlow.PathstringAllPath of the resource collaboration interface, supporting dynamic parameters
ProcessingFlow.InterfacestringAllResource collaboration interface
ProcessingFlow.DestinationobjectAllData destination area of the resource collaboration interface, through which data is stored in the temporary storage area. Key: property name of the resource collaboration interface; value: property name of the temporary data storage area
ProcessingFlow.SourceobjectAllData source area of the resource collaboration interface, where data from the defined source is stored. Key: property name of the resource collaboration interface; value: data source definition
ProcessingFlow.NamestringAllName of the resource collaboration interface method
ProcessingFlow.ParamsarrayAllInput parameters of the resource collaboration interface method, the sequence of which is the same as that of the parameters defined in an array
ProcessingFlow.CallIf[object, string]AllDynamically determines the ProcessingFlow execution mode, which can be object or string.
1. Object: The key is the data source definition, and the value is the expected validation result. If the value is #WITH, the expected result is that the data exists. If the value is #WITHOUT, the expected result is that the data does not exist. Other fields indicate the actual expected results. The usage of this mode is the same as Resources.ResourceExist.
2. String: Use the preset execution mode, which is currently as follows:
· CheckUri: executed during resource existence validation, providing data in the temporary storage area
ProcessingFlow.ForeachstringAllIterates arrays. #INDEX indicates the current number of iterations. Use ${<Array path>[#INDEX]} to reference the array elements of the current iteration.
Interfaces.AuthenticationobjectCLIDescribes whether the command requires authentication. If this keyword is configured, a command will prompt the user to enter the password, and authentication will be performed automatically.
Interfaces.ConfirmobjectCLIDescribes whether the command requires re-confirmation. If this keyword is configured, a command will prompt the user to complete confirmation.
Authentication.Description
Confirm.Description
stringCLIUser interaction prompt
Authentication.Condition
Confirm.Condition
stringCLIChecks the parameter following -v. The interaction is performed if the result is true. The default value of this field is true.
If this field is set to false, the Confirm keyword is used preferentially.

Mapping Symbols

KeywordDescription
${...}Data is referenced to a variable in the full path mode. The data sources include Uri, ReqBody, Statements, ProcessingFlow[...]/Destination, and Foreach.
Examples:
· ${Uri/Id}
· ${ReqBody/IpAddr}
· ${Statements/GetId()}
· ${ProcessingFlow[1]/Destination/Name}
[...]Array reference. Array variables can be referenced by subscript. In the Foreach scenario, #INDEX indicates the current iteration.
Example: ${Statements/GetPath()[#INDEX]}
()Used when invoking Statements
/Lower-level property reference
{{...}}Global data reference. The referenced data is configured in the config.json file of the interface.
Example: {{OemIdentifier}}
#WITHIndicates a resource exists in data validation.
#WITHOUTIndicates a resource does not exist in data validation.

Statements Keywords

KeywordDescription
Prefix-AddAdds the prefix configured in Formula.
Prefix-TrimDeletes the prefix configured in Formula.
Suffix-AddAdds the suffix configured in Formula.
Suffix-TrimDeletes the suffix configured in Formula.
CountNumber of elements contained in input properties
ConvertConverts the data type. The conversion mode is configured in Formula. Conversion modes: NumberToBool, BoolToNumber, NumberToString, StringToNumber, FloatToInteger, ToHex, and Tohex
DateFormatConverts a timestamp to a date in a specified format. Formula is the array type. The first parameter indicates the specified date format, and the second parameter indicates whether to display the local time zone.
L-PairProcesses array type data and Formula in pairs. The string in Formula serves as the key and the array element serves as the value to assemble an object.
SwitchReplaces data. Formula defines the array of replacement rules, where From is a matching item, and To is a replacement item. The rule without a matching item is the default rule.
If the input data meets any matching item, it is converted to the replacement item in the replacement rule. Data that does not meet any matching item is considered to meet the default rule. If there is no default rule, the data is not replaced.
ExpandThe input data serves as URIs for resource expansion. The input URI can be an internal URI. Formula indicates the number of expansion layers. Currently, openUBMC supports only one-layer expansion, that is, Formula is 1.
ScriptScript-based custom rules, generally used when the code is simple and not coupled with services. Formula indicates the path of the code or the file where the code is located.
The global variables that can be used in code include string, math, type, table, ipairs, pairs, next, error, base_messages, custom_messages, tonumber, tostring, cjson, null, lua_nil, Uri, ReqBody, Query, Context, ProcessingFlow, and Input.
PluginPlugin-based custom rules, generally used for coupled and heavy-load services. Formula is the form of "FileName.FunctionName(...)", where FileName indicates the plugin file name, FunctionName indicates the function name defined in plugins, and ... is the function input parameter.
The function input parameter supports the following keywords: Uri, ReqBody, Query, Context, ProcessingFlow, and Input.
Global variables that can be used in the plugin code include bus, mdb, require, libroutemapper_utils, mapper_interface, string, math, type, table, ipairs, pairs, next, pcall, xpcall, error, base_messages, custom_messages, tonumber, tostring, cjson, null, and lua_nil.

Validator Keywords

KeywordDescription
RangeApplies to the integer and number types. Validates the property value range, which includes maximum and minimum values.
LengthApplies to the string type. Validates the string length limit, which includes maximum and minimum values.
EnumApplies to the integer, number, and string types. Validates the property enumeration type.
NonemptyApplies to the string type. Validates whether a property is a non-empty string.
IPFormatApplies to the string type. Validates whether a property is in the IP address format.
RegexApplies to the string type. Validates whether a property meets the regular expression matching rule.
ScriptScript-based custom validation rule

General Format

General format of interface mapping configuration:

json
{
    "Resources": [
        {
            "Uri": "xxxx",
            "Interfaces": [
                {
                    "Type": "GET/PATCH/POST/DELETE",
                    "ResourceExist": {xxxx},
                    "ReqBody": {xxxx},
                    "RspBody": {xxxx},
                    "RspHeader": {xxxx},
                    "Statements": {xxxx},
                    "ProcessingFlow": [xxxx]
                }
            ]
        }
    ]
}
  • Resources: URI configuration object array
  • Interfaces: request configuration array of multiple Types corresponding to a URI
  • Type: request method, which can be GET, PATCH, POST, or DELETE
  • ResourceExist: URI validation
  • ReqBody: request body configuration
  • RspBody: response body configuration
  • RspHeader: response header configuration
  • Statements: data processing
  • ProcessingFlow: mapping configuration for resource collaboration interfaces

URI Validation

URI configuration uses dynamic fields to specify a resource among resources of the same type. Therefore, the URI access validity has to be validated based on whether the resource exists, which functions equally as the interface input parameter validation. For example, in "Uri": "/redfish/v1/Managers/:managersid", :managersid is a dynamic parameter. For rack-mounted models, the valid value is 1. An external system has to access the URI /redfish/v1/Managers/1 to access the correct interface.

json
"ResourceExist": {
    "${Uri/managersid}": "1",
    "${Statements/GetName()}": "#WITH",
    "${ProcessingFlow[1]/Destination/Valid}": true
}

If key==value is determined in each key-value pair configured in the ResourceExist field, the input parameter validation succeeds, all resource existence conditions are met, and the URI validation is successful. In the preceding example, the value of Uri/managersid must be "1" to determine fixed results. Additionally, two other conditions have to be met. #WITH and #WITHOUT indicate whether a property is nil; true and false serve as the determination rules for the bool type value.
The URI validation succeeds only when all the following conditions are met: The value of Uri/managersid is "1", Statements/GetName() is not nil, and the value of ProcessingFlow[1]/Destination/Valid is true. (When the ProcessingFlow configuration is directly or indirectly referenced by ResourceExist, add the configuration "CallIf": "CheckUri".) Note: The PATCH interface invokes the corresponding GET interface before processing. Therefore, ResourceExist does not need to be configured for PATCH.

ReqBody Declaration

A request sent by users may contain a request body. Since the request body is entered by users, the data may not always match the expected format in actual use. For example, a property type must be string, but the user enters a number instead. Therefore, a syntax is required to declare the data content of the request body and perform basic validation on the request body format. Here, ReqBody is used for declaration. (ReqBody declaration is similar to the syntax standards in the JSON Schema official document.)
The following request body is used as an example (assuming UserName is mandatory and can only be set to Administrator or root):

json
{
    "UserName": "root"
}

The corresponding ReqBody configuration is as follows:

json
"ReqBody": {
    "Type": "object",
    "Required": true,
    "Properties": {
        "UserName": {
            "Type": "string",
            "Required": true,
            "Validator": [
                {
                    "Type": "Enum",
                    "Formula": ["Administrator", "root"]
                }
            ]
        }
    }
}

The following describes the rule configuration for request body validation.

Integrity Check

The keyword Required declares whether a request body property is mandatory. The value is true/false, and the default value is false if not configured.

json
"ReqBody": {
    "Type": "object",
    "Required": true,
    "Properties": {
        "PropA": {
            "Required": true
        },
        "PropB": {
            "Required": false
        },
        "PropC": {
            "Type": "object",
            "Properties": {
                "Prop1": {
                    "Required": true
                }
            }
        }
    }
}

For example, in the preceding declaration, the request body is valid if it is{"PropA": 1} or {"PropA": 1, "PropB": 2} (integrity check not required for PropC/Prop1 if the PropC object does not exist). The request body is not valid if it is {"PropA": 1, "PropC": {}} or {"PropB": 2}, as the former lacks PropC/Prop1 and the latter lacks PropA.

Data Type Validation

The Type keyword is the foundation of data type validation and can be a string or an array.

  • If it is a string, it must be a specified data type. The value can be array, boolean, integer, number, null, object, or string.
  • If it is an array of strings, it contains multiple types, with each string specifying a basic type. Each element is unique. In this case, the request body data has to match any of the element types.
json
"ReqBody": {
    "Type": "object",
    "Required": true,
    "Properties": {
        "PropA": {
            "Type": "string"
        },
        "PropB": {
            "Type": ["number", "boolean"]
        }
    }
}

For example, in the preceding declaration, the request body {"PropA": "str", "PropB": 1} is valid, and {"PropA": 1, "PropB": "str"} is not valid. The PropA type must be string, and the PropB type can be number or boolean.
In addition to the basic types that are easy to understand, such as boolean, integer, number, null, and string, the following describes the composite types object and array.

Object

object is a mapping type in JSON, which maps keys to values. In JSON, the keys must always be strings. Each of these pairs is usually referred to as a property. The object properties (key-value pairs) are defined using the Properties keyword. The value of Properties is an object array. Each array element is used to declare property features. Keywords such as Type and Required can also be used to configure data types and integrity checks.

Array

Arrays are used for ordered elements. In JSON, each element in an array may be of a different type, and there are two ways in which arrays are generally used:

List validation: a sequence of arbitrary length where each element matches the same schema
Tuple validation: a sequence of fixed length where each element may have a different schema

  • List validation: A list contains keywords such as Items, minItems, maxItems, and uniqueItems.

    Items: Defines single-element validation in a list. Keywords such as Type can be used.
    maxItems: Defines the maximum number of elements in a list, which is not validated by default.
    minItems: Defines the minimum number of elements in a list, which is not validated by default.
    uniqueItems: Defines whether each array element must be unique. If the value is set to true, each array element must be unique. If it is set to false, an array can contain duplicate elements. The default value is false.

    json
    "ReqBody": {
        "Type": "object",
        "Required": true,
        "Properties": {
            "PropA": {
                "Type": "array",
                "Items": {
                    "Type": "number"
                },
                "minItems": 2,
                "maxItems": 5,
                "uniqueItems": true
            }
        }
    }

    In the preceding configuration, the PropA property is an array, where each element is a number. The array contains at least two elements and at most five elements. Each element is unique.

  • Tuple validation

    Tuple validation is useful when the array is a collection of elements where each has a different schema. For example, a 3-tuple [ID, user name, locked or not] has a different schema for each field:

    Id: ID, which must be a number
    UserName: user name, which must be a string
    Locked: locked or not, which must be a boolean value (true/false)

    The Items keyword is set to an array, where each element is a schema corresponding to each index of the tuple. That is, the first element in an array validates the first input element, the second element validates the second input element, and so on.

    json
    "ReqBody": [
    {
        "Name": "PropA",
        "Type": "array",
        "Items": [
            {
                "Type": "number"
            },
            {
                "Type": "string"
            },
            {
                "Type": "boolean"
            }
        ]
    },
    ]

In the preceding example, if the value of PropA is [10086, 10001, true], it is not valid, as the second element must be a string, but 10001 is a number. [10086, "root", true], [10086, "root"], and [10086, "root", true, "str"] are valid.

Data Content Validator

Sometimes, simple validation is required for the content of request body properties. For example, the string length must be within a specified range or a group of fixed values. Here, the Validator keyword declares the validation of the related content. The validation type is represented by the Type field. The following sections describe the supported Type.

json
{
    "Name": "Prop",
    "Validator": [
        {
            "Type": xxx,
            "Formula": xxx
        }
    ]
}

Enum

json
{
    "Type": "Enum",
    "Formula": ["Administrator", "root", "Admin"]
}

Enumeration validation. Formula configures value arrays within a specified range. Each element in the array is unique. This can validate simple data types, such as boolean, integer, number, null, and string. (Complex structures like object or array can also be configured, but are not recommended. The complex structures must be declared.)

Length

json
{
    "Type": "Length",
    "Formula": [1, 16]
}

Validates the string length. Formula specifies the upper and lower limits (closed interval). If no limits are required, set it to null.

Nonempty

json
{
    "Type": "Nonempty"
}

Non-empty string validation. The value "" is not valid.

Range

json
{
    "Type": "Range",
    "Formula": [1, 16]
}

Number range validation, which can be used for the integer and number data types. Formula specifies the upper and lower limits (closed interval). If no limits are required, set it to null.

Regex

json
{
    "Type": "Regex",
    "Formula": "^xx[0-9]"
}

Regular expression matching validation (standard regular expressions, not Lua regular expressions), which can be used for the string data type. In the preceding example, the value "xx1" is valid, while "xxx" is not valid.

IPFormat

json
{
    "Type": "IPFormat",
}

IP address format validation, which can be used for the string data type

Script

json
{
    "Type": "Script",
    "Formula": "if Input % 5 == 0 then local err = base_messages.PropertyValueFormatError(Input, PropertyName) err.RelatedProperties = {'#/' .. PropertyName} error(err) end return true"
}

Reuses the Script in data processing. For details about the usage rules, see Data Processing Statements. If the validation fails, execute error to throw the errors, which must be common errors defined by BMC. If the validation succeeds, return true or nil. Compared with the data processing Script, the environment variables are changed as follows:

  • Input: value of the property to be validated
  • PropertyName: new variable, indicating the name of the property to be validated, for example, Oem/openubmc/PropA
  • ProcessingFlow: The resource collaboration interface is not accessed during validation. Therefore, this variable is deleted.

Sensitive Information Masking

If a request body contains sensitive data, the field value in the error message must be masked as ******. The Sensitive keyword is introduced to indicate that the property value has to be masked, preventing sensitive data from being directly displayed in the Message information. Sensitive information must be configured with "Sensitive": true. Sensitive information in openUBMC includes but is not limited to user passwords and session tokens.

json
"ReqBody": {
    "Type": "object",
    "Required": true,
    "Properties": {
        "Password": {
            "Type": "string",
            "Sensitive": true
        }
    }
}

If the request body value is {"Password": 111}, the type validation fails. The obtained error information is as follows:

json
"MessageId": "Base.1.0.PropertyValueTypeError",
"Message": "The value ****** for the property Password is of a different type than the property can accept.",
"MessageArgs": [
    "******",
    "Password"
],
...

RspBody Definition

RspBody is a keyword for configuring the response body format of an interface. It assembles the property values obtained from the resource collaboration interface or data processing, and returns the values to the user side as command output of interface invocation. The following is an example RspBody configuration:

json
"RspBody": {
    "@odata.context": "/redfish/v1/$metadata#AccountService/Accounts/Members/$entity",
    "Name": "User Account",
    "UserName": "${ProcessingFlow[1]/Destination/UserName}",
    "Oem": {
        "openubmc": {
            "LoginRule": null
        }
    }
}

${ProcessingFlow[1]/Destination/UserName} indicates that data must be obtained from resource collaboration interfaces. For details, see the next section ProcessingFlow Configuration for Resource Collaboration Interface Mapping. If the obtained value is "Administrator", the response body received by the user is as follows:

json
{
    "@odata.context": "/redfish/v1/$metadata#AccountService/Accounts/Members/$entity",
    "Name": "User Account",
    "UserName": "Administrator",
    "Oem": {
        "openubmc": {
            "LoginRule": null
        }
    }
}

ProcessingFlow Configuration for Resource Collaboration Interface Mapping

The general format is as follows:

json
"ProcessingFlow": [
    {
        "Type": "Property/Method/List/Task/Paging"
        "Path": "xx",
        "Interface": "xxx",
        "Name": "xxx",
        "Params": [xxx],
        "Destination": {xxx},
        "Source": {xxx},
        "CallIf": {xxx},
        "Foreach": "xxx"
    },
    xxx
]

Common fields:

  • ProcessingFlow: The value must be an object array. Each object specifies a resource collaboration interface mapping. The object mapping data is executed in sequence.
  • Type: mapping types, including Property/Method/List/Task/Paging. For details, see the following sections (Paging used by CLI interfaces only).
  • Path: MDS object
  • Interface: resource collaboration interface
  • Name: method name
  • Params: method parameter
  • Destination: return value configuration
  • Source: used when setting properties
  • CallIf: Indicates whether to invoke resource collaboration interfaces, applying to all mapping types. For details about the rules, see CallIf.
  • Foreach: The resource collaboration interface is invoked for multiple times. This field applies to all mapping types. For details about the rules, see Foreach.

Property

  • Obtain properties.

    json
    {
        "Type": "Property",
        "Path": "/bmc/kepler/Managers/1/EthernetInterfaces/Ipv4",
        "Interface": "bmc.kepler.Managers.EthernetInterfaces.Ipv4",
        "Destination": {
            "IpMode": "IpModeIpv4",
            "IpAddr": "IpAddrIpv4",
            "SubnetMask": "SubnetMask"
        }
    },
    {
        "Type": "Property",
        "Path": "/bmc/kepler/Managers/1/EthernetInterfaces/Ipv6",
        "Interface": "bmc.kepler.Managers.EthernetInterfaces.Ipv6",
        "Destination": {
            "IpMode": "IpModeIpv6"
        }
    }

    Destination configures a series of key-value pairs. key indicates the property name on the resource collaboration interface. Obtain the property and rename it as value. Since different resource collaboration interfaces may have the same property name, renaming can avoid naming conflicts. In the preceding example, ${ProcessingFlow[1]/Destination/IpModeIpv4} indicates that the IpMode property of the IPv4 resource collaboration interface is obtained, and ${ProcessingFlow[2]/Destination/IpModeIpv6} indicates that the IpMode property of the IPv6 resource collaboration interface is obtained.

  • Set properties.

    json
    {
        "Type": "Property",
        "Path": "/bmc/kepler/Managers/1",
        "Interface": "bmc.kepler.Managers.Ntp",
        "Source": {
            "Preferred": "${ReqBody/PreferredServer}"
        }
    }

    The structure is similar to that of property obtaining. The keyword is changed to Source. In the preceding example, the PreferredServer property value in the request body is set to the Preferred property of the resource collaboration interface.

Method

json
    {
        "Type": "Method",
        "Path": "/bmc/kepler/Systems/Events",
        "Interface": "bmc.kepler.Systems.Events",
        "Name": "GetSelInfo",
        "Params": [
            "123"
        ],
        "ContextParams": {
            "SystemId": "1"
        },
        "Destination": {
            "Version": "Version",
            "CurrentEventNumber": "CurrentEventNumber",
            "MaxEventNumber": "MaxEventNumber"
        }
    }
  • Name: method name
  • Params: method parameter. A default value can be used to indicate there is no parameter (excluding context parameters).
  • ContextParams: context parameter configuration, corresponding to the a{ss} context parameter required for invoking methods in resource collaboration interfaces
  • Destination: similar to the configuration for obtaining properties. The key on the left corresponds to the variable name of the method return value, and the value on the right corresponds to the variable name configured by developers.

Using the preceding configuration as an example, when busctl is used to invoke methods in actual environments, the following information is returned:

shell
> busctl --user call bmc.kepler.event /bmc/kepler/Systems/Events bmc.kepler.Systems.Events GetSelInfo a{ss} 0

suu "1.0.0" 0 10000

The return value is suu "1.0.0" 0 10000. suu indicates that the subsequent data types are String, U32, and U32 in sequence. The Version, CurrentEventNumber, and MaxEventNumber fields are not displayed.
Check the declaration of GetSelInfo (the mdb_interface repository contains the return field declaration of resource collaboration interfaces). rsp contains the return field declaration.

json
"GetSelInfo" :{
    "req": {},
    "rsp": {
        "Version": {
            "baseType": "String"
        },
        "CurrentEventNumber": {
            "baseType": "U32"
        },
        "MaxEventNumber": {
            "baseType": "U32"
        }
    }
}

When using proxy objects to invoke method, the return value is encapsulated in a structured manner. For example, the return value of the GetSelInfo method is as follows:

lua
{
    Version = "1.0.0",
    CurrentEventNumber = 0,
    MaxEventNumber = 1000
}

List

json
{
    "Type": "List",
    "Path": "/bmc/kepler/Managers/1/NetworkProtocol",
    "Interface": "bmc.kepler.Managers.NetworkProtocol.Protocol",
    "Params": [1],
    "Destination": {
        "Members": "service_table"
    }
}

Obtain the resource collaboration interface collection.

  • Interface: If this field is not configured, all resource collaboration interfaces of the MDS sub-object are obtained. If configured, resource collaboration interfaces that contain Interface are obtained.

  • Params: configured as required. Params[1] indicates the retrieval depth. For example, 1 indicates the MDS sub-object, and 2 indicates the MDS sub-sub-object. If Params is not configured, the default depth is 1.

In the preceding example, the /bmc/kepler/Managers/1/NetworkProtocol resource has the following MDS sub-objects (all resource collaboration interfaces of the sub-objects have bmc.kepler.Managers.NetworkProtocol.Protocol):

shell
> busctl --user tree bmc.kepler.nsm
└─/bmc
  └─/bmc/kepler
    └─/bmc/kepler/Managers
 └─/bmc/kepler/Managers/1
   └─/bmc/kepler/Managers/1/NetworkProtocol
     ├─/bmc/kepler/Managers/1/NetworkProtocol/HTTP
     ├─/bmc/kepler/Managers/1/NetworkProtocol/HTTPS
     ├─/bmc/kepler/Managers/1/NetworkProtocol/KVMIP

As a result, the following key-value pairs are added to the Destination:

json
"service_table": [
    "/bmc/kepler/Managers/1/NetworkProtocol/HTTP",
    "/bmc/kepler/Managers/1/NetworkProtocol/HTTPS",
    "/bmc/kepler/Managers/1/NetworkProtocol/KVMIP",
    ......
]

Task

json
{
    "Type": "Task",
    "Path": "/bmc/kepler/Managers/1/LogServices",
    "Interface": "bmc.kepler.Managers.LogServices",
    "Name": "Dump",
    "Params": [
        0
    ],
    "Destination": {
        "TaskId": "TaskId"
    },
    "PostTaskProcess": [
        {
            "Type": "ChangeOwner",
            "Params": [
                "/tmp/web/operate.log"
            ]
         }
    ]
}

Task is a special Method used for asynchronous execution.

  • PostTaskProcess: post-task operation, configuring the specified operation to be performed after a task is executed. Type indicates the operation type. Currently, the owner and permission of a file can be modified after the file is exported.
  • ChangeOwner: Changes the file owner to the current user and the file permission to 600. The parameter is the absolute path of the local file (remote file paths not supported).

Note: Multiple Task methods can be configured in a ProcessingFlow, but only one of them takes effect. Use CallIf to control the Task to be executed.

CallIf

json
"CallIf": {
    "${ReqBody/PropA}": "#WITH"
    "${ReqBody/PropB}": "#WITHOUT",
    "${ReqBody/PropC}": "str1",
    "${Uri/id}": 1
}

The CallIf condition is met and the corresponding Methods are executed only when all properties are valid. #WITH and #WITHOUT are introduced to indicate whether a property exists. The preceding example indicates that the CallIf condition is met only when all the four conditions are met: ReqBody/PropA exists, ReqBody/PropB does not exist, the value of ReqBody/PropC is "str1", and the value of Uri/id is 1.

Foreach

json
"ReqBody": {
    "Type": "object",
    "Required": true,
    "Properties": {
        "SnmpTrapNotification": {
            "Type": "object",
            "Properties": {
                "TrapServer": {
                    "Type": "array",
                    "Items": {
                        "Type": "object",
                        "Properties": {
                            "TrapServerPort": {
                                "Type": "number"
                            }
                        }
                    }
                }
            }
        }
    }
},
"ProcessingFlow": [
    {
        "Type": "Property",
        "Path": "/bmc/kepler/EventService/Subscriptions/Snmp/Nmses/${#INDEX}",
        "Interface": "bmc.kepler.EventService.Subscriptions.Snmp.Nms",
        "Source": {
            "Port": "${ReqBody/SnmpTrapNotification/TrapServer[#INDEX]/TrapServerPort}"
        },
        "Foreach": "${ReqBody/SnmpTrapNotification/TrapServer}"
    }
]

In the preceding configuration example, SnmpTrapNotification/TrapServer in the request body is an array. The properties of bmc.kepler.EventService.Subscriptions.Snmp.Nms must be set for multiple times based on the array size.

json
{
    "SnmpTrapNotification": {
        "TrapServer": [
            {
                "TrapServerPort": 3162
            },
            {
                "TrapServerPort": 3163
            },
            {
                "TrapServerPort": 3164
            },
            {
                "TrapServerPort": 3165
            }
        ]
    }
}

Assume that a request body is configured as above and the size of the SnmpTrapNotification/TrapServer array is 4. The statement "Foreach": "${ReqBody/SnmpTrapNotification/TrapServer}" indicates that the properties must be set for four times (Foreach can also configure the number directly). For the first time, the Path is /bmc/kepler/EventService/Subscriptions/Snmp/Nmses/1, and the data source is ${ReqBody/SnmpTrapNotification/TrapServer[1]/TrapServerPort}. (#INDEX is used together with Foreach and will be replaced with the number of iterations.)

Data Reference

Data reference: Some positions (DEST) need to use data from external sources (SRC). For example, the response body needs to use the data on the resource collaboration interface collection. To simplify data reference and obtain SRC data in the same format, the following rule is defined: ${var} indicates that the value of var comes from external data SRC. For example, ${ReqBody/xxx} indicates that the xxx property in the request body ReqBody is referenced. The data type obtained through data reference is JsonObject, that is, ordered JSON.

Data Source

For interface mapping configuration, the external data is as follows:

  • Uri: dynamic fields contained in a URI
  • Query: query parameter
  • ReqBody: data in the request body
  • ReqBodyOriginal: original data in the request body. Abnormal data is deleted during ReqBody validation and cannot be obtained during ProcessingFlow configuration. In this case, ReqBodyOriginal can be obtained.
  • ReqHeader: data in the request header
  • Context: context information, including the following fields:
    • CLI: Interface (value: CLI), UserName, ClientIp, and Privilege
    • Redfish user password authentication mode: Interface (value: Redfish), UserName, ClientIp, Privilege, RoleId, and AccountId
    • Redfish session authentication mode: In addition to the fields of the user password authentication mode, the following fields are also supported: AuthType, Token, and SessionId.
    • Web_backend: Interface (value: WEB), UserName, ClientIp, Privilege, AccountId, RoleId, AuthType, Token, and SessionId
    • SNMP: Interface (value: SNMP), UserName, ClientIp, and Privilege
  • ProcessingFlow[].Destination: data obtained from resource collaboration interfaces

URI Configuration

  • Fixed properties

(Non–data reference) Ideally, most URI values should be fixed pure data.

json
"RspBody": {
    "Prop": "redfish/v1/Systems/1"
}
  • Simple mode

The framework replaces ${var} with the value of var in the external data. For example, if the value of var is 1, the value of Prop is "redfish/v1/Systems/1".

json
"RspBody": {
    "Prop" : "redfish/v1/Systems/${var}"
}
  • Statements

In most cases, external data has to be processed before usage.
"${Statements/Prop()}" indicates that the data is configured in Statements.Prop. (Note: Statements/Prop is followed by a pair of parentheses.)
Statements.Prop indicates the value of the data referencing var after being processed by multiple Steps. Statements support multiple types of configurations. For details, see Data Processing Statements.

json
"RspBody": {
    "Prop" : "${Statements/Prop()}"
},
"Statements": {
    "Prop": {
        "Input": "${var}"
        "Steps": [ {xxxx} ]
    }
}

Data Processing Statements

Data processing: Data from resource collaboration interfaces has to be processed before usage.

json
"Statements": {
    "Prop": {
        "Input": "${var}"
        "Steps": [
            {
                "Type": "xxxx",
                "Formula": "xxxxx"
            },
            {
                "Type": "xxxx",
                "Formula": "xxxxx"
            },
        ]
    }
}

Input: data source to be processed. The value must reference external data.
Steps: array type. Multiple types of processing logic can be configured. Input is the input of Steps[1], the output of Steps[1] is the input of Steps[2], and so on. The output of Steps[n] is the final processing result.
Steps[].Type: Specifies the data processing type. For details, see the following sections.
Steps[].Formula: data processing formula and rule. Nested data reference configuration is supported.

Convert

json
{
    "Type": "Convert",
    "Formula": "StringToNumber"
}

Data type conversion. In the preceding example, a string is converted to a number. For example, the output of "12" is 12. Formula specifies the converted types. The following values are supported:

  • NumberToBool: Converts a number to a boolean value (0 converted to false, and non-zero values converted to true).
  • BoolToNumber: Converts a boolean value to a number (false converted to 0, and true converted to 1).
  • NumberToString: Converts a number to a string.
  • StringToNumber: Converts a string to a number.
  • FloatToInteger: Converts a floating point integer to an integer. If the fractional part is not 0, the value is converted to nil. For example, the output of 3.1 is nil.
  • ToHex: Converts a number to a hexadecimal string. The letters are in uppercase.
  • Tohex: Converts a number to a hexadecimal string. The letters are in lowercase.

If the input data type does not match the pre-conversion type declared by Formula, the output is nil.

Count

json
{
    "Type": "Count"
}

The input data must be an array. The array size is calculated, and the Formula field is not required. For example, the output of ["1", "2", "3"] is 3.

Expand

json
{
    "Type": "Expand",
    "Formula": "1"
}

The input data must be an accessible URI string. The default value of Formula is "1".
Expand is used to replace a URI with its corresponding response body.
Note: If the result of Expand is not a URI which is expected to be accessed independently, do not start with /redfish or /UI/Rest. Use /expand or /bmc/kepler instead. In this way, the URI will be intercepted directly by nginx during access and will not be redirected to the interface layer or service layer.

If the response body of /redfish/v1/AccountService/Accounts/2 is as follows:

json
{
    "UserName": "Administrator",
    "RoleId": "Administrator",
    "Locked": false,
}

When the input is /redfish/v1/AccountService/Accounts/2, the output is the same as the above response body.

The input data can also be an array of strings. Each string must be an accessible URI. The Expand operation replaces each string with the corresponding response body of the URI. If the response body of /redfish/v1/AccountService/Accounts/3 is as follows:

json
{
    "UserName": "Admin",
    "RoleId": "Administrator",
    "Locked": false,
}

When the input is ` ["/redfish/v1/AccountService/Accounts/2", "/redfish/v1/AccountService/Accounts/3"] , the output is as follows:

json
[
    &#123;
        "UserName": "Administrator",
        "RoleId": "Administrator",
        "Locked": false,
    &#125;,
    &#123;
        "UserName": "Admin",
        "RoleId": "Administrator",
        "Locked": false,
    &#125;
]

During path traversal processing of resource collaboration interfaces, the URI of the resource collaboration interface can be added to obtain the response data.

json
{
   "Uri": "/bmc/kepler/AccountService/Accounts/:id",
   "Interfaces": [
      {
        "Type": "Get",
        "RspBody": {
            "UserName": "$&#123;ProcessingFlow[1]/Destination/Id&#125;",
            "RoleId": "$&#123;ProcessingFlow[1]/Destination/Source&#125;",
            "Locked": "$&#123;ProcessingFlow[1]/Destination/Destination&#125;",
        },
        "ProcessingFlow": [
            {
                "Type": "Property",
                "Path": "/bmc/kepler/AccountService/Accounts/$&#123;Uri/id&#125;",
                "Interface": "bmc.kepler.AccountService.ManagerAccount",
                "Destination": &#123;
                     "UserName": "UserName",
                     "RoleId": "RoleId",
                     "Locked": "Locked"
                &#125;
            }
         ]
      }
   ]
}

The input data can also be an object array. Each object has only one key-value pair. The key must be @odata.id, and the value must be an accessible URI string. The Expand operation replaces each object with the corresponding response body of the URI.

L-Pair

json
&#123;
    "Type": "L-Pair",
    "Formula": "@odata.id"
&#125;

The input must be an array, and Formula can be any string.
L-Pair uses Formula as key and the array element as value to assemble objects and replace the original elements.
For example, if the input is ["/redfish/v1/System/Blade1", "/redfish/v1/System/Blade2", "/redfish/v1/System/Blade3"], and Formula is @odata.id, the output is as follows:

json
[
    &#123;"@odata.id": "/redfish/v1/System/Blade1"&#125;,
    &#123;"@odata.id": "/redfish/v1/System/Blade2"&#125;,
    &#123;"@odata.id": "/redfish/v1/System/Blade3"&#125;
]

Prefix-Add

json
&#123;
    "Type": "Prefix-Add",
    "Formula": "/redfish/v1/"
&#125;

Formula is the prefix string to be added.

  1. If the input is a string or a number, the output is a string consisting of Formula and the input data.
  2. If the input is an array, the Formula prefix is added to each element in the array as the output.

Assume that the value of Formula is /redfish/v1/. If the input is "System", the output is "/redfish/v1/System". If the input is ["System/Blade1", "System/Blade2"], the output is ["/redfish/v1/System/1", "/redfish/v1/System/Blade2"].

Prefix-Trim

json
&#123;
    "Type": "Prefix-Trim",
    "Formula": "/bmc/kepler/"
&#125;

Prefix-Trim is used to delete a prefix. The usage rules are similar to Prefix-Add.

Suffix-Add

json
&#123;
    "Type": "Suffix-Add",
    "Formula": "/Function/1"
&#125;

Suffix-Add is used to add a suffix. Formula is the suffix string to be added. In the preceding example, if the input is "PCIeCard", the output is "/PCIeCard/Function/1". If the input is ["PCIeCard1", "PCIeCard2"], the output is ["/PCIeCard1/Function/1", "/PCIeCard2/Function/1"].

Suffix-Trim

json
&#123;
    "Type": "Suffix-Trim",
    "Formula": "/Function/1"
&#125;

Suffix-Trim is used to delete a suffix. The usage rules are similar to Suffix-Add.

Switch

json
{
    "Type": "Switch",
    "Formula": [
        &#123;
            "Case": "Administrator",
            "To": 1
        &#125;,
        &#123;
            "Case": "root",
            "To": 2
        &#125;,
        &#123;
            "Case": null,
            "To": 3
        &#125;,
        &#123;
            "To": 0
        &#125;
    ]
}

Data replacement, similar to the switch statements of C/Java. Case is a branch, and To indicates the replacement data (with break by default).
Only the To configuration corresponds to the default branch, which can be default and must be placed at the end.
In the preceding example:
If the input is "Administrator", the output is 1.
If the input is "root", the output is 2.
If the input is null or nil (empty data), the output is 3.
If the input is "Admin", the output is 0.

DateFormat

json
&#123;
    "Type": "DateFormat",
    "Formula": ["%Y-%m-%dT%H:%M:%S", true]
&#125;

The input is a timestamp (a number or a numeric string), and the output is a time string.
Formula[1] specifies the time format (see the parameter format of the os.date function in Lua). If this parameter is not set or is set to null, use the default value "%Y-%m-%dT%H:%M:%S".
Formula[2] indicates whether to display the time zone. The default value is false.
In the preceding example, if the input is 1 and the system time zone is UTC+8, the output is "1970-01-01T08:00:01+08:00".

Script

json
&#123;
    "Type": "Script",
    "Formula": "return ReqBody.Option == 'all'"
&#125;

The content of Formula is a Lua script, which can process any complex logic (not recommended for use with other processing types).
In the preceding example, if Option of ReqBody is "all", the output is true. Otherwise, the output is false.
For a long script, if it is inconvenient to read the content in one line, the script can be saved in an external file, and the file name can be configured using Formula. For example, if the value is get_operate_log.lua, the script/get_operate_log.lua file must exist in the same-level directory of the configuration file.

Note: Reduce the use of Script unless complex logic cannot be configured. Interface mapping configuration implements interfaces in the configuration mode, while Script is actually using code.

Plugin

json
&#123;
    "Type": "Plugin",
    "Formula": "orchestrator.bios.get_registry_version(Uri.systemid)"
&#125;

The content of Formula is a function. Input parameters are supported and can use data sources like ReqBody.
Plugin can process services with complex logic (not recommended for use with other processing types).
For example, if Redfish plugins are stored in the /opt/bmc/apps/redfish/interface_config/plugins directory, the preceding configuration requires that the orchestrator/bios.lua file exists in the directory and the file has the get_registry_version function.

Note: Reduce the use of Plugin, which provides functions that can be invoked. In essence, it is also using code.

Differences Between Script and Plugin

Script is used for pure logic processing. Formula configures a Lua script or file name, which cannot be reused. Plugin is used to compile service-related logic. Formula configures function invocation, which requires corresponding function implementation and can be reused. The following table lists the data variables that can be used in Script and Plugin.

VariableDescriptionScript Environment VariablePlugin Function Input ParameterPlugin Environment Variable
busdbus
mdbMDB library
requireLua built-in function
libroutemapper_utilsC library encapsulated by interface mapping configuration
mapper_interfaceLua library encapsulated by interface mapping configuration
stringLua standard library
mathLua standard library
typeLua built-in function
tableLua standard library
ipairsLua built-in function
pairsLua built-in function
nextLua built-in function
pcallLua built-in function
xpcallLua built-in function
errorLua built-in function
base_messagesBasic message definition
custom_messagesCustom error message
tonumberLua built-in function
tostringLua built-in function
cjsoncjson library
nullcjson.null
lua_nilNil value of Lua. If the RspBody property is unable to be obtained, the value is converted to null. If the property is not displayed, use lua_nil.
UriData source
ReqBodyData source
QueryData source
ContextData source
ProcessingFlowData source
InputInput of Steps[ ]

LockdownAllow System Lock Validation

LockdownAllow configures whether an operation is allowed when the system is locked. The value true indicates that the operation is allowed, while the value false indicates that the operation is not allowed. Interface- and property-level configurations are supported. The inner layer can overwrite the outer layer. The default value is false if this parameter is not configured. The following is an example configuration:

json
{
    "Uri": "/redfish/v1/AccountService",
    "Interfaces": [
        {
            "Type": "PATCH",
            "LockdownAllow": false,
            "Properties": {
                "Oem": {
                    "Type": "object",
                    "Properties": {
                        "openubmc": {
                            "Type": "object",
                            "Properties": {
                                "SystemLockDownEnabled": &#123;
                                    "LockdownAllow": true,
                                &#125;,
                                "SecurityBannerEnabled": &#123;
                                    "Type": "boolean",
                                &#125;
                            }
                        }
                    }
                }
            }
        }
    ]
}