From 863f92a94aca49b05ade9386d0432235919a073f Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Wed, 11 Feb 2026 15:49:57 -0600 Subject: [PATCH] fix: handle RouterOS version returned as list of integers Some MikroTik devices return the version OID as a list of integers [7, 20, 6] instead of a binary string "7.20.6". Added pattern match to detect_version/1 to handle this case and convert to dotted string. Fixes warning: "Failed to detect version: {:ok, [7, 20, 6]}" Co-Authored-By: Claude Sonnet 4.5 --- CHANGELOG.txt | 10 ++++++++++ lib/towerops/snmp/profiles/vendors/routeros.ex | 18 ++++++++++++++++++ .../snmp/profiles/vendors/routeros_test.exs | 18 ++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 130430d1..07dfed45 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,16 @@ CHANGELOG - towerops-web ======================== +2026-02-11 - fix: handle RouterOS version returned as list of integers + - File: lib/towerops/snmp/profiles/vendors/routeros.ex (detect_version/1) + Added pattern match to handle case where SNMP version OID returns list + of integers [7, 20, 6] instead of binary string "7.20.6". Converts list + to dotted string format using Enum.join/2. + - File: test/towerops/snmp/profiles/vendors/routeros_test.exs + Added two test cases for list-formatted versions with and without license level. + - Bug: Warning logged "Failed to detect version: {:ok, [7, 20, 6]}" even though + version was successfully retrieved, just in wrong format. + 2026-02-11 - fix: normalize OIDs so agent-polled sensors match regardless of leading dot - File: lib/towerops_web/channels/agent_channel.ex Agent (gosnmp) returns OIDs with leading dots (e.g. ".1.3.6.1.4.1.41112...") diff --git a/lib/towerops/snmp/profiles/vendors/routeros.ex b/lib/towerops/snmp/profiles/vendors/routeros.ex index d874cc0c..71ce77fc 100644 --- a/lib/towerops/snmp/profiles/vendors/routeros.ex +++ b/lib/towerops/snmp/profiles/vendors/routeros.ex @@ -93,6 +93,24 @@ defmodule Towerops.Snmp.Profiles.Vendors.Routeros do Logger.debug("RouterOS: Detected version: #{formatted_version}") formatted_version + {:ok, version} when is_list(version) -> + # Version came back as list of integers like [7, 20, 6] + # Convert to dotted string format + version_string = Enum.join(version, ".") + license_level = detect_license_level(client_opts) + + formatted_version = + case license_level do + level when is_integer(level) -> + "RouterOS #{version_string} (Level #{level})" + + _ -> + "RouterOS #{version_string}" + end + + Logger.debug("RouterOS: Detected version: #{formatted_version}") + formatted_version + other -> Logger.warning("RouterOS: Failed to detect version: #{inspect(other)}") nil diff --git a/test/towerops/snmp/profiles/vendors/routeros_test.exs b/test/towerops/snmp/profiles/vendors/routeros_test.exs index d65950df..a7b4062c 100644 --- a/test/towerops/snmp/profiles/vendors/routeros_test.exs +++ b/test/towerops/snmp/profiles/vendors/routeros_test.exs @@ -118,6 +118,24 @@ defmodule Towerops.Snmp.Profiles.Vendors.RouterosTest do assert Routeros.detect_version(@client_opts) == nil end + + test "handles version returned as list of integers" do + expect(SnmpMock, :get, 2, fn + _, @version_oid, _ -> {:ok, [7, 20, 6]} + _, @license_level_oid, _ -> {:ok, 6} + end) + + assert Routeros.detect_version(@client_opts) == "RouterOS 7.20.6 (Level 6)" + end + + test "handles version returned as list of integers without license level" do + expect(SnmpMock, :get, 2, fn + _, @version_oid, _ -> {:ok, [6, 48, 3]} + _, @license_level_oid, _ -> {:error, :timeout} + end) + + assert Routeros.detect_version(@client_opts) == "RouterOS 6.48.3" + end end describe "detect_serial_number/1" do