A ring is a set of Calix C7 Devices that share the same IP Address. For this reason, you cannot apply the usual way to add a node to the OpenNMS inventory.
The idea would be to add an OpenNMS node for each C7 entity with a unique SNMP agent, regardless of its nature: a node, a shelve, a card, a location, etc.
Then, use the metadata feature to populate the specifics of the SNMP agent at the node level. This is what the SNMP Collector would use at run-time to know how to reach the SNMP Agent, as ALL the ring entities would have the same IP Address. In other words, multiple OpenNMS nodes will have the same IP address but a different port to reach their respective statistics.
There are 2 ways to populate the inventory:
With Provisiond, the idea is to allow scan SNMP (using metadata on the detectors) to discover the physical interfaces (or SNMP Interfaces) and persist the required ones based on a given filter via SNMP Policies. No IP interface would be persisted this way.
Unfortunately, as reaching a C7 entity via SNMP has the same priority as business-related requests, it is important to minimize the SNMP requests sent to those devices. To achieve this, set the scan-interval
to be one a week or even higher. The reason for this is, once the OpenNMS node is populated, chances are, there is no need to rescan, as we assume the ifIndex
is fixed across all physical interfaces on a given SNMP agent. If this is not the case, the best approach would be using requisitions.
But, if that is not possible due to the size of the IP-MIB::ipAddressTable
, IF-MIB::ifTable
and IF-MIB::ifXTable
, we have the second option, which involves using the ReST end-point for nodes, to populate the database (or the inventory) manually.
This document intends to collect SNMP Interfaces statistics only, in other words, statistics from SNMP tables indexed by the ifIndex
. Other statistics like private MIBs are not suitable for this solution, as the SNMP Collector works in OpenNMS by retrieving the whole columns of a given table. That goes against the fact that making SNMP queries against a C7 agent is expensive. The only use case to retrieve a given set of rows is for tables indexed by the ifIndex
.
The onmsctl tool is the easiest way to manipulate the inventory to avoid dealing with the OpeNNMS ReST API.
Version v1.0.0-beta7
or newer is required.
To populate the inventory for an OpenNMS node we need to know the following:
The output should be something like this:
Take a note about the Node ID as this value will be used on subsequent requests.
Defining a node that way will be interpreted by Provisiond
as an auto-discovered node, meaning Provisiond
will attempt to scan the node regularly according to the default-foreign-source.xml
. It is recommended to have a dedicated OpenNMS instance to monitor the C7 rings and make sure there are no detectors and policies on this file to avoid undesired side effects.
The sysObjectId
is a mandatory field that the SNMP Collector will use to know which systemDef
inside the chosen SNMP Collection within datacollection-config.xml
will be used to determinate the set of metrics to be collected for the device.
Optionally, the following SNMP attributes can also be set, as those would be visible on the WebUI:
Do not set the location
element unless the node is going to be reachable via Minion
.
The line 11 contains the Node ID as an argument.
The output should be something like this:
The line 7 contains the Node ID as an argument.
The output should be something like this:
To specify an ifIndex
to associate that IP interface with an existing SNMP Interface, that physical interface must exist in the chosen node.
The snmpPrimary
flag has to be P
(i.e., Primary
) to let the SNMP Collector know that this IP will be used to retrieve SNMP metrics.
The line 2 contains the Node ID as an argument.
The line 3 contains the IP Address of the parent interface where the service would be added.
The line 4 contains the name of the service.
The command returns nothing on success.
The metadata
can be added at the node level, interface level or service level. Assuming the idea is that each unique SNMP Agent on the C7 ring will have a node in OpenNMS, the node-level metadata would be enough for this solution.
The line 5 contains the Node ID as an argument.
The command returns nothing on success.
The context
is a way to group a set of metadata, and a metadata itself is a key-value pair.
When using requisitions, the context is always going to be requisitions
and cannot be changed. This is why, for custom ones, we should use a unique name.
The idea is to add one metadata entry for each variable that makes the SNMP agent unique.
The context
and the key
must match the service configuration inside collectd-configuration.xml
.
Even if the above commands offer a way to build the inventory, there is a better approach, especially when there is a need to add multiple nodes with multiple IP and SNMP interfaces. This method involves creating a YAML file and then use onmsctl
to send the request to OpenNMS.
The advantage is that it will take care about all the dependencies like the Node ID automatically for you.
The content of the YAML file should be something like this:
Assuming the content of the file exist in nodes.yaml
, you can send it to OpenNMS like this:
The output would be something like this:
You can specify multiple nodes, multiple IP or SNMP interfaces per node, multiple services per IP, and multiple metadata elements per node, IP interface or service.
With a simple command, it is possible to change the metadata, and the collector will use it on the next attempt.
For instance, to change the timeout for node with ID 7, the following command can do it:
Note that the last argument is the Node ID.
To list the current metadata:
You'll get:
To remove an existing metadata:
Note that the last argument is the Node ID.
We recommend having a dedicated package for C7, although, as the service name is unique, this is not strictly required.
There, we will use a special service. That is because there is a custom behavior associated with a monitored service when it is called SNMP
, and we don't want that for this use case, so we decided to use a custom one called SNMP-C7
:
In case there is going to be a different set of metrics depending on the SNMP Agent, the collection
can also be assigned via metadata.
The collection
should match a valid snmp-collection
inside the datacollection-config.xml
. Inside of it, a datacollection-group
must be specified, and inside of it, a systemDef
referencing the same sysObjectId
used when the node was defined.
Note that the name of the snmp-collection
matches the collection
parameters inside the Collection Package.
The rrd
section is mandatory but only used when the RRDtool or JRobin backend is enabled. This is ignored when using Newts/Cassandra.
The above XML is a sample of what the actual configuration should look like. Note that the name of the datacollection-group
matches the include-collection
entry from datacollectioon-config.xml
. This XML is intended to be stored on a file inside the etc/datacollection
directory.
It is crucial to set the following property inside /opt/opennms/etc/opennms.properties.d
for Collectd
, to avoid performing bulk requests against the whole ifTable
or ifXTable
, as this is forbidden on a C7:
That is another reason for having a dedicated OpenNMS for monitoring C7, as that is a global property that affects all the monitored nodes.