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
128 lines
3.5 KiB
Elixir
128 lines
3.5 KiB
Elixir
defmodule Mix.Tasks.CopyMibs do
|
|
@shortdoc "Copies MIB files from source directory to app MIB directory"
|
|
|
|
@moduledoc """
|
|
Copies MIB files from a source directory to the application's MIB directory.
|
|
|
|
## Usage
|
|
|
|
# Copy all MIB files
|
|
mix copy_mibs --source-path ~/mibs
|
|
|
|
# Copy specific vendor MIB directories
|
|
mix copy_mibs --source-path ~/mibs --vendors mikrotik,cisco,ubiquiti
|
|
"""
|
|
|
|
use Mix.Task
|
|
|
|
require Logger
|
|
|
|
def run(args) do
|
|
{opts, _} =
|
|
OptionParser.parse!(args,
|
|
strict: [
|
|
source_path: :string,
|
|
vendors: :string,
|
|
target_dir: :string
|
|
]
|
|
)
|
|
|
|
source_path = opts[:source_path] || raise "Missing --source-path argument"
|
|
target_dir = opts[:target_dir] || get_default_target_dir()
|
|
vendors = parse_vendors(opts[:vendors])
|
|
|
|
source_mibs = source_path
|
|
|
|
if !File.exists?(source_mibs) do
|
|
raise "LibreNMS MIB directory not found: #{source_mibs}"
|
|
end
|
|
|
|
# Ensure target directory exists
|
|
File.mkdir_p!(target_dir)
|
|
|
|
case vendors do
|
|
:all ->
|
|
copy_all_mibs(source_mibs, target_dir)
|
|
|
|
vendor_list ->
|
|
copy_vendor_mibs(source_mibs, target_dir, vendor_list)
|
|
end
|
|
end
|
|
|
|
defp get_default_target_dir do
|
|
# In development, use priv/mibs; in production use /app/mibs
|
|
if Mix.env() == :dev do
|
|
Path.join([File.cwd!(), "priv", "mibs"])
|
|
else
|
|
Application.get_env(:towerops, :mib_dir, "/app/mibs")
|
|
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 copy_all_mibs(source_dir, target_dir) do
|
|
Logger.info("Copying all MIB files from #{source_dir} to #{target_dir}...")
|
|
|
|
# Use rsync for efficient copying
|
|
case System.cmd("rsync", ["-av", "--exclude=.git", "#{source_dir}/", target_dir]) do
|
|
{output, 0} ->
|
|
Logger.info("Successfully copied MIB files")
|
|
Logger.debug(output)
|
|
:ok
|
|
|
|
{error, exit_code} ->
|
|
Logger.error("Failed to copy MIB files (exit code #{exit_code}): #{error}")
|
|
{:error, :copy_failed}
|
|
end
|
|
rescue
|
|
_e in ErlangError ->
|
|
# rsync not found, fall back to File.cp_r
|
|
Logger.warning("rsync not found, using File.cp_r (slower)")
|
|
copy_mibs_recursive(source_dir, target_dir)
|
|
end
|
|
|
|
defp copy_vendor_mibs(source_dir, target_dir, vendors) do
|
|
Logger.info("Copying MIB files for vendors: #{Enum.join(vendors, ", ")}")
|
|
|
|
results =
|
|
Enum.map(vendors, fn vendor ->
|
|
source_path = Path.join(source_dir, vendor)
|
|
target_path = Path.join(target_dir, vendor)
|
|
|
|
if File.exists?(source_path) do
|
|
Logger.info("Copying #{vendor} MIBs...")
|
|
File.mkdir_p!(target_path)
|
|
_ = File.cp_r!(source_path, target_path)
|
|
{:ok, vendor}
|
|
else
|
|
Logger.warning("Vendor MIB directory not found: #{vendor}")
|
|
{:error, vendor}
|
|
end
|
|
end)
|
|
|
|
successes = Enum.count(results, &match?({:ok, _}, &1))
|
|
failures = Enum.count(results, &match?({:error, _}, &1))
|
|
|
|
Logger.info("Copied #{successes} vendor MIB directories (#{failures} not found)")
|
|
end
|
|
|
|
defp copy_mibs_recursive(source_dir, target_dir) do
|
|
case File.cp_r(source_dir, target_dir) do
|
|
{:ok, _files} ->
|
|
Logger.info("Successfully copied MIB files")
|
|
:ok
|
|
|
|
{:error, reason, file} ->
|
|
Logger.error("Failed to copy #{file}: #{inspect(reason)}")
|
|
{:error, :copy_failed}
|
|
end
|
|
end
|
|
end
|