fix(imports): skip sensors without OIDs and truncate long MIB values

Fixed two profile import issues:

1. Skip sensors without OIDs:
   - Some profiles have sensors with null/missing OID fields
   - These can't be used for SNMP polling anyway
   - Added check to skip importing sensors without oid or num_oid
   - Prevents Ecto.Changeset validation errors

2. Truncate MIB values to 255 characters:
   - ERROR 22001 (string_data_right_truncation)
   - MIB field is varchar(255) but some values exceed this
   - Added truncation to first 255 chars before saving
   - Location: lib/towerops/device_profiles/importer.ex:229-236

Both errors were causing profile imports to fail with crashes.
This commit is contained in:
Graham McIntire 2026-01-18 11:30:27 -06:00
parent eb9ba57f2e
commit 2ecc2082e6
No known key found for this signature in database

View file

@ -224,9 +224,16 @@ defmodule Towerops.DeviceProfiles.Importer do
end
defp import_discovery_definitions(profile, data) do
# Import MIB if specified
# Import MIB if specified (truncate to 255 chars if needed)
if data["mib"] do
DeviceProfiles.update_profile(profile, %{mib: data["mib"]})
mib =
if String.length(data["mib"]) > 255 do
String.slice(data["mib"], 0, 255)
else
data["mib"]
end
DeviceProfiles.update_profile(profile, %{mib: mib})
end
modules = data["modules"] || %{}
@ -311,29 +318,32 @@ defmodule Towerops.DeviceProfiles.Importer do
defp import_sensors_of_class(profile_id, sensor_class, sensors) do
Enum.each(sensors, fn sensor ->
attrs = %{
device_profile_id: profile_id,
sensor_class: sensor_class,
oid: sensor["oid"],
num_oid: sensor["num_oid"],
index: to_string(sensor["index"] || ""),
descr: sensor["descr"],
divisor: calculate_divisor(sensor["precision"]),
precision: sensor["precision"],
sensor_type: sensor["type"],
low_limit: parse_float(sensor["low_limit"]),
low_warn_limit: parse_float(sensor["low_warn_limit"]),
warn_limit: parse_float(sensor["warn_limit"]),
high_limit: parse_float(sensor["high_limit"]),
skip_value_lt: parse_float(sensor["skip_value_lt"]),
skip_value_gt: parse_float(sensor["skip_value_gt"]),
user_func: sensor["user_func"],
entPhysicalIndex: sensor["entPhysicalIndex"],
group: sensor["group"],
options: extract_sensor_options(sensor)
}
# Skip sensors without a valid OID (required for SNMP polling)
if sensor["oid"] || sensor["num_oid"] do
attrs = %{
device_profile_id: profile_id,
sensor_class: sensor_class,
oid: sensor["oid"],
num_oid: sensor["num_oid"],
index: to_string(sensor["index"] || ""),
descr: sensor["descr"],
divisor: calculate_divisor(sensor["precision"]),
precision: sensor["precision"],
sensor_type: sensor["type"],
low_limit: parse_float(sensor["low_limit"]),
low_warn_limit: parse_float(sensor["low_warn_limit"]),
warn_limit: parse_float(sensor["warn_limit"]),
high_limit: parse_float(sensor["high_limit"]),
skip_value_lt: parse_float(sensor["skip_value_lt"]),
skip_value_gt: parse_float(sensor["skip_value_gt"]),
user_func: sensor["user_func"],
entPhysicalIndex: sensor["entPhysicalIndex"],
group: sensor["group"],
options: extract_sensor_options(sensor)
}
import_sensor_with_states(attrs, sensor["states"])
import_sensor_with_states(attrs, sensor["states"])
end
end)
end