Auto-expand MIB directories to include subdirectories

- Update MibTranslator to automatically expand configured MIB directories
- snmptranslate doesn't search recursively, so we explicitly list all subdirs
- Simplify config to only specify root priv/mibs directory
- Update both config.exs (production) and dev.exs (development)
- Subdirectories like mikrotik/, cisco/, net-snmp/ are auto-discovered
This commit is contained in:
Graham McIntire 2026-01-19 14:06:51 -06:00
parent 77d70b28b7
commit 028f2600a2
No known key found for this signature in database
3 changed files with 32 additions and 11 deletions

View file

@ -90,12 +90,10 @@ config :towerops, ToweropsWeb.Endpoint,
# SNMP MIB directories for production (in Docker image)
# MIB files are included in the release at /app/priv/mibs
# MibTranslator automatically expands these to include subdirectories
# Override in dev.exs for local development paths
config :towerops, :mib_dirs, [
"/app/priv/mibs",
"/app/priv/mibs/mikrotik",
"/app/priv/mibs/cisco",
"/app/priv/mibs/net-snmp",
"/usr/share/snmp/mibs"
]

View file

@ -98,14 +98,10 @@ config :towerops, :env, :dev
# Configure SNMP MIB directories for development
# Point to local priv/mibs subdirectories where MIB files are stored
# Note: The root mibs/ directory only contains symlinks to LibreNMS repo
# SNMP MIB directories for development
# MibTranslator automatically expands these to include subdirectories
config :towerops, :mib_dirs, [
# Standard MIBs in priv/mibs root
Path.join([File.cwd!(), "priv", "mibs"]),
# Vendor-specific MIB directories
Path.join([File.cwd!(), "priv", "mibs", "mikrotik"]),
Path.join([File.cwd!(), "priv", "mibs", "cisco"]),
Path.join([File.cwd!(), "priv", "mibs", "net-snmp"]),
# System MIBs as fallback
"/usr/share/snmp/mibs"
]

View file

@ -57,9 +57,13 @@ defmodule Towerops.Snmp.MibTranslator do
defp translate_mib_name(mib_name) do
# Get MIB directories from config or use default
mib_dirs = Application.get_env(:towerops, :mib_dirs, ["/app/mibs", "/usr/share/snmp/mibs"])
mib_dirs = Application.get_env(:towerops, :mib_dirs, ["/app/priv/mibs", "/usr/share/snmp/mibs"])
# Expand directories to include subdirectories (snmptranslate doesn't search recursively)
expanded_dirs = Enum.flat_map(mib_dirs, &expand_mib_directory/1)
# snmptranslate requires colon-separated paths with + prefix for each directory
mib_path = Enum.map_join(mib_dirs, ":", fn dir -> "+#{dir}" end)
mib_path = Enum.map_join(expanded_dirs, ":", fn dir -> "+#{dir}" end)
mib_dir_args = if mib_path == "", do: [], else: ["-M", mib_path]
# Use snmptranslate to convert MIB name to numeric OID
@ -83,4 +87,27 @@ defmodule Towerops.Snmp.MibTranslator do
Logger.error("snmptranslate command failed: #{inspect(e)}")
{:error, :command_not_found}
end
# Expand a MIB directory to include itself and all subdirectories
# snmptranslate doesn't search recursively, so we need to explicitly list all dirs
defp expand_mib_directory(dir) do
if File.exists?(dir) and File.dir?(dir) do
# Include the directory itself
subdirs =
dir
|> File.ls!()
|> Enum.map(&Path.join(dir, &1))
|> Enum.filter(&File.dir?/1)
|> Enum.reject(fn subdir ->
# Skip hidden directories and common non-MIB directories
basename = Path.basename(subdir)
String.starts_with?(basename, ".") or basename in ["lost+found"]
end)
[dir | subdirs]
else
# Directory doesn't exist, return empty list
[]
end
end
end