proxMon/agent/lib/proxmox_agent/config.ex

77 lines
1.9 KiB
Elixir

defmodule ProxmoxAgent.Config do
@moduledoc "Loads and validates the TOML agent config."
defstruct [
:server_url,
:token,
:host_id,
fast_seconds: 30,
medium_seconds: 300,
slow_seconds: 1800
]
@type t :: %__MODULE__{
server_url: String.t(),
token: String.t(),
host_id: String.t(),
fast_seconds: pos_integer(),
medium_seconds: pos_integer(),
slow_seconds: pos_integer()
}
@required ~w(server_url token)a
@spec load(Path.t()) ::
{:ok, t()}
| {:error, {:file_read, term()} | {:parse, term()} | {:missing_key, atom()}}
def load(path) do
with {:ok, body} <- read_file(path),
{:ok, parsed} <- parse_toml(body),
:ok <- validate_required(parsed) do
{:ok, build(parsed)}
end
end
defp read_file(path) do
case File.read(path) do
{:ok, body} -> {:ok, body}
{:error, reason} -> {:error, {:file_read, reason}}
end
end
defp parse_toml(body) do
case Toml.decode(body) do
{:ok, map} -> {:ok, map}
{:error, reason} -> {:error, {:parse, reason}}
end
end
defp validate_required(map) do
Enum.find_value(@required, :ok, fn key ->
case Map.get(map, Atom.to_string(key)) do
v when is_binary(v) and v != "" -> nil
_ -> {:error, {:missing_key, key}}
end
end)
end
defp build(map) do
intervals = Map.get(map, "intervals", %{})
%__MODULE__{
server_url: map["server_url"],
token: map["token"],
host_id: map["host_id"] || hostname(),
fast_seconds: Map.get(intervals, "fast_seconds", 30),
medium_seconds: Map.get(intervals, "medium_seconds", 300),
slow_seconds: Map.get(intervals, "slow_seconds", 1800)
}
end
defp hostname do
case :inet.gethostname() do
{:ok, name} -> List.to_string(name)
_ -> "unknown-host"
end
end
end