towerops/lib/mix/tasks/backfill_checks.ex
Graham McIntire 4421727e61 fix: resolve all Elixir 1.20 type system warnings across project
Removes unreachable catch-all clauses, drops unused `require Logger`
lines, adds pin operators to bitstring size patterns, reorders function
heads for correct dispatch, and replaces deprecated LoggerBackends calls.
2026-05-28 14:52:30 -05:00

101 lines
2.9 KiB
Elixir

defmodule Mix.Tasks.Backfill.Checks do
@shortdoc "Backfill checks for existing SNMP-enabled devices"
@moduledoc """
Backfill checks for existing devices with SNMP discovery data.
This task creates check records for all devices that have existing
snmp_device records with sensors, interfaces, processors, or storage.
Usage:
mix backfill.checks
mix backfill.checks --dry-run
"""
use Mix.Task
import Ecto.Query
alias Towerops.Devices
alias Towerops.Repo
alias Towerops.Snmp.Discovery
@impl Mix.Task
def run(args) do
Mix.Task.run("app.start")
dry_run = "--dry-run" in args
if dry_run do
IO.puts("=== DRY RUN MODE - No changes will be made ===\n")
end
devices =
Repo.all(
from d in Devices.Device,
where: d.snmp_enabled == true,
preload: [:organization, snmp_device: [:sensors, :interfaces, :processors, :storage]]
)
IO.puts("Found #{length(devices)} SNMP-enabled devices\n")
Enum.each(devices, fn device ->
if device.snmp_device do
backfill_device_checks(device, dry_run)
else
IO.puts("Skipping #{device.name} - no SNMP discovery data")
end
end)
IO.puts("\n=== Backfill complete ===")
end
defp backfill_device_checks(device, dry_run) do
snmp_device = device.snmp_device
sensor_count = length(snmp_device.sensors)
interface_count = length(snmp_device.interfaces)
processor_count = length(snmp_device.processors)
storage_count = length(snmp_device.storage)
total = sensor_count + interface_count + processor_count + storage_count
cond do
total == 0 ->
IO.puts("Skipping #{device.name} - no discovered entities")
dry_run ->
print_device_summary(device, sensor_count, interface_count, processor_count, storage_count)
IO.puts(" [DRY RUN] Would create #{total} checks")
true ->
print_device_summary(device, sensor_count, interface_count, processor_count, storage_count)
create_and_report_checks(device, snmp_device)
end
end
defp print_device_summary(device, sensors, interfaces, processors, storage) do
IO.puts("\n#{device.name} (#{device.ip_address}):")
IO.puts(" - #{sensors} sensors")
IO.puts(" - #{interfaces} interfaces")
IO.puts(" - #{processors} processors")
IO.puts(" - #{storage} storage")
end
defp create_and_report_checks(device, snmp_device) do
result = Discovery.create_checks_from_discovery(device, snmp_device)
created = result.sensors + result.interfaces + result.processors + result.storage
if result.errors == [] do
IO.puts(" ✓ Created #{created} checks")
else
IO.puts(" ✓ Created #{created} checks (#{length(result.errors)} errors)")
print_errors(result.errors)
end
end
defp print_errors(errors) do
Enum.each(errors, fn error ->
IO.puts("#{error.type}: #{error.message}")
end)
end
end