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.
This commit is contained in:
parent
196c9473a4
commit
4421727e61
45 changed files with 33 additions and 145 deletions
|
|
@ -20,8 +20,6 @@ defmodule Mix.Tasks.Backfill.Checks do
|
||||||
alias Towerops.Repo
|
alias Towerops.Repo
|
||||||
alias Towerops.Snmp.Discovery
|
alias Towerops.Snmp.Discovery
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@impl Mix.Task
|
@impl Mix.Task
|
||||||
def run(args) do
|
def run(args) do
|
||||||
Mix.Task.run("app.start")
|
Mix.Task.run("app.start")
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,6 @@ defmodule Mix.Tasks.ImportProfiles do
|
||||||
alias Towerops.Profiles.SensorOid
|
alias Towerops.Profiles.SensorOid
|
||||||
alias Towerops.Repo
|
alias Towerops.Repo
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@requirements ["app.start"]
|
@requirements ["app.start"]
|
||||||
|
|
||||||
def run(args) do
|
def run(args) do
|
||||||
|
|
|
||||||
|
|
@ -487,7 +487,7 @@ defmodule SnmpKit.SnmpLib.ASN1 do
|
||||||
|
|
||||||
defp decode_long_form_length(data, num_octets) do
|
defp decode_long_form_length(data, num_octets) do
|
||||||
case data do
|
case data do
|
||||||
<<length_bytes::binary-size(num_octets), remaining::binary>> ->
|
<<length_bytes::binary-size(^num_octets), remaining::binary>> ->
|
||||||
length = :binary.decode_unsigned(length_bytes, :big)
|
length = :binary.decode_unsigned(length_bytes, :big)
|
||||||
{:ok, {length, remaining}}
|
{:ok, {length, remaining}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@ defmodule SnmpKit.SnmpLib.HostParser do
|
||||||
`{:error, reason}` for invalid input
|
`{:error, reason}` for invalid input
|
||||||
"""
|
"""
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@type ip4_tuple :: {0..255, 0..255, 0..255, 0..255}
|
@type ip4_tuple :: {0..255, 0..255, 0..255, 0..255}
|
||||||
@type ip6_tuple ::
|
@type ip6_tuple ::
|
||||||
{0..65_535, 0..65_535, 0..65_535, 0..65_535, 0..65_535, 0..65_535, 0..65_535, 0..65_535}
|
{0..65_535, 0..65_535, 0..65_535, 0..65_535, 0..65_535, 0..65_535, 0..65_535, 0..65_535}
|
||||||
|
|
@ -130,19 +128,12 @@ defmodule SnmpKit.SnmpLib.HostParser do
|
||||||
parse_string(input, default_port)
|
parse_string(input, default_port)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Charlist input
|
# Keyword list input: [host: ..., port: ...]
|
||||||
def parse(input, default_port) when is_list(input) do
|
def parse([_ | _] = input, default_port) do
|
||||||
# Validate charlist contains only valid ASCII/UTF-8 characters
|
if Keyword.keyword?(input) do
|
||||||
if valid_charlist?(input) do
|
parse_keyword(input, default_port)
|
||||||
try do
|
|
||||||
string_input = List.to_string(input)
|
|
||||||
parse_string(string_input, default_port)
|
|
||||||
rescue
|
|
||||||
# Not a valid charlist
|
|
||||||
_ -> {:error, :invalid_charlist}
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
{:error, :invalid_charlist}
|
parse_charlist(input, default_port)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -156,13 +147,19 @@ defmodule SnmpKit.SnmpLib.HostParser do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Keyword list input: [host: ..., port: ...]
|
# Charlist input
|
||||||
def parse([_ | _] = input, default_port) when is_list(input) do
|
def parse(input, default_port) when is_list(input) do
|
||||||
if Keyword.keyword?(input) do
|
# Validate charlist contains only valid ASCII/UTF-8 characters
|
||||||
parse_keyword(input, default_port)
|
if valid_charlist?(input) do
|
||||||
|
try do
|
||||||
|
string_input = List.to_string(input)
|
||||||
|
parse_string(string_input, default_port)
|
||||||
|
rescue
|
||||||
|
# Not a valid charlist
|
||||||
|
_ -> {:error, :invalid_charlist}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
# Try as charlist
|
{:error, :invalid_charlist}
|
||||||
parse_charlist(input, default_port)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -666,8 +666,6 @@ defmodule SnmpKit.SnmpLib.MIB.Parser do
|
||||||
_ -> list
|
_ -> list
|
||||||
end
|
end
|
||||||
|
|
||||||
defp convert_deep_charlist(other), do: other
|
|
||||||
|
|
||||||
defp list_of_charlists?(list) do
|
defp list_of_charlists?(list) do
|
||||||
Enum.all?(list, fn
|
Enum.all?(list, fn
|
||||||
sublist when is_list(sublist) -> charlist?(sublist)
|
sublist when is_list(sublist) -> charlist?(sublist)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ defmodule SnmpKit.SnmpLib.MIB.Registry do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.OID
|
alias SnmpKit.SnmpLib.OID
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@standard_mibs %{
|
@standard_mibs %{
|
||||||
# System group (1.3.6.1.2.1.1)
|
# System group (1.3.6.1.2.1.1)
|
||||||
"sysDescr" => [1, 3, 6, 1, 2, 1, 1, 1],
|
"sysDescr" => [1, 3, 6, 1, 2, 1, 1, 1],
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,6 @@ defmodule SnmpKit.SnmpLib.PDU.Decoder do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp peek_version(_), do: {:error, :invalid_data}
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Alias for decode/1.
|
Alias for decode/1.
|
||||||
"""
|
"""
|
||||||
|
|
@ -136,9 +134,6 @@ defmodule SnmpKit.SnmpLib.PDU.Decoder do
|
||||||
pdu: pdu
|
pdu: pdu
|
||||||
}}
|
}}
|
||||||
else
|
else
|
||||||
{:error, reason} when is_tuple(reason) ->
|
|
||||||
{:error, reason}
|
|
||||||
|
|
||||||
{:error, reason} ->
|
{:error, reason} ->
|
||||||
{:error, {:message_parse_error, reason}}
|
{:error, {:message_parse_error, reason}}
|
||||||
end
|
end
|
||||||
|
|
@ -159,7 +154,7 @@ defmodule SnmpKit.SnmpLib.PDU.Decoder do
|
||||||
num_length_bytes = length_of_length - 128
|
num_length_bytes = length_of_length - 128
|
||||||
|
|
||||||
if num_length_bytes > 0 and num_length_bytes <= 4 and byte_size(rest) >= num_length_bytes do
|
if num_length_bytes > 0 and num_length_bytes <= 4 and byte_size(rest) >= num_length_bytes do
|
||||||
<<length_bytes::binary-size(num_length_bytes), remaining::binary>> = rest
|
<<length_bytes::binary-size(^num_length_bytes), remaining::binary>> = rest
|
||||||
actual_length = :binary.decode_unsigned(length_bytes, :big)
|
actual_length = :binary.decode_unsigned(length_bytes, :big)
|
||||||
|
|
||||||
if byte_size(remaining) >= actual_length do
|
if byte_size(remaining) >= actual_length do
|
||||||
|
|
@ -226,7 +221,7 @@ defmodule SnmpKit.SnmpLib.PDU.Decoder do
|
||||||
num_length_bytes = length_of_length - 128
|
num_length_bytes = length_of_length - 128
|
||||||
|
|
||||||
if num_length_bytes > 0 and num_length_bytes <= 4 and byte_size(rest) >= num_length_bytes do
|
if num_length_bytes > 0 and num_length_bytes <= 4 and byte_size(rest) >= num_length_bytes do
|
||||||
<<length_bytes::binary-size(num_length_bytes), remaining_with_content::binary>> = rest
|
<<length_bytes::binary-size(^num_length_bytes), remaining_with_content::binary>> = rest
|
||||||
actual_length = :binary.decode_unsigned(length_bytes, :big)
|
actual_length = :binary.decode_unsigned(length_bytes, :big)
|
||||||
|
|
||||||
if byte_size(remaining_with_content) >= actual_length do
|
if byte_size(remaining_with_content) >= actual_length do
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,6 @@ defmodule SnmpKit.SnmpLib.PDU.Encoder do
|
||||||
case encode_pdu_fast(pdu) do
|
case encode_pdu_fast(pdu) do
|
||||||
{:ok, result} when is_binary(result) -> {:ok, result}
|
{:ok, result} when is_binary(result) -> {:ok, result}
|
||||||
{:error, reason} -> {:error, reason}
|
{:error, reason} -> {:error, reason}
|
||||||
result when is_binary(result) -> {:ok, result}
|
|
||||||
other -> {:error, {:invalid_pdu_result, other}}
|
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
error -> {:error, {:encoding_error, error}}
|
error -> {:error, {:encoding_error, error}}
|
||||||
|
|
|
||||||
|
|
@ -940,11 +940,10 @@ defmodule SnmpKit.SnmpLib.Types do
|
||||||
defp perform_encoding(value, :boolean) when is_boolean(value), do: {:ok, value}
|
defp perform_encoding(value, :boolean) when is_boolean(value), do: {:ok, value}
|
||||||
defp perform_encoding(value, :object_identifier) when is_list(value), do: {:ok, value}
|
defp perform_encoding(value, :object_identifier) when is_list(value), do: {:ok, value}
|
||||||
defp perform_encoding(value, :oid) when is_list(value), do: {:ok, value}
|
defp perform_encoding(value, :oid) when is_list(value), do: {:ok, value}
|
||||||
defp perform_encoding(_value, :null), do: {:ok, nil}
|
|
||||||
defp perform_encoding(nil, :null), do: {:ok, nil}
|
|
||||||
defp perform_encoding(:null, :null), do: {:ok, nil}
|
|
||||||
defp perform_encoding(value, :opaque) when is_binary(value), do: {:ok, value}
|
defp perform_encoding(value, :opaque) when is_binary(value), do: {:ok, value}
|
||||||
|
|
||||||
|
defp perform_encoding(<<a, b, c, d>>, :ip_address), do: {:ok, {a, b, c, d}}
|
||||||
|
|
||||||
# Handle IP address encoding
|
# Handle IP address encoding
|
||||||
defp perform_encoding(value, :ip_address) when is_binary(value) do
|
defp perform_encoding(value, :ip_address) when is_binary(value) do
|
||||||
case parse_ip_address(value) do
|
case parse_ip_address(value) do
|
||||||
|
|
@ -958,8 +957,6 @@ defmodule SnmpKit.SnmpLib.Types do
|
||||||
{:ok, value}
|
{:ok, value}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp perform_encoding(<<a, b, c, d>>, :ip_address), do: {:ok, {a, b, c, d}}
|
|
||||||
|
|
||||||
# Handle OID string encoding
|
# Handle OID string encoding
|
||||||
defp perform_encoding(value, :object_identifier) when is_binary(value) do
|
defp perform_encoding(value, :object_identifier) when is_binary(value) do
|
||||||
case OID.string_to_list(value) do
|
case OID.string_to_list(value) do
|
||||||
|
|
@ -1022,6 +1019,4 @@ defmodule SnmpKit.SnmpLib.Types do
|
||||||
end) and length(list) >= 2
|
end) and length(list) >= 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp oid_list?(_), do: false
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,6 @@ defmodule SnmpKit.SnmpLib.Utils do
|
||||||
|
|
||||||
alias SnmpKit.SnmpLib.Error
|
alias SnmpKit.SnmpLib.Error
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@formatting SnmpKit.Formatting
|
@formatting SnmpKit.Formatting
|
||||||
|
|
||||||
@type oid :: [non_neg_integer()]
|
@type oid :: [non_neg_integer()]
|
||||||
|
|
@ -659,16 +657,12 @@ defmodule SnmpKit.SnmpLib.Utils do
|
||||||
Enum.all?([a, b, c, d], &valid_ipv4_octet?/1)
|
Enum.all?([a, b, c, d], &valid_ipv4_octet?/1)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp valid_ip_tuple?(_), do: false
|
|
||||||
|
|
||||||
defp valid_ipv4_octet?(n), do: is_integer(n) and n >= 0 and n <= 255
|
defp valid_ipv4_octet?(n), do: is_integer(n) and n >= 0 and n <= 255
|
||||||
|
|
||||||
defp valid_ipv6_tuple?({a, b, c, d, e, f, g, h}) do
|
defp valid_ipv6_tuple?({a, b, c, d, e, f, g, h}) do
|
||||||
Enum.all?([a, b, c, d, e, f, g, h], &valid_ipv6_segment?/1)
|
Enum.all?([a, b, c, d, e, f, g, h], &valid_ipv6_segment?/1)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp valid_ipv6_tuple?(_), do: false
|
|
||||||
|
|
||||||
defp valid_ipv6_segment?(n), do: is_integer(n) and n >= 0 and n <= 65_535
|
defp valid_ipv6_segment?(n), do: is_integer(n) and n >= 0 and n <= 65_535
|
||||||
|
|
||||||
defp ipv4_or_simple_hostname?(host_str) do
|
defp ipv4_or_simple_hostname?(host_str) do
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,6 @@ defmodule SnmpKit.SnmpLib.Walker do
|
||||||
alias SnmpKit.SnmpLib.Manager
|
alias SnmpKit.SnmpLib.Manager
|
||||||
alias SnmpKit.SnmpLib.OID
|
alias SnmpKit.SnmpLib.OID
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@default_max_repetitions 30
|
@default_max_repetitions 30
|
||||||
@default_timeout 10_000
|
@default_timeout 10_000
|
||||||
@default_max_retries 3
|
@default_max_retries 3
|
||||||
|
|
|
||||||
|
|
@ -99,12 +99,6 @@ defmodule SnmpKit.SnmpMgr.Core do
|
||||||
{:ok, {type, value}} ->
|
{:ok, {type, value}} ->
|
||||||
{:ok, {type, value}}
|
{:ok, {type, value}}
|
||||||
|
|
||||||
# Type information must be preserved - reject responses without type information
|
|
||||||
{:ok, value} ->
|
|
||||||
{:error,
|
|
||||||
{:type_information_lost,
|
|
||||||
"SNMP GET operation must preserve type information. Got value without type: #{inspect(value)}"}}
|
|
||||||
|
|
||||||
{:error, reason} ->
|
{:error, reason} ->
|
||||||
{:error, reason}
|
{:error, reason}
|
||||||
end
|
end
|
||||||
|
|
@ -150,12 +144,6 @@ defmodule SnmpKit.SnmpMgr.Core do
|
||||||
{:ok, {type, value}} ->
|
{:ok, {type, value}} ->
|
||||||
{:ok, {oid_string, type, value}}
|
{:ok, {oid_string, type, value}}
|
||||||
|
|
||||||
{:ok, value} ->
|
|
||||||
# Type information must be preserved - reject responses without type information
|
|
||||||
{:error,
|
|
||||||
{:type_information_lost,
|
|
||||||
"SNMP GET operation must preserve type information. Got value without type for OID #{oid_string}: #{inspect(value)}"}}
|
|
||||||
|
|
||||||
{:error, reason} ->
|
{:error, reason} ->
|
||||||
{:error, reason}
|
{:error, reason}
|
||||||
end
|
end
|
||||||
|
|
@ -464,7 +452,6 @@ defmodule SnmpKit.SnmpMgr.Core do
|
||||||
defp parse_numeric_oid(oid_string) do
|
defp parse_numeric_oid(oid_string) do
|
||||||
case OID.string_to_list(oid_string) do
|
case OID.string_to_list(oid_string) do
|
||||||
{:ok, [_ | _] = oid_list} -> {:ok, oid_list}
|
{:ok, [_ | _] = oid_list} -> {:ok, oid_list}
|
||||||
{:ok, []} -> {:ok, [1, 3]}
|
|
||||||
error -> error
|
error -> error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ defmodule SnmpKit.SnmpMgr.MIB do
|
||||||
alias SnmpKit.SnmpLib.MIB.Parser
|
alias SnmpKit.SnmpLib.MIB.Parser
|
||||||
alias SnmpKit.SnmpLib.OID
|
alias SnmpKit.SnmpLib.OID
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@compile {:no_warn_undefined, [:snmpc, :snmp_misc]}
|
@compile {:no_warn_undefined, [:snmpc, :snmp_misc]}
|
||||||
|
|
||||||
@standard_mibs %{
|
@standard_mibs %{
|
||||||
|
|
|
||||||
|
|
@ -307,11 +307,8 @@ defmodule Towerops.Application do
|
||||||
# Add the backend with a unique identifier (using apply to avoid compile-time warnings)
|
# Add the backend with a unique identifier (using apply to avoid compile-time warnings)
|
||||||
apply(LoggerBackends, :add, [{LoggerFileBackend, :file_log}])
|
apply(LoggerBackends, :add, [{LoggerFileBackend, :file_log}])
|
||||||
|
|
||||||
# Configure the backend with path and level
|
# Use LoggerBackends for modern Elixir (Logger.configure_backend is deprecated)
|
||||||
Logger.configure_backend({LoggerFileBackend, :file_log},
|
apply(LoggerBackends, :configure, [{LoggerFileBackend, :file_log}, [path: "_build/dev.log", level: :debug]])
|
||||||
path: "_build/dev.log",
|
|
||||||
level: :debug
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
Logger.debug("LoggerBackends not available - file logging disabled (dev-only feature)")
|
Logger.debug("LoggerBackends not available - file logging disabled (dev-only feature)")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@ defmodule Towerops.ConfigChanges.Correlator do
|
||||||
alias Towerops.Preseem.SubscriberMetric
|
alias Towerops.Preseem.SubscriberMetric
|
||||||
alias Towerops.Repo
|
alias Towerops.Repo
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@pre_window_hours 2
|
@pre_window_hours 2
|
||||||
@post_window_hours 4
|
@post_window_hours 4
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ defmodule Towerops.Coverages.Raster do
|
||||||
|
|
||||||
alias Towerops.Coverages.Coverage
|
alias Towerops.Coverages.Coverage
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@nan_sentinel 1.0e30
|
@nan_sentinel 1.0e30
|
||||||
|
|
||||||
# cnHeat-ish palette: green strong, yellow good, orange marginal, red poor.
|
# cnHeat-ish palette: green strong, yellow good, orange marginal, red poor.
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,4 @@ defmodule Towerops.ErrorTrackerIgnorer do
|
||||||
String.contains?(binary_kind, "DBConnection.ConnectionError") and
|
String.contains?(binary_kind, "DBConnection.ConnectionError") and
|
||||||
Enum.any?(@transient_db_phrases, &String.contains?(binary_reason, &1))
|
Enum.any?(@transient_db_phrases, &String.contains?(binary_reason, &1))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp transient_db_error?(_), do: false
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ defmodule Towerops.Lidar.Reader do
|
||||||
|
|
||||||
alias Towerops.Lidar.Tile
|
alias Towerops.Lidar.Tile
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@gdal_bin "gdallocationinfo"
|
@gdal_bin "gdallocationinfo"
|
||||||
# GDAL emits this sentinel for nodata in -valonly mode
|
# GDAL emits this sentinel for nodata in -valonly mode
|
||||||
@nodata_sentinels ["-3.4028235e+38", "-3.402823466e+38", "-9999"]
|
@nodata_sentinels ["-3.4028235e+38", "-3.402823466e+38", "-9999"]
|
||||||
|
|
|
||||||
|
|
@ -254,8 +254,6 @@ defmodule Towerops.Mikrotik.GaiiaResolver do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp smush(nil), do: ""
|
|
||||||
|
|
||||||
defp smush(s) when is_binary(s) do
|
defp smush(s) when is_binary(s) do
|
||||||
s
|
s
|
||||||
|> String.downcase()
|
|> String.downcase()
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ defmodule Towerops.NetBox.Client do
|
||||||
|
|
||||||
alias Towerops.HTTP
|
alias Towerops.HTTP
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Test connectivity and authentication against a NetBox instance.
|
Test connectivity and authentication against a NetBox instance.
|
||||||
Returns `{:ok, info}` with the NetBox version or `{:error, reason}`.
|
Returns `{:ok, info}` with the NetBox version or `{:error, reason}`.
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,6 @@ defmodule Towerops.Preseem.Baseline do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compute_stats([]), do: %{mean: 0.0, stddev: 0.0, p5: 0.0, p95: 0.0}
|
|
||||||
|
|
||||||
defp compute_stats(values) do
|
defp compute_stats(values) do
|
||||||
float_values = Enum.map(values, &to_float/1)
|
float_values = Enum.map(values, &to_float/1)
|
||||||
sorted = Enum.sort(float_values)
|
sorted = Enum.sort(float_values)
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ defmodule Towerops.Proto.Wire do
|
||||||
case decode_varint(data) do
|
case decode_varint(data) do
|
||||||
{:ok, {len, rest}} ->
|
{:ok, {len, rest}} ->
|
||||||
if byte_size(rest) >= len do
|
if byte_size(rest) >= len do
|
||||||
<<field_data::binary-size(len), remaining::binary>> = rest
|
<<field_data::binary-size(^len), remaining::binary>> = rest
|
||||||
{:ok, {field_data, remaining}}
|
{:ok, {field_data, remaining}}
|
||||||
else
|
else
|
||||||
{:error, :unexpected_eof}
|
{:error, :unexpected_eof}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ defmodule Towerops.Reports do
|
||||||
alias Towerops.Reports.Report
|
alias Towerops.Reports.Report
|
||||||
alias Towerops.RfLinks
|
alias Towerops.RfLinks
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
# -- CRUD --
|
# -- CRUD --
|
||||||
|
|
||||||
def list_reports(organization_id) do
|
def list_reports(organization_id) do
|
||||||
|
|
|
||||||
|
|
@ -1452,8 +1452,6 @@ defmodule Towerops.Snmp.Discovery do
|
||||||
defp map_pool_type_to_mempool_type(type), do: type
|
defp map_pool_type_to_mempool_type(type), do: type
|
||||||
|
|
||||||
defp calculate_usage_percent(_used, 0), do: 0.0
|
defp calculate_usage_percent(_used, 0), do: 0.0
|
||||||
defp calculate_usage_percent(_used, nil), do: nil
|
|
||||||
defp calculate_usage_percent(nil, _total), do: nil
|
|
||||||
|
|
||||||
defp calculate_usage_percent(used, total) when is_integer(used) and is_integer(total) do
|
defp calculate_usage_percent(used, total) when is_integer(used) and is_integer(total) do
|
||||||
Float.round(used / total * 100.0, 2)
|
Float.round(used / total * 100.0, 2)
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ defmodule Towerops.Snmp.MacDiscovery do
|
||||||
|
|
||||||
alias Towerops.Snmp.Client
|
alias Towerops.Snmp.Client
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@type mac_entry :: %{
|
@type mac_entry :: %{
|
||||||
required(:mac_address) => String.t(),
|
required(:mac_address) => String.t(),
|
||||||
required(:port_index) => integer(),
|
required(:port_index) => integer(),
|
||||||
|
|
|
||||||
|
|
@ -329,8 +329,6 @@ defmodule Towerops.Snmp.NeighborDiscovery do
|
||||||
|
|
||||||
# Helper Functions
|
# Helper Functions
|
||||||
|
|
||||||
defp find_interface_by_index(nil, _interfaces), do: nil
|
|
||||||
|
|
||||||
defp find_interface_by_index(if_index, interfaces) do
|
defp find_interface_by_index(if_index, interfaces) do
|
||||||
Enum.find(interfaces, fn interface ->
|
Enum.find(interfaces, fn interface ->
|
||||||
interface.if_index == if_index
|
interface.if_index == if_index
|
||||||
|
|
|
||||||
|
|
@ -729,8 +729,6 @@ defmodule Towerops.Snmp.Profiles.Vendors.Routeros do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp format_gauge_description(name, _sensor_type), do: name
|
|
||||||
|
|
||||||
# Map mtxrGaugeUnit value to sensor type, unit string, and divisor
|
# Map mtxrGaugeUnit value to sensor type, unit string, and divisor
|
||||||
# Mikrotik reports temperature in tenths of degrees (e.g., 230 = 23.0°C)
|
# Mikrotik reports temperature in tenths of degrees (e.g., 230 = 23.0°C)
|
||||||
defp gauge_unit_to_sensor_type(@gauge_unit_celsius), do: {"temperature", "°C", 10}
|
defp gauge_unit_to_sensor_type(@gauge_unit_celsius), do: {"temperature", "°C", 10}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ defmodule Towerops.Snmp.Topology do
|
||||||
%{
|
%{
|
||||||
id: device.id,
|
id: device.id,
|
||||||
label: device.name,
|
label: device.name,
|
||||||
type: device_type_atom(device),
|
type: device_type_atom(device.device_role),
|
||||||
status: device.status,
|
status: device.status,
|
||||||
site_id: device.site_id,
|
site_id: device.site_id,
|
||||||
site_name: device.site.name,
|
site_name: device.site.name,
|
||||||
|
|
@ -191,8 +191,6 @@ defmodule Towerops.Snmp.Topology do
|
||||||
|
|
||||||
defp ipv4?(_), do: false
|
defp ipv4?(_), do: false
|
||||||
|
|
||||||
defp calculate_prefix_length(nil), do: ""
|
|
||||||
|
|
||||||
defp calculate_prefix_length(subnet_mask) do
|
defp calculate_prefix_length(subnet_mask) do
|
||||||
subnet_mask
|
subnet_mask
|
||||||
|> String.split(".")
|
|> String.split(".")
|
||||||
|
|
@ -262,8 +260,7 @@ defmodule Towerops.Snmp.Topology do
|
||||||
|> Enum.sort_by(& &1.device_count, :desc)
|
|> Enum.sort_by(& &1.device_count, :desc)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Convert device type to atom with whitelist to prevent atom exhaustion
|
# Convert device type string to atom with whitelist to prevent atom exhaustion
|
||||||
defp device_type_atom(device) when is_atom(device), do: device
|
|
||||||
defp device_type_atom("router"), do: :router
|
defp device_type_atom("router"), do: :router
|
||||||
defp device_type_atom("switch"), do: :switch
|
defp device_type_atom("switch"), do: :switch
|
||||||
defp device_type_atom("wireless"), do: :wireless
|
defp device_type_atom("wireless"), do: :wireless
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ defmodule Towerops.Snmp.WirelessClientDiscovery do
|
||||||
alias Towerops.Snmp.Client
|
alias Towerops.Snmp.Client
|
||||||
alias Towerops.Snmp.WirelessClientDiscovery.Parser
|
alias Towerops.Snmp.WirelessClientDiscovery.Parser
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
# Cambium ePMP - cambiumAPConnectedSTATable
|
# Cambium ePMP - cambiumAPConnectedSTATable
|
||||||
@epmp_base "1.3.6.1.4.1.17713.21.1.2.30.1"
|
@epmp_base "1.3.6.1.4.1.17713.21.1.2.30.1"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,6 @@ defmodule Towerops.Uisp.ConfigSnapshot do
|
||||||
alias Towerops.Repo
|
alias Towerops.Repo
|
||||||
alias Towerops.Uisp.Client
|
alias Towerops.Uisp.Client
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Fetches and stores configuration snapshots for all UISP devices.
|
Fetches and stores configuration snapshots for all UISP devices.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ defmodule Towerops.Uisp.GpsSync do
|
||||||
alias Towerops.Repo
|
alias Towerops.Repo
|
||||||
alias Towerops.Sites.Site
|
alias Towerops.Sites.Site
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Updates GPS coordinates for devices and sites from UISP device data.
|
Updates GPS coordinates for devices and sites from UISP device data.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,6 @@ defmodule Towerops.Workers.CapacityInsightWorker do
|
||||||
alias Towerops.Repo
|
alias Towerops.Repo
|
||||||
alias Towerops.Snmp.Interface
|
alias Towerops.Snmp.Interface
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@critical_threshold 90
|
@critical_threshold 90
|
||||||
@warning_threshold 75
|
@warning_threshold 75
|
||||||
@resolve_threshold 70
|
@resolve_threshold 70
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ defmodule Towerops.Workers.GaiiaWebhookWorker do
|
||||||
|
|
||||||
alias Towerops.Gaiia.Webhooks
|
alias Towerops.Gaiia.Webhooks
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@impl Oban.Worker
|
@impl Oban.Worker
|
||||||
def perform(%Oban.Job{args: %{"organization_id" => org_id, "event" => event, "payload" => payload}}) do
|
def perform(%Oban.Job{args: %{"organization_id" => org_id, "event" => event, "payload" => payload}}) do
|
||||||
Webhooks.process_event(org_id, event, payload)
|
Webhooks.process_event(org_id, event, payload)
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ defmodule ToweropsWeb.Layouts do
|
||||||
alias ToweropsWeb.Helpers.StatusHelpers
|
alias ToweropsWeb.Helpers.StatusHelpers
|
||||||
alias ToweropsWeb.Live.Components.GlobalSearchComponent
|
alias ToweropsWeb.Live.Components.GlobalSearchComponent
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
# Embed all files in layouts/* within this module.
|
# Embed all files in layouts/* within this module.
|
||||||
# The default root.html.heex file contains the HTML
|
# The default root.html.heex file contains the HTML
|
||||||
# skeleton of your application, namely HTML headers
|
# skeleton of your application, namely HTML headers
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ defmodule ToweropsWeb.MarketingLayouts do
|
||||||
|
|
||||||
alias ToweropsWeb.Components.CookieConsent
|
alias ToweropsWeb.Components.CookieConsent
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Renders the marketing layout.
|
Renders the marketing layout.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -473,8 +473,8 @@ defmodule ToweropsWeb.Api.V1.MibController do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp hardlink?(path) do
|
defp hardlink?(path) do
|
||||||
case File.lstat(path) do
|
case :file.read_file_info(String.to_charlist(path)) do
|
||||||
{:ok, %{nlink: nlink}} -> nlink > 1
|
{:ok, file_info} -> elem(file_info, 8) > 1
|
||||||
_ -> false
|
_ -> false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,6 @@ defmodule ToweropsWeb.Api.V1.PagerdutyWebhookController do
|
||||||
|
|
||||||
{:error, :unhandled_event} ->
|
{:error, :unhandled_event} ->
|
||||||
json(conn, %{status: "accepted"})
|
json(conn, %{status: "accepted"})
|
||||||
|
|
||||||
{:error, _reason} ->
|
|
||||||
conn |> put_status(500) |> json(%{error: "Internal error"})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -237,9 +237,6 @@ defmodule ToweropsWeb.Api.V1.SchedulesController do
|
||||||
|> json(%{errors: translate_errors(changeset)})
|
|> json(%{errors: translate_errors(changeset)})
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{:error, :forbidden} ->
|
|
||||||
conn |> put_status(:forbidden) |> json(%{error: "Access denied to this schedule"})
|
|
||||||
|
|
||||||
{:error, :not_found} ->
|
{:error, :not_found} ->
|
||||||
conn |> put_status(:not_found) |> json(%{error: "Schedule not found"})
|
conn |> put_status(:not_found) |> json(%{error: "Schedule not found"})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,6 @@ defmodule ToweropsWeb.DashboardLive do
|
||||||
defp uptime_color(pct) when pct >= 95.0, do: "text-yellow-600 dark:text-yellow-400"
|
defp uptime_color(pct) when pct >= 95.0, do: "text-yellow-600 dark:text-yellow-400"
|
||||||
defp uptime_color(_pct), do: "text-red-600 dark:text-red-400"
|
defp uptime_color(_pct), do: "text-red-600 dark:text-red-400"
|
||||||
|
|
||||||
defp format_qoe(nil), do: "—"
|
|
||||||
defp format_qoe(score), do: :erlang.float_to_binary(score / 1, decimals: 1)
|
defp format_qoe(score), do: :erlang.float_to_binary(score / 1, decimals: 1)
|
||||||
|
|
||||||
defp format_short_datetime(datetime, timezone) do
|
defp format_short_datetime(datetime, timezone) do
|
||||||
|
|
|
||||||
|
|
@ -131,13 +131,10 @@ defmodule ToweropsWeb.DeviceLive.Form do
|
||||||
agent && agent.name
|
agent && agent.name
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add agent_token_id to the changeset data
|
# Create changeset with agent_token_id and validate to populate form fields
|
||||||
device_with_agent = Map.put(device, :agent_token_id, agent_token_id)
|
|
||||||
|
|
||||||
# Create changeset and validate to populate form.params for conditional rendering
|
|
||||||
changeset =
|
changeset =
|
||||||
device_with_agent
|
device
|
||||||
|> Devices.change_device(%{})
|
|> Devices.change_device(%{agent_token_id: agent_token_id})
|
||||||
|> Map.put(:action, :validate)
|
|> Map.put(:action, :validate)
|
||||||
|
|
||||||
# Get effective SNMP configuration and source
|
# Get effective SNMP configuration and source
|
||||||
|
|
@ -154,7 +151,7 @@ defmodule ToweropsWeb.DeviceLive.Form do
|
||||||
|
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, t("Edit Device"))
|
|> assign(:page_title, t("Edit Device"))
|
||||||
|> assign(:device, device_with_agent)
|
|> assign(:device, device)
|
||||||
|> assign(:form, to_form(changeset))
|
|> assign(:form, to_form(changeset))
|
||||||
|> assign(:agent_source, agent_source)
|
|> assign(:agent_source, agent_source)
|
||||||
|> assign(:effective_agent_name, effective_agent_name)
|
|> assign(:effective_agent_name, effective_agent_name)
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
||||||
alias ToweropsWeb.DeviceLive.Helpers.SensorClassifiers
|
alias ToweropsWeb.DeviceLive.Helpers.SensorClassifiers
|
||||||
alias ToweropsWeb.Live.Helpers.AccessControl
|
alias ToweropsWeb.Live.Helpers.AccessControl
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
# SNMP interface type to category mappings
|
# SNMP interface type to category mappings
|
||||||
@interface_type_categories %{
|
@interface_type_categories %{
|
||||||
6 => "Ethernet",
|
6 => "Ethernet",
|
||||||
|
|
@ -1158,8 +1156,6 @@ defmodule ToweropsWeb.DeviceLive.Show do
|
||||||
TimeHelpers.format_time_ago(datetime)
|
TimeHelpers.format_time_ago(datetime)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp format_mrr(nil), do: "$0"
|
|
||||||
|
|
||||||
defp format_mrr(%Decimal{} = d) do
|
defp format_mrr(%Decimal{} = d) do
|
||||||
"$#{d |> Decimal.round(2) |> Decimal.to_string(:normal)}"
|
"$#{d |> Decimal.round(2) |> Decimal.to_string(:normal)}"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -376,8 +376,6 @@ defmodule ToweropsWeb.Org.IntegrationsLive do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp next_sync_minutes(nil, _interval), do: nil
|
|
||||||
|
|
||||||
defp next_sync_minutes(last_synced_at, interval) do
|
defp next_sync_minutes(last_synced_at, interval) do
|
||||||
next_sync = DateTime.add(last_synced_at, interval * 60, :second)
|
next_sync = DateTime.add(last_synced_at, interval * 60, :second)
|
||||||
diff = DateTime.diff(next_sync, DateTime.utc_now(), :second)
|
diff = DateTime.diff(next_sync, DateTime.utc_now(), :second)
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ defmodule ToweropsWeb.Plugs.DetectEUUser do
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def call(conn, _opts) do
|
def call(conn, _opts) do
|
||||||
require Logger
|
|
||||||
|
|
||||||
# Fetch cookies to check for existing consent
|
# Fetch cookies to check for existing consent
|
||||||
conn = fetch_cookies(conn)
|
conn = fetch_cookies(conn)
|
||||||
requires_consent = detect_eu_user(conn)
|
requires_consent = detect_eu_user(conn)
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ defmodule ToweropsWeb.Plugs.FilterNoisyLogs do
|
||||||
"""
|
"""
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
def init(opts), do: opts
|
def init(opts), do: opts
|
||||||
|
|
||||||
def call(conn, _opts) do
|
def call(conn, _opts) do
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ defmodule ToweropsWeb.Plugs.RemoteIpLogger do
|
||||||
|
|
||||||
alias ToweropsWeb.RemoteIp
|
alias ToweropsWeb.RemoteIp
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
def init(opts), do: opts
|
def init(opts), do: opts
|
||||||
|
|
||||||
def call(conn, _opts) do
|
def call(conn, _opts) do
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue