From 26bbd8e68ab71885f71042406085d62a4fedbd71 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sat, 17 Jan 2026 18:28:50 -0600 Subject: [PATCH] fix: strip LibreNMS template variables from sensor OIDs LibreNMS sensor OIDs contain template variables like '.{{ $index }}' which need to be removed before performing SNMP walks. Added clean_oid_template/1 to strip these template variables: - '.1.3.6.1.4.1.17713.21.2.1.36.{{ $index }}' -> '.1.3.6.1.4.1.17713.21.2.1.36' - 'sysUptime.{{ $index }}' -> 'sysUptime' The SNMP walk will now use the base OID and discover all instances with their actual index values. --- lib/towerops/snmp/profiles/dynamic.ex | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/towerops/snmp/profiles/dynamic.ex b/lib/towerops/snmp/profiles/dynamic.ex index 3026e9d9..9255ad7f 100644 --- a/lib/towerops/snmp/profiles/dynamic.ex +++ b/lib/towerops/snmp/profiles/dynamic.ex @@ -104,7 +104,11 @@ defmodule Towerops.Snmp.Profiles.Dynamic do oid = sensor_def.num_oid || sensor_def.oid if oid do - case Client.walk(client_opts, oid) do + # Remove LibreNMS template variables like ".{{ $index }}" from OID + # For walks, we need the base OID without the index placeholder + walk_oid = clean_oid_template(oid) + + case Client.walk(client_opts, walk_oid) do {:ok, results} when is_list(results) and results != [] -> # Convert walk results to sensor data Enum.map(results, fn result -> @@ -112,11 +116,11 @@ defmodule Towerops.Snmp.Profiles.Dynamic do end) {:ok, _empty} -> - Logger.debug("No data found for sensor OID: #{oid}") + Logger.debug("No data found for sensor OID: #{walk_oid}") [] {:error, reason} -> - Logger.warning("Failed to walk sensor OID #{oid}: #{inspect(reason)}") + Logger.warning("Failed to walk sensor OID #{walk_oid}: #{inspect(reason)}") [] end else @@ -125,6 +129,16 @@ defmodule Towerops.Snmp.Profiles.Dynamic do end end + # Remove LibreNMS template variables from OID + # Examples: + # ".1.3.6.1.4.1.17713.21.2.1.36.{{ $index }}" -> ".1.3.6.1.4.1.17713.21.2.1.36" + # "sysUptime.{{ $index }}" -> "sysUptime" + defp clean_oid_template(oid) do + oid + |> String.replace(~r/\.?\{\{[^}]+\}\}/, "") + |> String.trim_trailing(".") + end + defp build_sensor_data(sensor_def, %{oid: oid, value: value}) do # Build sensor index from OID (extract last component) sensor_index = extract_index_from_oid(oid, sensor_def.index)