Discovery SNMP

 Reading time: 6

Author: Carlos Marín

SNMP (Simple Network Management Protocol) was introduced in 1988 as a protocol for monitoring and managing network equipment. After several revisions and versions in which improvements and modifications have been introduced, it is still one of the most widely used protocols. If we take into account that it is an extended protocol among most manufacturers and devices that exposes status information and that can be consulted at any time, it makes SNMP itself the de facto observability system of any hardware device and therefore we will be able to consult and store (for later processing) all the information of that device.

At DataDope we use this protocol to perform discoveries on network devices and their interfaces to populate on network devices and their interfaces to populate CMDB and that can not be discovered by other protocols. Periodically we launch network scans are launched periodically on the networks configured in CMDB. We are able to discover those IPs with the UDP port and whose SNMP service is activated SNMP service is enabled and thus we are able to perform an execution on the devices in a more optimal way. Devices in a more optimal way. Once we have performed the discovery on the devices, the data will be sent to CMDB. Bridge, this component is in charge of structuring the data obtained and generating the and generate the different relationships to be later sent to the CMDB API Gateway. Sent to CMDB API Gateway that will be the component in charge of storing the data correctly in the storing the data correctly in the CMDB.

Throughout the document we will point out what is the development done in the Ansible module for SNMP, configuration and execution flow along with graphical examples of the same.

Ansible module for SNMP

A specific module for SNMP has been developed and is included in Datadope’s Ansible Collection and is published for the community together with the work done on OS Facts by colleagues.

The module is composed by a “module” that executes in the client the SNMP agent attacking the previously templatized OIDs and an “action” that runs on the “action that runs on the server (local, not remote) and performs all the pre-processing part of the all the pre-processing and post-processing of the data obtained through SNMP. A “role” is provided that manages the files necessary for the execution of the module. The files are customizable templates to query the different OIDs of a device and files as “databases”. That help us to categorize and nourish the categorize and nourish the discovered devices with information.


The vendor assigns a unique identifying OID for a type of device managed by SNMP and allows us to identify the type, make and model. A YAML file has been generated that allows us to categorize devices by devices by templates and to feed its information through various data sources. That collect information about sysObjectId and that we complement as we discover new unknown devices.

At the first level, we identify the type of template we are going to use (which we will discuss later, below each template we have a list of the different below each template we have a list of the different brands of devices available. available, for each brand in turn we have the list of device types (Networking, Printer, Storage, etc.). to finally group the different SysObjectIDs available by means of the dictionary whose value is the device model assigned to its identifier.

The module in its first iteration collects SysObjectID and SysDescription information by default it uses a generic template to obtain data from its interfaces, but from the two mentioned OIDs we can categorize the devices in our file “sysobject_ids.yaml” within the snmp_discovery role and generate a specific template if necessary.


We have designed a system of templates in YAML format that allows us to consult the different to query the different OIDs in a simple way and to apply post-processing on the obtained values. We support scalar object queries (the result of the query can only be one) and can only be one) and tabular object queries (defines several instances of related objects that are grouped into MIB tables). Tabular objects or tables can be related to each other, this relationship is usually done through the index that allows us to group values within the same table. This index can coincide between several tables or that the value of a table is the index to another table. This allows us to group values to generate a customized output.

The scalar objects are defined by a key whose dictionary will be its OID to be queried and a post-processing if necessary (not mandatory). required). The name we define to the key, will be the value of the key value in the output.

*Definition in template

*Ansible Facts Output

The tabular objects or tables are defined by a key with a dictionary of keys: value. First we specify that it is of type list (type: list), dependencies if they are required, omit information (omit: true) if that table is dependent on another table to supply nourish its information and we want to omit its output, its OID (base), its OID (base) and its OID (base). output, its OID (base) of the table to query and finally the “entries”.

The entries (list) belong to each field that we are going to query within the table as a column in SQL, these entries are defined just like the scalar objects, but we can defined in the same way as scalar objects, but we can omit their output if the value is referential as an index and is only needed to generate dependencies. As OID inside an entry we define the termination of its base OID from the table, although we can define the base OID will be omitted when generating the query (only for that entry). As a result, we obtain a key with a list of dictionaries with the obtained values.

*Definition in template

*Ansible Facts Output

Currently we support two types of dependencies, which are groupings of data in the same dictionary, since there is a relationship between tables through indexes.

Dependency of type “index”: Internally the groupings of values within the same table is associated to a common index, if we define a table with dependency to a previous one (previously consulted) and whose dictionary groupings have the same index, we will make a merge of values between the two tables for that table that we define the dependency.

*Definition in template

*Internal structure separated in tables

*Internal merge structure in table_2

Dependency of type “value”: This type of dependency is generated for those tables that have a different identifier, but within each table element but within each element of the table we can consult a field whose value is the index of the previous table and that allows us to generate the generate the dependency (table merge).

*Definition in template

*Internal structure separated in tables

*Internal merge structure in table_2

Finally, with everything detailed above and using the example template, defined scalar and tabular objects with example template, with different dependencies, we obtain the following output of a network device with its IPs (ipAddrEntry) nourished with data from the ifMIB and interfaces tables.

Ana Ramírez

Ana Ramírez

Did you find it interesting?

Leave a Reply

Your email address will not be published. Required fields are marked *