86 lines
2.2 KiB
Elixir
86 lines
2.2 KiB
Elixir
defmodule ProxmoxAgent.Config do
|
|
@moduledoc "Loads and validates the TOML agent config."
|
|
|
|
defstruct [
|
|
:server_url,
|
|
:token,
|
|
:host_id,
|
|
:dump_dir,
|
|
fast_seconds: 30,
|
|
medium_seconds: 300,
|
|
slow_seconds: 1800
|
|
]
|
|
|
|
@type t :: %__MODULE__{
|
|
server_url: String.t(),
|
|
token: String.t(),
|
|
host_id: String.t(),
|
|
dump_dir: String.t() | nil,
|
|
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", %{})
|
|
debug = Map.get(map, "debug", %{})
|
|
|
|
%__MODULE__{
|
|
server_url: map["server_url"],
|
|
token: map["token"],
|
|
host_id: map["host_id"] || hostname(),
|
|
dump_dir: normalize_dump_dir(Map.get(debug, "dump_dir")),
|
|
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 normalize_dump_dir(nil), do: nil
|
|
defp normalize_dump_dir(""), do: nil
|
|
defp normalize_dump_dir(s) when is_binary(s), do: s
|
|
defp normalize_dump_dir(_), do: nil
|
|
|
|
defp hostname do
|
|
case :inet.gethostname() do
|
|
{:ok, name} -> List.to_string(name)
|
|
_ -> "unknown-host"
|
|
end
|
|
end
|
|
end
|