Ad Widget

Collapse

Help with Preprocessing, LLD Macros, JsonPath, Mac addresses, and Switches

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • icycler1
    Junior Member
    • Aug 2024
    • 3

    #1

    Help with Preprocessing, LLD Macros, JsonPath, Mac addresses, and Switches


    Environment:
    Zabbix 7.0.1
    SNMP Agents
    No Proxys
    Cisco Network Equipment only.

    Objective:
    1. Create an Item Prototype that generates an Item Per Mac address discovered by a host: OID - 1.3.6.1.2.1.17.4.3.1.1
    2. Have the value returned to those items be the physical interface name (I.E. GigabitEthernet0/1) on the switch(host) associated with the outbound path to that mac: OID - 1.3.6.1.2.1.2.2.1.2

    Problem:
    The snmpwalk for 1.3.6.1.2.1.2.2.1.2 provides "Next OIDs" that do not correspond with any identifiers of 1.3.6.1.2.1.17.4.3.1.1, but instead lead to a relationship with additional OIDs.

    The Data Relationships:

    1. snmpwalk 1.3.6.1.2.1.17.4.3.1.1 - provides the list of discovered mac addresses with the "NEXT OIDS" being the mac address represented in decimal and the value being the mac address as a hex string.

    Example(sanitized): SNMPv2-SMI::mib-2.17.4.3.1.1.255.255.255.255.255.255 = Hex-STRING: FF FF FF FF FF FF

    2. snmpwalk 1.3.6.1.2.1.17.4.3.1.2 - Returns the mac address to port mapping index. (macs are in decimal form, value is an index for snmp off IF-MIB)

    Example(sanitized): SNMPv2-SMI::mib-2.17.4.3.1.2.255.255.255.255.255.255 = INTEGER: 80

    3. snmpwalk 1.3.6.1.2.1.17.1.4.1.2 - Returns the mapping of port oids to port indexs

    Example(sanitized): SNMPv2-SMI::mib-2.17.1.4.1.2.80 = INTEGER: 5004

    4. snmpwalk 1.3.6.1.2.1.2.2.1.2 - Returns the name of the interface based on the index retrieved in 3.

    Example(sanitized): IF-MIB::ifDescr.5004 = STRING: FastEthernet0/1


    Following the Data:

    The "Sub OID" of 1 (example: 255.255.255.255.255.255) can be fed to 2 as shown in its example. The Value returned by 2 is the next needed index (Example: "80"). That index may be fed to 3 as shown in the example. That calls return is the next needed index (Example: "5004"). The last step is to request the name of the interface in step 4 using the value returned by 3 as seen in 4's example.
    By following the snmp response data the answer found is: Mac address: FF:FF:FF:FF:FF:FF is reached through port FastEthernet0/1

    Question:
    How can I use Zabbix to dynamically create MAC address items for a switch, each with a stored value of the uplink interface needed for the switch to reach that MAC address?
    I.E. Name: "Mac address: FF:FF:FF:FF:FF:FF" Value: "FastEthernet0/1"

    I cannot seem to find how in zabbix preprocessing or LLD Macros to traverse data relationships in this way. My attempts keep bringing me to snmpwalk to json, followed by jsonpath, but jsonpath cannot key into any of my macro variables, zabbix throws a context error any time I try to use variables in jsonpath.

    Help please....
  • icycler1
    Junior Member
    • Aug 2024
    • 3

    #2
    I have successfully solved this.
    I needed to use Javascript preprocessing of the received snmp data.

    First I captured the data in the master item:

    Master ITEM
    snmp agent.
    walk[1.3.6.1.2.1.17.4.3.1.2,1.3.6.1.2.1.17.1.4.1.2,1.3. 6.1.2.1.2.2.1.2,1.3.6.1.2.1.17.4.3.1.1]

    Then in the master item i preprocessed it.

    step 1: snmp walk to json:
    • Field Name: value ###Literally I used the word value###
    • oid prefix: .1.3.6.1.2.1
    • format unchanged

    step 2: Javascript

    Code:
    // Parse the input value as JSON
    var snmpData = JSON.parse(value);  // 'value' is the input data passed to the script
    
    // Initialize mappings
    var macToPort = {};        // Mapping of MAC addresses to port indexes
    var portToInterface = {};  // Mapping of port indexes to interface indexes
    var interfaceToName = {};  // Mapping of interface indexes to names
    
    // Variables to store MAC address and port index temporarily
    var macAddress = null;
    var portIndex = null;
    
    // Process the received JSON
    snmpData.forEach(function(entry) {
        var snmpIndex = entry["{#SNMPINDEX}"];
        var snmpValue = entry.value;
    
        if (snmpIndex.startsWith("17.4.3.1.1")) {
            // Extract MAC address
            macAddress = snmpValue; // Save the MAC address
        } else if (snmpIndex.startsWith("17.4.3.1.2")) {
            // Map MAC address to port index
            portIndex = snmpValue;
            if (macAddress) {
                macToPort[macAddress] = portIndex; // Use the last seen MAC address
                macAddress = null; // Reset MAC address for the next entry
            }
        } else if (snmpIndex.startsWith("17.1.4.1.2")) {
            // Map port index to interface index
            // Use only the last part of the snmpIndex as the key
            portToInterface[snmpIndex.split('.').pop()] = snmpValue;
        } else if (snmpIndex.startsWith("2.2.1.2")) {
            // Map interface index to interface name
            interfaceToName[snmpIndex.split('.').pop()] = snmpValue;
        }
    });
    
    // Combine the data to map MAC addresses to interface names
    var result = [];
    for (var mac in macToPort) {
        var portIndex = macToPort[mac];
        var interfaceIndex = portToInterface[portIndex];
        var interfaceName = interfaceToName[interfaceIndex];
    
        if (interfaceName) {
            result.push({
                "macindex": mac,
                "interfaceindex": interfaceName,
                "{#MACADDRESS}": mac,
                "{#INTERFACENAME}": interfaceName
            });
        }
    }
    
    
    return JSON.stringify(result);
    
    //Preprecessing in item prototype: $[?(@.macindex == '{#MACADDRESS}')].interfaceindex
    This javascript sets both the values and MACROs for me since zabbix macro handling was being a pain. For whatever reason, I cannot use JSONPATH in zabbix where I need to call the name of a macro as a literal string.

    END OF MASTER ITEM.

    Discovery Item.
    Just set it as a dependent item of the master item above with a static name and key value.


    Item Prototype.
    Name:Mac Address Proto {#MACADDRESS}
    Dependant on master
    Key:INT.MAC.ADDRESS[{#MACADDRESS}]
    Type of info: Text

    Preprocessing: JsonPath
    $[?(@.macindex == '{#MACADDRESS}')].interfaceindex

    Comment

    Working...