SNMP接口映射配置指南
更新时间:2025/07/23
在Gitcode上查看源码

openUBMC社区的SNMP接口采用接口映射配置方案实现,需要将命令配置到json文件中。SNMP接口的接口映射配置文件在rackmount代码仓的snmp路径下。

本篇指导仅介绍SNMP接口独有的配置规则,接口映射配置公共机制可见《接口映射配置》

接口Uri

Uri的示例如下所示:

json
"Uri": "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.0.0.1/Systems/Readwrite"

NOTE

{{SnmpOemIdentifier}}为批量字段替换的目标替换字段,实际使用时如默认配置,会加载为2011.2.235.1.1(具体含义和配置方法可见《接口多层级定制》批量字段替换章节

Uri的格式为:

shell
/snmp/接口Oid/接口名称/接口模式
  • 接口Oid 每一个接口Oid要保证是全局唯一的;

  • 接口名称 每一个接口名称可以不是全局唯一的;

  • 接口模式

    • Readwrite: 支持GET/PATCH操作,可读可写;
    • Readonly: 只支持GET操作,只可读;
    • Setonly: 只支持PATCH或者POST操作,用于只写、导入导出、升级等操作。

数据类型

SNMP协议的数据类型有三大类:通用数据类型、通用结构数据类型和应用数据类型。目前仅涉及SNMP协议的通用数据类型和应用数据类型, 其中涉及的通用数据类型为:

  • INTEGER: 整型,是-2,147,483,648~2,147,483,647之间的有符号整数,对应的接口映射配置属性数据类型为integer;
  • OCTET STRING: 字符串,对应的接口映射配置属性数据类型为string;
  • OBJECT IDENTIFIER: 对象标识符,一般用于表示告警事件Oid, 对应的接口映射配置属性数据类型为objectId;

涉及的应用数据类型为:

  • IpAddress: IP地址,对应的接口映射配置属性数据类型为ipAddress.

SNMP接口分为简单接口和Table类型接口,简单接口用于查询和设置单个属性,Table类型接口用于查询和设置集合资源的多个属性。

简单接口

简单接口的配置规则无特殊要求,可参考《接口映射配置》进行配置。

配置示例

json
{
    "Resources": [
        {
            "Uri": "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.0.0.1/Systems/Readwrite",
            "Interfaces": [
                {
                    "Type": "GET",
                    "RspBody": {
                        "Name": "${ProcessingFlow[1]/Destination/Name}"
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/System",
                            "Interface": "bmc.kepler.System",
                            "Destination": {
                                "Name": "Name"
                            }
                        }
                    ]
                },
                {
                    "Type": "PATCH",
                    "ReqBody": {
                        "Type": "object",
                        "Required": true,
                        "Properties": {
                            "UserName": {
                                "Type": "string",
                                "Required": true
                            }
                        }
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/System",
                            "Interface": "bmc.kepler.System",
                            "Source": {
                                "Name": "${ReqBody/Name}"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

Table类型接口

Table类型接口用于查询和设置集合资源的多个属性。

配置示例

json
{
    "Resources": [
        {
            "Uri": "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.0.0.2/Devices/Readwrite",
            "Sequence": [
                {
                    "Name": "Id",
                    "Type": "integer",
                    "Access": "Readonly",
                    "Primary": true
                },
                {
                    "Name": "Enabled",
                    "Type": "integer",
                    "Access": "Readwrite"
                }
            ],
            "Interfaces": [
                {
                    "Type": "GET",
                    "RspBody": {
                        "Devices": "${Statements/Devices()}"
                    },
                    "Statements": {
                        "Devices": {
                            "Input": "${ProcessingFlow[1]/Destination/Devices}",
                            "Steps": [
                                {
                                    "Type": "Expand",
                                    "Formula": "1"
                                }
                            ]
                        }
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "List",
                            "Path": "/bmc/kepler/Devices",
                            "Destination": {
                                "Members": "Devices"
                            }
                        }
                    ]
                },
                {
                    "Type": "PATCH",
                    "ReqBody": {
                        "Type": "object",
                        "Required": true,
                        "Properties": {
                            "Id": {
                                "Type": "integer",
                                "Required": true
                            },
                            "Enabled": {
                                "Type": "integer"
                            }
                        }
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/Devices/${ReqBody/Id}",
                            "Interface": "bmc.kepler.Device",
                            "Source": {
                                "Enabled": "${ReqBody/Enabled}"
                            }
                        }
                    ]
                }
            ]
        },
        {
            "Uri": "/bmc/kepler/Devices/:id",
            "Interfaces": [
                {
                    "Type": "GET",
                    "RspBody": {
                        "Id": "${Uri/id}",
                        "Enabled": "${ProcessingFlow[1]/Destination/Enabled}"
                    },
                    "ProcessingFlow": [
                        {
                            "Type": "Property",
                            "Path": "/bmc/kepler/Devices/${Uri/Id}",
                            "Interface": "bmc.kepler.Device",
                            "Destination": {
                                "Enabled": "Enabled"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

Sequence

Sequence字段用于指示接口中每一个属性的属性名、数据类型和是否为主键。Sequence中至少配置有一个主键,通过Primary字段进行设置。主键的值用于区分不同的子资源,配置示例如下所示:

json
"Sequence": [
    {
        "Name": "Id",
        "Type": "integer",
        "Access": "Readonly",
        "Primary": true
    },
    {
        "Name": "Enabled",
        "Type": "integer",
        "Access": "Readwrite"
    }
]

上述例子中,Id字段为主键。假设系统有4个device子资源,则SNMP接口返回的Id可为1234,用于区分不同的device.

IMPORTANT

配置时务必确保主键取值互不相同,可以用于区分不同的子资源,否则处理时将会因覆盖而获得不可预期的返回。


响应体RspBody

示例如下:

json
"RspBody": {
    "Devices": "${Statements/Devices()}"
}

RspBody中只有一个属性,属性值为集合资源数组,其中数组中的每一个元素代表一个子资源。。例如,子资源返回的属性值如下所示:

json
{
    "Id": 1,
    "Enabled": 2
}

请求体ReqBody

请求体中必须要配置主键,主键可用于接口映射配置中索引对应的子资源;主键的属性名和数据类型要跟Sequence中定义的主键一致;而请求体中的其他属性则可以根据业务的需要自行配置。如下所示:

json
{
    "Type": "PATCH",
    "ReqBody": {
        "Type": "object",
        "Required": true,
        "Properties": {
            "Id": {
                "Type": "integer",
                "Required": true
            },
            "Enabled": {
                "Type": "integer"
            }
        }
    },
    "ProcessingFlow": [
        {
            "Type": "Property",
            "Path": "/bmc/kepler/Devices/${ReqBody/Id}",
            "Interface": "bmc.kepler.Device",
            "Source": {
                "Enabled": "${ReqBody/Enabled}"
            }
        }
    ]
}

ReqBody中的Id为主键,属性名和数据类型跟Sequence中定义的一致。


接口错误码

SNMP接口通过错误引擎来定义接口执行失败时返回的SNMP错误码,在mdb_interface代码仓错误类型定义中,为错误类型定义对应SnmpStatusCode来定义错误引擎与SNMP错误码的映射关系。当前错误引擎的大部分错误类型都配置了SnmpStatusCode;若未配置,则SnmpStatusCode默认为5.

如下例中的错误类型定义,当SNMP接口请求处理过程中,业务代码中抛出错误PropertyValueTypeError,则最后收到的SNMP错误码将是SnmpStatusCode定义的7.

json
"PropertyValueTypeError": {
    "Description": "Indicates that a property was given the wrong value type, such as when a number is supplied for a property that requires a string.",
    "Message": "The value %1 for the property %2 is of a different type than the property can accept.",
    "Severity": "Warning",
    "NumberOfArgs": 2,
    "ParamTypes": [
        "string",
        "string"
    ],
    "Resolution": "Correct the value for the property in the request body and resubmit the request if the operation failed.",
    "HttpStatusCode": 400,
    "IpmiCompletionCode": "0xFF",
    "SnmpStatusCode": 7,
    "TraceDepth": 0
}

SNMP协议的错误码定义

SNMP协议定义了18种错误码,错误码对应表如下:

宏定义常量值说明
SNMP_ERRORSTATUS_NOERROR0未发生任何错误
SNMP_ERRORSTATUS_TOOBIG1无法将请求的 SNMP 操作结果放在单个 SNMP 消息中
SNMP_ERRORSTATUS_NOSUCHNAME2请求的 SNMP 操作标识了一个未知变量
SNMP_ERRORSTATUS_BADVALUE3请求的 SNMP 操作尝试更改变量,但它指定了语法或值错误
SNMP_ERRORSTATUS_READONLY4请求的 SNMP 操作尝试更改不允许更改的变量
SNMP_ERRORSTATUS_GENERR5在请求的 SNMP 操作期间,出现此处列出的错误以外的错误
SNMP_ERRORSTATUS_NOACCESS6指定的 SNMP 变量不可访问
SNMP_ERRORSTATUS_WRONGTYPE7值指定了与变量所需的类型不一致的类型
SNMP_ERRORSTATUS_WRONGLENGTH8值指定了与变量所需长度不一致的类型
SNMP_ERRORSTATUS_WRONGENCODING9值包含与字段的 ASN.1 标签不一致的抽象语法表示法(ASN.1)编码
SNMP_ERRORSTATUS_WRONGVALUE10值不能分配给变量
SNMP_ERRORSTATUS_NOCREATION11变量不存在,且代理无法创建它
SNMP_ERRORSTATUS_INCONSISTENTVALUE12该值与其他托管对象的值不一致
SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE13将值分配给变量需要分配当前不可用的资源
SNMP_ERRORSTATUS_COMMITFAILED14未发生验证错误,但未更新任何变量
SNMP_ERRORSTATUS_UNDOFAILED15未发生验证错误。某些变量已更新,因为无法撤消其赋值
SNMP_ERRORSTATUS_AUTHORIZATIONERROR16发生授权错误
SNMP_ERRORSTATUS_NOTWRITABLE17变量存在,但代理无法修改它
SNMP_ERRORSTATUS_INCONSISTENTNAME18变量不存在;代理无法创建它,因为命名对象实例与其他托管对象的值不一致

NOTE

后续如果要在mdb_interface代码仓错误类型定义中新增错误类型时,请根据后台业务需要,为新增的错误类型增加SNMP错误码定义(即SnmpStatusCode字段),否则当后台组件返回该种类型错误时,SNMP接口会默认返回SNMP_ERRORSTATUS_GENERR.


SNMPv1错误码映射

SNMPv1版本的错误码只有错误码定义中常量值为0-5的6种,因此使用SNMPv1版本访问SNMP接口时,如果后台组件返回的SNMP错误码不属于上述6种错误码,SNMP接口层会对错误码进行转换。

  • 因节点值导致的错误,如错误的值、类型、长度、编码失败、值不一致,转化至SNMP_ERRORSTATUS_BADVALUE
  • 因无法获取导致的错误,如节点未创建、鉴权失败、不可写、节点名不一致,转化至SNMP_ERRORSTATUS_NOSUCHNAME
  • 因其它不可知错误导致的操作失败,转化至SNMP_ERRORSTATUS_GENERR

具体的转换规则如下:

后台抛出错误码宏定义转换至SNMPv1错误码宏定义
SNMP_ERRORSTATUS_WRONGTYPESNMP_ERRORSTATUS_BADVALUE
SNMP_ERRORSTATUS_WRONGLENGTH
SNMP_ERRORSTATUS_WRONGENCODING
SNMP_ERRORSTATUS_WRONGVALUE
SNMP_ERRORSTATUS_INCONSISTENTVALUE
SNMP_ERRORSTATUS_NOACCESSSNMP_ERRORSTATUS_NOSUCHNAME
SNMP_ERRORSTATUS_NOCREATION
SNMP_ERRORSTATUS_AUTHORIZATIONERROR
SNMP_ERRORSTATUS_NOTWRITABLE
SNMP_ERRORSTATUS_INCONSISTENTNAME
SNMP_ERRORSTATUS_RESOURCEUNAVAILABLESNMP_ERRORSTATUS_GENERR
SNMP_ERRORSTATUS_COMMITFAILED
SNMP_ERRORSTATUS_UNDOFAILED

特有字段说明

SNMP接口存在一些与其它北向接口不一样的配置规则。

SNMPv1v2cSupported字段

用于配置SNMPv1和SNMPv2c版本是否允许访问此SNMP接口,如果没有配置则默认为true(即允许SNMPv1和SNMPv2c版本访问此SNMP接口)。

配置示例:

json
{
    "Resources": [
        {
            "Uri": "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.0.0.1/Systems/Readwrite",
            "Interfaces": [
                {
                    "Type": "PATCH",
                    "SNMPv1v2cSupported": false,
                    "ReqBody": { xxx },
                    "ProcessingFlow": [
                        { xxx }
                    ]
                }
            ]
        }
    ]
}

上述示例中,SNMPv1v2cSupported的值被置为false,因此SNMPv1和SNMPv2c版本无法访问此接口。


@Instance字段

对于Table类型接口,接口的Instance值默认与主键值一致,如果要自定义Table类型接口的Instance值,则可以使用@Instance字段进行配置。@Instance字段是一个数组类型,用于支持拥有多个Instance值的SNMP接口。如下所示:

json
{
    "Resources": [
        {
            "Uri": "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.7.50/fruPowerDescriptionTable/Readwrite",
            "Sequence": [
                {
                    "Name": "fruNum",
                    "Type": "integer",
                    "Access": "Readonly",
                    "Primary": true
                },
                {
                    "Name": "fruPowerControl",
                    "Type": "string",
                    "Access": "Setonly"
                }
            ],
            "Interfaces": [
                {
                    "Type": "GET",
                    "RspBody": {
                        "Sequence": [
                            {
                                "@Instance": [
                                    1
                                ],
                                "fruNum": 0,
                                "fruPowerControl": "write-only"
                            },
                            {
                                "@Instance": [
                                    5
                                ],
                                "fruNum": 4,
                                "fruPowerControl": "write-only"
                            }
                        ]
                    }
                }
            ]
        }
    ]
}

上述接口映射配置配置了一个Table类型SNMP接口的GET类型的接口,主键为fruNum. 当我们walk这个SNMP接口时,会调用这个SNMP接口的GET类型接口,得到如下返回(假设{{SnmpOemIdentifier}}为默认的2011.2.235.1.1):

shell
iso.3.6.1.4.1.2011.2.235.1.1.7.50.1.1.1 = INTEGER: 0
iso.3.6.1.4.1.2011.2.235.1.1.7.50.1.1.5 = INTEGER: 4
iso.3.6.1.4.1.2011.2.235.1.1.7.50.1.2.1 = STRING: "write-only"
iso.3.6.1.4.1.2011.2.235.1.1.7.50.1.2.5 = STRING: "write-only"

可以看到,如主键值为0的实例iso.3.6.1.4.1.2011.2.235.1.1.7.50.1.1.1 = INTEGER: 0Instance值已被配置为1,若没有@Instance字段,这个值将会与主键值保持一致,为0,此时该实例将会是iso.3.6.1.4.1.2011.2.235.1.1.7.50.1.1.0 = INTEGER: 0.


任务机制

有部分SNMP接口也涉及任务机制,当访问该SNMP接口时,后台业务组件会创建一个异步任务来执行相关业务操作。同时,通过其它的SNMP接口可以查询到任务执行的进度和报错信息等。

创建任务

创建任务的配置规则可参考《接口映射配置》

示例

json
{
    "Uri": "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.0.0.3/Upgrade/Setonly",
    "Interfaces": [
        {
            "Type": "POST",
            "SNMPv1v2cSupported": false,
            "ReqBody": {
                "Type": "object",
                "Required": true,
                "Properties": {
                    "FilePath": {
                        "Type": "string",
                        "Required": true
                    }
                }
            },
            "ProcessingFlow": [
                {
                    "Type": "Task",
                    "Path": "/bmc/kepler/System",
                    "Interface": "bmc.kepler.System",
                    "Name": "StartUpgrade",
                    "Params": [
                        "${ReqBody/FilePath}"
                    ],
                    "Destination": {
                        "TaskId": "TaskId"
                    }
                }
            ]
        }
    ]
}

查询任务信息

配置映射接口获取任务信息

json
{
    "Uri": "/bmc/kepler/System/TaskService/Tasks/:taskid",
    "Interfaces": [
        {
            "Type": "GET",
            "RspBody": {
                "Progress": "${ProcessingFlow[1]/Destination/Progress}"
            },
            "ProcessingFlow": [
                {
                    "Type": "Property",
                    "Path": "/bmc/kepler/System/TaskService/Tasks/${Uri/taskid}",
                    "Interface": "bmc.kepler.TaskService.Task",
                    "Destination": {
                        "Progress": "Progress"
                    }
                }
            ]
        }
    ]
}

以上述接口配置为示例,示例中的任务Uri为/bmc/kepler/System/TaskService/Tasks/:taskid. 此Uri的前缀/bmc/kepler/System/TaskService/Tasks/要跟资源协作接口的Task路径前缀保持一致。如上述接口对应的资源协作接口的Task路径可以为/bmc/kepler/System/TaskService/Tasks/3545341234


配置查询任务信息接口

json
{
    "Uri": "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.0.0.5/UpgradeProgress/Readonly",
    "Interfaces": [
        {
            "Type": "GET",
            "TaskReferenceUri": [
                "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.42.2/Upgrade/Setonly",
                "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.0.0.4/Reset/Setonly"
            ],
            "RspBody": {
                "Progress": "-1"
            }
        }
    ]
}

TaskReferenceUri字段

TaskReferenceUri字段用于指定此查询任务接口要查询的任务是由哪个Uri所创建的。如示例中

json
"TaskReferenceUri": [
    "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.42.2/Upgrade/Setonly",
    "/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.0.0.4/Reset/Setonly"
]

当访问此SNMP接口来查询任务信息时,此接口只会去查询由/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.42.2/Upgrade/Setonly/snmp/1.3.6.1.4.1.{{SnmpOemIdentifier}}.0.0.4/Reset/Setonly这两个接口所创建的任务信息。如果这两个接口都分别创建了一个任务,则会优先查询最新创建的那个任务的信息。


任务信息的默认值

假设用户还未访问创建任务的接口,但是却去查询任务的信息,则查询任务的接口会返回默认的任务信息。要想定制默认的任务信息,可以通过配置RspBody字段中属性的默认值来实现。如示例中

json
"RspBody": {
    "Progress": "-1"
}

RspBody字段中Progress属性的默认值被配置为"-1",因此该接口返回的默认任务信息为"-1".