Vendor modules added: - Aviat (WTM microwave radios) - Aruba (wireless controllers and APs) - CiscoWLC (Cisco wireless LAN controllers) - Teltonika (RUTOS LTE routers) - Sub10 (mmWave backhaul radios) Dialyzer fixes: - Fix unknown type Devices.t/0 in alert.ex and device.ex - Fix unmatched_return warnings across multiple files - Add :exq to PLT for Exq function detection - Remove dead code in base.ex, dynamic.ex, vendor.ex - Fix Device.t() type spec to allow nil name field Tests: 1437 tests, 0 failures Dialyzer: 0 errors Credo: no issues
160 lines
4.4 KiB
Elixir
160 lines
4.4 KiB
Elixir
defmodule Mix.Tasks.ImportMibs do
|
|
@shortdoc "Import MIB files from LibreNMS to priv/mibs"
|
|
|
|
@moduledoc """
|
|
Imports MIB files from a LibreNMS installation to priv/mibs for inclusion in the Docker image.
|
|
|
|
## Usage
|
|
|
|
# Import all MIB files
|
|
mix import_mibs --source-path ~/dev/librenms/mibs
|
|
|
|
# Import specific vendors only
|
|
mix import_mibs --source-path ~/dev/librenms/mibs --vendors mikrotik,cisco,ubiquiti
|
|
|
|
## Options
|
|
|
|
* `--source-path` - Path to the LibreNMS mibs directory (required)
|
|
* `--vendors` - Comma-separated list of vendor directories to import (default: all)
|
|
* `--clean` - Remove existing MIBs in priv/mibs before importing (default: false)
|
|
|
|
## Notes
|
|
|
|
* Copies MIB files to priv/mibs/ which will be included in the Docker image
|
|
* Preserves directory structure from LibreNMS
|
|
* Standard MIB files are copied to priv/mibs/ root
|
|
* Vendor-specific MIBs are copied to priv/mibs/vendor_name/
|
|
* After importing, commit the changes to git so MIBs are included in the container
|
|
"""
|
|
|
|
use Mix.Task
|
|
|
|
require Logger
|
|
|
|
def run(args) do
|
|
{opts, _} =
|
|
OptionParser.parse!(args,
|
|
strict: [
|
|
source_path: :string,
|
|
vendors: :string,
|
|
clean: :boolean
|
|
]
|
|
)
|
|
|
|
source_path = opts[:source_path] || raise "Missing --source-path argument"
|
|
vendors = parse_vendors(opts[:vendors])
|
|
clean = opts[:clean] || false
|
|
|
|
if !File.exists?(source_path) do
|
|
raise "Source directory not found: #{source_path}"
|
|
end
|
|
|
|
dest_path = Path.join(["priv", "mibs"])
|
|
|
|
if clean do
|
|
Logger.info("Cleaning priv/mibs...")
|
|
_ = File.rm_rf!(dest_path)
|
|
File.mkdir_p!(dest_path)
|
|
else
|
|
File.mkdir_p!(dest_path)
|
|
end
|
|
|
|
case vendors do
|
|
:all ->
|
|
import_all_vendors(source_path, dest_path)
|
|
|
|
vendor_list ->
|
|
import_specific_vendors(source_path, dest_path, vendor_list)
|
|
end
|
|
end
|
|
|
|
defp parse_vendors(nil), do: :all
|
|
defp parse_vendors(""), do: :all
|
|
|
|
defp parse_vendors(vendors_string) do
|
|
vendors_string
|
|
|> String.split(",")
|
|
|> Enum.map(&String.trim/1)
|
|
|> Enum.reject(&(&1 == ""))
|
|
end
|
|
|
|
defp import_all_vendors(source_path, dest_path) do
|
|
Logger.info("Discovering entries in #{source_path}...")
|
|
|
|
entries =
|
|
source_path
|
|
|> File.ls!()
|
|
|> Enum.reject(fn name ->
|
|
name == "lost+found" or String.starts_with?(name, ".")
|
|
end)
|
|
|> Enum.sort()
|
|
|
|
Logger.info("Found #{length(entries)} entries to import")
|
|
|
|
# Separate files and directories
|
|
{files, directories} =
|
|
Enum.split_with(entries, fn name ->
|
|
path = Path.join(source_path, name)
|
|
File.regular?(path)
|
|
end)
|
|
|
|
# Copy top-level MIB files (standard MIBs)
|
|
Logger.info("Copying #{length(files)} standard MIB files...")
|
|
|
|
Enum.each(files, fn file ->
|
|
copy_file(Path.join(source_path, file), Path.join(dest_path, file))
|
|
end)
|
|
|
|
# Copy vendor directories
|
|
Logger.info("Copying #{length(directories)} vendor directories...")
|
|
|
|
Enum.each(directories, fn vendor ->
|
|
copy_vendor_directory(source_path, dest_path, vendor)
|
|
end)
|
|
|
|
Logger.info("Import complete!")
|
|
Logger.info("Remember to commit the changes: git add priv/mibs && git commit")
|
|
end
|
|
|
|
defp import_specific_vendors(source_path, dest_path, vendors) do
|
|
Logger.info("Importing #{length(vendors)} specified vendors...")
|
|
|
|
Enum.each(vendors, fn vendor ->
|
|
vendor_source = Path.join(source_path, vendor)
|
|
|
|
if File.exists?(vendor_source) do
|
|
copy_vendor_directory(source_path, dest_path, vendor)
|
|
else
|
|
Logger.warning("Vendor directory not found: #{vendor}")
|
|
end
|
|
end)
|
|
|
|
Logger.info("Import complete!")
|
|
Logger.info("Remember to commit the changes: git add priv/mibs && git commit")
|
|
end
|
|
|
|
defp copy_vendor_directory(source_path, dest_path, vendor) do
|
|
vendor_source = Path.join(source_path, vendor)
|
|
vendor_dest = Path.join(dest_path, vendor)
|
|
|
|
Logger.info("Copying #{vendor}...")
|
|
|
|
case File.cp_r(vendor_source, vendor_dest) do
|
|
{:ok, _files} ->
|
|
:ok
|
|
|
|
{:error, reason, file} ->
|
|
Logger.error("Failed to copy #{vendor}: #{inspect(reason)} (file: #{file})")
|
|
end
|
|
end
|
|
|
|
defp copy_file(source, dest) do
|
|
case File.copy(source, dest) do
|
|
{:ok, _bytes} ->
|
|
:ok
|
|
|
|
{:error, reason} ->
|
|
Logger.error("Failed to copy #{Path.basename(source)}: #{inspect(reason)}")
|
|
end
|
|
end
|
|
end
|