113 lines
2.6 KiB
Elixir
113 lines
2.6 KiB
Elixir
defmodule Towerops.Profiles do
|
|
@moduledoc """
|
|
Context for managing device profiles.
|
|
Profiles are stored in the database and can be updated without deployment.
|
|
"""
|
|
|
|
import Ecto.Query
|
|
|
|
alias Towerops.Profiles.DeviceOid
|
|
alias Towerops.Profiles.DeviceProfile
|
|
alias Towerops.Profiles.SensorOid
|
|
alias Towerops.Repo
|
|
|
|
@doc """
|
|
Lists all enabled profiles ordered by priority.
|
|
"""
|
|
def list_profiles do
|
|
DeviceProfile
|
|
|> where([p], p.enabled == true)
|
|
|> order_by([p], asc: p.priority)
|
|
|> Repo.all()
|
|
end
|
|
|
|
@doc """
|
|
Gets a profile by name with associations loaded.
|
|
"""
|
|
def get_profile(name) do
|
|
DeviceProfile
|
|
|> where([p], p.name == ^name)
|
|
|> preload([:device_oids, :sensor_oids])
|
|
|> Repo.one()
|
|
end
|
|
|
|
@doc """
|
|
Matches a profile based on sysDescr and sysObjectID.
|
|
Returns the first matching profile based on priority.
|
|
"""
|
|
def match_profile(system_info) do
|
|
sys_descr = Map.get(system_info, :sys_descr, "")
|
|
sys_object_id = Map.get(system_info, :sys_object_id, "")
|
|
|
|
profiles = list_profiles()
|
|
|
|
Enum.find(profiles, fn profile ->
|
|
matches_detection_pattern?(profile, sys_descr) ||
|
|
matches_detection_oid?(profile, sys_object_id)
|
|
end)
|
|
end
|
|
|
|
@doc """
|
|
Creates a new profile.
|
|
"""
|
|
def create_profile(attrs) do
|
|
%DeviceProfile{}
|
|
|> DeviceProfile.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
@doc """
|
|
Updates a profile.
|
|
"""
|
|
def update_profile(%DeviceProfile{} = profile, attrs) do
|
|
profile
|
|
|> DeviceProfile.changeset(attrs)
|
|
|> Repo.update()
|
|
end
|
|
|
|
@doc """
|
|
Deletes a profile.
|
|
"""
|
|
def delete_profile(%DeviceProfile{} = profile) do
|
|
Repo.delete(profile)
|
|
end
|
|
|
|
@doc """
|
|
Adds a device OID to a profile.
|
|
"""
|
|
def add_device_oid(profile_id, field, mib_name) do
|
|
%DeviceOid{}
|
|
|> DeviceOid.changeset(%{
|
|
profile_id: profile_id,
|
|
field: field,
|
|
mib_name: mib_name
|
|
})
|
|
|> Repo.insert()
|
|
end
|
|
|
|
@doc """
|
|
Adds a sensor OID to a profile.
|
|
"""
|
|
def add_sensor_oid(profile_id, attrs) do
|
|
%SensorOid{}
|
|
|> SensorOid.changeset(Map.put(attrs, :profile_id, profile_id))
|
|
|> Repo.insert()
|
|
end
|
|
|
|
# Private functions
|
|
|
|
defp matches_detection_pattern?(%{detection_pattern: nil}, _sys_descr), do: false
|
|
|
|
defp matches_detection_pattern?(%{detection_pattern: pattern}, sys_descr) do
|
|
case Regex.compile(pattern) do
|
|
{:ok, regex} -> Regex.match?(regex, sys_descr)
|
|
{:error, _} -> false
|
|
end
|
|
end
|
|
|
|
defp matches_detection_oid?(%{detection_oid: nil}, _sys_object_id), do: false
|
|
|
|
defp matches_detection_oid?(%{detection_oid: pattern}, sys_object_id) do
|
|
String.starts_with?(sys_object_id, pattern)
|
|
end
|
|
end
|