Appendix D |
SNMP Proxy Monitoring Modules |
This appendix covers the following topics:
This appendix describes how to build modules that enable Sun Management Center agents to proxy monitor other legacy SNMP agents running on the same host or other hosts or devices on the network.
These modules allow Sun Management Center agents to manage and determine the status of objects being monitored by legacy agents in the same manner as objects being monitored by typical Sun Management Center modules. This is accomplished by having the Sun Management Center agent query the legacy agent and storing any retrieved data locally. This data can then be processed by the Sun Management Center agent for typical module actions such as alarm limit checking. In addition, traps issued from the legacy agent can be correlated with jobs in the Sun Management Center agent and used to trigger refresh actions that can reacquire data from legacy agents to determine the status in a timely manner.
The following sections describe the differences in the various module definition files for SNMP proxy monitoring modules. Two new module definition files are also described.
In addition to the standard module parameters required, SNMP proxy monitoring modules require additional information to be specified in the module parameter file.
These parameters are:
These additional parameters are used to automatically construct the refreshCommand for nodes that inherit from the TARGET-SNMP primitive (see below). As such, only SNMP gets from legacy agents are permitted using these module parameters. Additional parameters may be specified for SNMP sets (see below).
These parameters are specified in the module parameter file in the same manner as other parameters and can have optional parameters, such as description, associated with them.
The following example shows the module parameter file for the MIB2 Proxy Module. This example includes the standard module parameters as well as the four additional parameters and associated optional parameters (description, reqd and access) required for SNMP proxy monitoring modules.
For SNMP proxy monitoring modules, the module Model file must be used to map out the portion of the MIB in the legacy agent (under the branch specified by the targetEnterprise) that is of interest to the module.
For example, a fragment of the MIB2 proxy module model file for the system and udp branches of the MIB2 tree is shown in the next section.
CODE EXAMPLE D-2 Example: mib2-proxy-models-d.x type = reference consoleHint:mediumDesc = base.modules.mib2Proxy:moduleDetail # # system Managed Object # implements MIB-II system Group # system = { [use MANAGED-OBJECT] mediumDesc = MIB-II System Group consoleHint:mediumDesc = base.modules.mib2Proxy:system sysDescr = { [use STRING MANAGED-PROPERTY] shortDesc = sysDescr mediumDesc = System Descr fullDesc = MIB-II System Description consoleHint:mediumDesc = base.modules.mib2Proxy:system.sysDescr } sysObjectID = { [use OID MANAGED-PROPERTY] shortDesc = sysOID mediumDesc = System OID fullDesc = Object Identifier of the software system consoleHint:mediumDesc = base.modules.mib2Proxy:system.sysObjectID } sysUpTime = { [use STRING MANAGED-PROPERTY] shortDesc = Time since up mediumDesc = Time since System is up fullDesc = The time in microseconds since the system is up consoleHint:mediumDesc = base.modules.mib2Proxy:system.sysUpTime } sysContact = { [use STRING MANAGED-PROPERTY] shortDesc = Contact mediumDesc = System Contact fullDesc = Contact name for this system consoleHint:mediumDesc = base.modules.mib2Proxy:system.sysContact } sysName = { [use STRING MANAGED-PROPERTY] mediumDesc = system name consoleHint:mediumDesc = base.modules.mib2Proxy:system.sysName } sysLocation = { [use STRING MANAGED-PROPERTY] shortDesc = Time since up mediumDesc = system location consoleHint:mediumDesc = base.modules.mib2Proxy:system.sysLocation } sysServices = { [use INT MANAGED-PROPERTY] mediumDesc = system services consoleHint:mediumDesc = base.modules.mib2Proxy:system.sysServices } } ... ... ... udp = { [use MANAGED-OBJECT] mediumDesc = MIB-II UDP Group consoleHint:mediumDesc = base.modules.mib2Proxy:udp udpInDatagrams = { [use COUNTER MANAGED-PROPERTY] mediumDesc = udpInDatagrams consoleHint:mediumDesc = base.modules.mib2Proxy:udp.udpInDatagrams } udpNoPorts = { [use COUNTER MANAGED-PROPERTY] mediumDesc = udpNoPorts consoleHint:mediumDesc = base.modules.mib2Proxy:udp.udpNoPorts } udpInErrors = { [use COUNTER MANAGED-PROPERTY] mediumDesc = udpInErrors consoleHint:mediumDesc = base.modules.mib2Proxy:udp.udpInErrors } udpOutDatagrams = { [use COUNTER MANAGED-PROPERTY] mediumDesc = udpOutDatagrams consoleHint:mediumDesc = base.modules.mib2Proxy:udp.udpOutDatagrams } udpTable = { [ use MANAGED-OBJECT-TABLE ] shortDesc = UDP Table mediumDesc = UDP Table fullDesc = UDP Table in MIB-II consoleHint:mediumDesc = base.modules.mib2Proxy:udp.udpTable udpEntry = {[ use MANAGED-OBJECT-TABLE-ENTRY ] shortDesc = UDP Entry mediumDesc = UDP Entry fullDesc = UDP Entry in MIB-II consoleHint:mediumDesc = base.modules.mib2Proxy:udp.udpTable.udpEntry index = udpLocalAddress udpLocalPort udpLocalAddress = { [ use STRING MANAGED-PROPERTY ] mediumDesc = udpLocalAddress consoleHint:mediumDesc = \ base.modules.mib2Proxy:udp.udpTable.udpEntry.udpLocalAddress } udpLocalPort = { [ use INT MANAGED-PROPERTY ] mediumDesc = udpLocalPort consoleHint:mediumDesc = \ base.modules.mib2Proxy:udp.udpTable.udpEntry.udpLocalPort } } } }
To allow the Sun Management Center agent to reference the legacy agent using URLs, an additional module definition file must be created and loaded into the agent (see the next section). This file is used to map symbolic object identification names to their numeric OID values. The naming convention for this file is <module><-subspec>-oids-d.dat and can be generated using the script mib2x. This script is located in /opt/SUNWsymon/util/bin/<arch>. The general usage for this script is:
mib2x -f <ASN.1 MIB text file> > <module><-subspec>-oids-d.dat
This script reads an ASN.1 MIB text file and generates, on standard output, text with the following format:
<sym1> = <oid1> [<instance>] <sym1>/<sym2> = <oid1>.<oid2> [<instance>] <sym1>/<sym2>/<sym3> = <oid1>.<oid2>.<oid3> [<instance>] ...
This file maps symbolic names of nodes in the legacy MIB to OIDs. The text created by the mib2x script may need to be edited manually. The first few lines from the MIB2 Proxy module legacy MIB OIDs file (mib2-proxy-oids-d.dat) are:
iso = 1 iso/org = 1.3 iso/org/dod = 1.3.6 iso/org/dod/internet = 1.3.6.1 iso/org/dod/internet/directory = 1.3.6.1.1 iso/org/dod/internet/mgmt = 1.3.6.1.2 iso/org/dod/internet/mgmt/mib-2 = 1.3.6.1.2.1 iso/org/dod/internet/mgmt/mib-2/system = 1.3.6.1.2.1.1 iso/org/dod/internet/mgmt/mib-2/system/sysDescr = 1.3.6.1.2.1.1.1 ...
To enable the Sun Management Center agent to reference the legacy agent using URLs, OIDs file of the legacy agent must be loaded into the agent. The loading of this file and the qualifiers required to collect data from the legacy agent are described in the following section.
Loading the Legacy MIB OIDs Mapping FileThe legacy agent's OIDs file must be loaded into the Sun Management Center agent SNMP OID cache. This is done by specifying the following qualifiers in the module realization file:
activateActions(post) = <key> activateService(<key>) = .services.snmp activateCommand(<key>) = cache load <module><-subspec>-oids
Where <key> can be any unique identifier and the <module><-subspec>-oids corresponds to legacy MIB OIDs file. The activateActions(post) qualifier is a space separated list of keys that corresponds to actions that will be performed after the current MIB tree has been instantiated. Each <key> must have a activateService and activateCommand that specifies the command as well as the context in which the command is to be executed.
In this case, there is only one key and it corresponds to the action of loading the legacy MIB OIDs file into the context of the SNMP service object. For example, for the MIB2 Proxy module the qualifiers used to load the OIDs file are:
activateActions(post) = loadcache activateService(loadcache) = .services.snmp activateCommand(loadcache) = cache load pmib2-oidsData Acquisition
For SNMP proxy monitoring modules, data acquisition is accomplished through proxy SNMP operations such as SNMP get, instead of typical module data acquisition mechanisms such as shell scripts or TCL/TOE code. To facilitate data acquisition for proxy SNMP operations, one of the following primitives should be used:
These primitives automatically set the node type to active and constructs the refreshCommand. Nodes that inherit from this primitive are typically the nodes that realize the objects from the models file. For example, shown below are the two objects from the MIB2 Proxy module realization file that instantiate the objects from the models file. These objects also inherit from the TARGET-SNMP primitive.
CODE EXAMPLE D-3 Example: mib2-proxy-d.x [ requires templates mib2-proxy-models-d ] ... system = { [ use templates.mib2-proxy-models-d.system TARGET-SNMP ] ... } ... udp = { [ use templates.mib2-proxy-models-d.udp TARGET-SNMP ] udpTable = { [ use templates.mib2-proxy-models-d.udp.udpTable TARGET-SNMP ] } }
Nodes that inherit from the TARGET-SNMP primitive must also specify two additional qualifiers. These two qualifiers are used to automatically construct the refreshCommand.
They are:
The refreshOidPrefix specifies the symbolic OID in the legacy agent from the enterprise branch (as specified by the targetEnterprise parameter) to the node containing the managed properties of interest. The refreshOids qualifier is a comma separated list of managed properties. Together, the targetEnterprise, refreshOidPrefix, and refreshOids specify the full symbolic OIDs used to access the MIB of the legacy agent. For example, suppose data from the symbolic OID shown below is required.
iso.org.dod.internet.mgmt.mib-2.system.sysDescrThe targetEnterprise is set to iso.org.dod.internet.mgmt.mib-2, the refreshOidPrefix is set to system, and the refreshOids is set to sysDescr#0. The #0 is added to indicate a scalar value. If the managed property was a vector value, then no #0 is required.
Note - The number of items in the refreshOids list is the number of data values that will be acquired from the legacy agent and cascaded into passive managed properties below the active node. As a result, the number of items in the refreshOids list must match the number of passive managed properties below the active node.
Nodes that inherit from the TARGET-SNMP-BINARY primitive must specify a refreshHint qualifier in addition to the refreshOidPrefix and refreshOids qualifiers. refreshHint must specify the conversion from binary to ascii. See Mapping of the DISPLAY-HINT clause in RFC 1903 for more information on the valid contents of refreshHint (Note: octal and binary conversions are not supported for INT nodes and octal conversions are not supported for STRING nodes). The refreshHint specification is typically 1x:, indicating that the value returned from the snmp get is a : delimited string, where each delimited value is a hexadecimal representing a single byte
Shown below is a section from the MIB2 proxy module realization file illustrating the specification of the refreshOidPrefix and refreshOids qualifiers.
system = { [ use templates.mib2-proxy-models-d.sysget TARGET-SNMP ] type = active refreshInterval = 3600 refreshOidPrefix = system refreshOids = sysDescr#0,sysObjectID#0,sysUpTime#0,sysContact#0, sysName#0,sysLocation#0,sysServices#0 } udp = { [ use templates.mib2-proxy-models-d.udp TARGET-SNMP ] type = active refreshInterval = 3600 refreshOidPrefix = udp refreshOids = udpInDatagrams#0,udpNoPorts#0,udpInErrors#0,
udpOutDatagrams#0 udpTable = { [ use templates.mib2-proxy-models-d.udp.udpTable TARGET-SNMP ] type = active refreshOp = walk refreshInterval = 0 refreshOidPrefix = udp.udpTable.udpEntry refreshOids = udpLocalAddress,udpLocalPort } }
In the iftableget node, refreshOp is set to walk and the items in the refreshOids list do not have #0 appended to them, as the data values to be retrieved are vectors.
By default, the TARGET-SNMP primitive sets refreshOp = get to perform a single SNMP get operation for scalar values. However, by setting the refreshOp to walk, the TARGET-SNMP primitive will traverse the MIB tree from the point specified and return all values. As a result, all values from the vector are returned.
Shown below is the complete module realization file for the MIB2 proxy module.
CODE EXAMPLE D-4 Module Realization: MIB2 Proxy Module [ use MANAGED-MODULE ] [ load mib2-proxy-m.x ] [ requires template mib2-proxy-models-d ] consoleHint:mediumDesc = base.modules.mib2Proxy:moduleDetail refreshService = .services.snmp activateActions(post) = loadcache activateService(loadcache) = .services.snmp activateCommand(loadcache) = cache load mib2-proxy-oids system = { [ USE TEmplates.mib2-proxy-models-d.system TARGET-SNMP ] type = active initInterval = 1 refreshInterval = 3600 refreshOidPrefix = system refreshOids = \ sysDescr#0,sysObjectID#0,sysUpTime#0,sysContact#0,sysName#0,\ sysLocation#0,sysServices#0 } ... ... ... udp = { [ use templates.mib2-proxy-models-d.udp TARGET-SNMP ] type = active initInterval = 1 refreshInterval = 3600 refreshOidPrefix = udp refreshOids = udpInDatagrams#0,udpNoPorts#0,udpInErrors#0,udpOutDatagrams#0 udpTable = { [ use templates.mib2-proxy-models-d.udp.udpTable TARGET-SNMP ] type = active initInterval = 1 refreshOp = walk refreshInterval = 0 refreshOidPrefix = udp.udpTable.udpEntry refreshOids = udpLocalAddress,udpLocalPort } }
SNMP sets to legacy agents can be made as part of the setActions infrastructure (see Chapter 6). The setService must be set to .services.snmp and the setCommand must be set to:
set <ip address> <port> -1 {{<varbind>} [{<varbind>} ... ]} \ [-version <snmpVersion>] [-securityLevel <securityLevel>] \ [-securityName <securityName>] [-context <context>] [-timeout <timeout>] \ [-retries <retries>]
where:
<ip address> is the IP address of the host where the legacy agent is running. If this is the same as the targetHost module parameter, then %targetAddress can be used for this value.
<port> is the port used by the legacy agent. If this value is the same as the targetPort module parameter, then %targetPort can be used for this value.
<varbind> consists of <url> <asn1 type> <value> [<display hint>].
- <url> can be either one of sym/<symbolic oid>, oid/<numeric oid>, or mod/<module oid>.
- <asn1 type> specifies the type of data being set. This can be OCTET STRING, Integer32, NULL, OBJECT IDENTIFIER, IpAddress, Counter32, Unsigned32, TimeTicks, Counter64, INTEGER, or Gauge32.
- <value> is the value to be set.
- <display hint> is optional and used to convert <value> to the appropriate format for setting. See Mapping of the DISPLAY-HINT clause in RFC 1903 for more information (Note that octal and binary conversions are not supported for INTEGER types and octal conversions are not supported for OCTET STRING types. The <display hint> specification is typically used to set binary data in the legacy agents. In such a case, <display hint> is typically 1x:, indicating that the <value> is a : delimited string, where each delimited value is a hexadecimal representing a single byte.
<snmpVersion> is optional (default is SNMPv2u) and specifies snmp version used by the legacy agent. If this is the same as the snmpVersion module parameter, %snmpVersion can be used for this value.
<securityLevel> is optional (default is auth) and specifies the SNMP security level supported by the legacy agent. If this value is the same as the securityLevel module parameter, %securityLevel can be used.
<securityName> is optional (default is espublic) and specifies the name (or community) with which to perform the SNMP set. If this value is the same as the securityName module parameter, %securityName can be used.
<context> is optional (default is no context) and specifies the MIB context for the object to be set. If this value is the same as the context module parameter, then %context can be used.
<timeout> is optional (default is 30 seconds) and specifies the time out for the SNMP request in seconds.
<retries> is optional (default is 3 times) and specified the number of times the SNMP set is retried.
In the code fragment below, setnode is a node that has setActions defined. Whenever an SNMP set is made to this node, it will execute an SNMP set to a legacy agent. The set command specifies <ip address>, <port>, <snmpVersion>, <securityLevel>, and <securityName> to be the same as the module parameters. Note, this would indicate that the read and write security names (or communities) are the same. The SNMP set is setting some fixed binary data to the OID 1.3.6.1.4.1.9999.1.1.0.
setnode = { ... setActions = doset setService(doset) = services.snmp setCommand(doset) = set %targetAddress %targetPort -1 {{oid/ 1.3.6.1.4.1.9999.1.1.0 {OCTET STRING} 0:0:4:da:40:cc:e1:f7:99:1f:e1:0 1x:}} -version %snmpVersion - securityLevel %securityLevel -securityName %securityName }
In certain cases, the legacy agent may issue traps that the SNMP proxy monitoring module may be interested in. In such a case, the legacy agent must first be configured to send the traps to the Sun Management Center Trap handler.
Once traps are being sent to the Sun Management Center Trap handler, they will be forwarded to the Sun Management Center agent. The SNMP proxy monitoring module must then add to the agent the actions to be performed for the traps that it is interested in. This is done by loading a new module definition file in to the Sun Management Center agent.
Naming ConventionsThe naming convention for this file is <module>-<subspec>-traps-d.x and the format is as follows:
[ requires class trapaction ] [ inherit classes.trapaction ] <object1> = { [ inherit classes.trapaction ] criteria = enterprise enterprise = <oid corresponding to targetEnterprise> <object2> = { [ inherit classes.trapaction ] criteria = <criteria1> [ <criteria2> <criteria3> ... ] <criteria1> = <value1> ... trapActions = <key1> [ <key2> ... ] trapService(<key1>) = <service> trapMethod(<key1>) = <command> } [ <other objects> ] }<object1> should be a unique identifier indicating the module name.
Sample Specification
Specifying the following:
criteria = enterprise
enterprise = <oid corresponding to targetEnterprise>
allows traps from the specified enterprise (the OID corresponding to the value set in the targetEnterprise module parameter) to be passed down to <object2> (and other objects if specified) for further processing. This allows <object2> to be selective in which traps are processed. Again <object2> is another unique identifier.
Specifying the following:
criteria = <criteria1> [ <criteria2> <criteria3> ... ] \ <criteria1> = <value1>
allows further trap filtering capabilities. The criteria qualifier is a space separated list of parameters whose values are checked for comparison.
Valid ParametersThe list of valid parameters are:
Use trapOid in place of the genericTrap and specificTrap specifications. The trapOid specification will support both SNMPv1 and SNMPv2 traps, whereas genericTrap and specificTrap specifications only support SNMPv1 traps.
For every parameter specified in the criteria list, there must be a qualifier that corresponds to the parameter and the value to be checked against.
The following example will check the agentAddr parameter for equivalence to 192.83.121.224. :
criteria = agentAddr agentAddr = 192.83.121.224
If the test fails, no further processing of the trap is done. The `equal to' test can be changed to `not equal to', by specifying not before the value.
The following exa,mple will test the agentAddr parameter and fail if it equals 1982.83.121.224.
criteria = agentAddr agentAddr = not 192.83.121.224
If no criteria list is specified, all traps passed into <object2> will activate all trap actions. The specification of actions to be performed on traps is made by the following set of qualifiers:
trapActions = <key1> [ <key2> ... ] trapService(<key1>) = <service> trapMethod(<key1>) = <command>
The trapActions qualifier is a space separated list of actions to be performed. For each action in the list, there must be a trapService and trapMethod specified. Typically the action required on a trap is to refresh the data values.
This is done by specifying:
trapActions = <key> trapService(<key>) = .services.snmp trapMethod(<key>) = jobFireByTag %agentAddr:%enterprise
In this case, the trapMethod qualifier specifies a command to fire all jobs associated with the specific agent and enterprise.
Shown below is the trap action file for the HP JetDirect module:
CODE EXAMPLE D-5 Example: hp-jetdirect-trapspd.x [ requires class trapaction ] [ inherit classes.trapaction ] hpjetdirect = { [ inherit classes.trapaction ] criteria = enterprise enterprise = 1.3.6.1.4.1.11.2.3.9.1 notauth = { [ inherit classes.trapaction ] # # match traps that are not authentication failures # criteria = trapOIDRegexp trapOIDRegexp = not ^1\\.3\\.6\\.1\\.6\\.3\\.1\\.1\\.5\\.5$ # # perform trap correlation in job module using trap enterprise # trapActions = jobfire trapService(jobfire) = .services.snmp trapMethod(jobfire) = jobFireByTag %agentAddr:/%enterprise } }
To load the trap actions file into the agent, an additional key is required in the activateActions(post) list (see Chapter 6).
Shown below are the qualifiers required:
activateActions(post) = <key1> <key2>activateService(<key2>) = .services.trapactivateCommand(<key2>) = loadActions <module><-subspec>-trapsIn this case the activateCommand qualifier will load the file <module>-<subspec>-traps-d.x file into the context of the .services.trap object in the Sun Management Center agent.
Example: Qualifiers for Loading the HP JetDirect Module Trap Actions FileShown below are the qualifiers for loading the HP JetDirect module trap actions file.
activateActions(post) = loadtraps activateService(loadtraps) = .services.trap activateCommand(loadtraps) = loadActions hp-jetdirect-trapsExample: Qualifiers for Loading Both the OIDs and Trap Actions Files for the HP JetDirect Module
Shown below are the qualifiers for loading both the OIDs and trap actions files for the HP JetDirect module:
activateActions(post) = loadcache loadtraps activateService(loadcache) = .services.snmp activateCommand(loadcache) = cache load hp-jetdirect-oids activateService(loadtraps) = .services.trap activateCommand(loadtraps) = loadActions hp-jetdirect-traps