lamina_dashboard/lib/lamina/dashboard/remote.ex

103 lines
2.5 KiB
Elixir

defmodule Lamina.Dashboard.Remote do
alias Lamina.Registry.ServerRegistry
alias Lamina.Server
@moduledoc """
Uses the Erlang `:rpc` module to interact with potentially-remote Lamina
servers.
"""
@doc """
List the running configuration servers on the remote node.
"""
@spec list_servers(node) :: [module]
def list_servers(node) do
:rpc.call(node, __MODULE__, :do_list_servers, [])
end
@doc """
List the configuration keys for a specific server on the remote node.
"""
@spec list_config_keys(node, module) :: [atom]
def list_config_keys(node, server) do
:rpc.call(node, __MODULE__, :do_list_config_keys, [server])
end
@doc """
List the configured providers for server on node.
"""
@spec list_providers(node, module) :: [{module, keyword}]
def list_providers(node, server) do
:rpc.call(node, __MODULE__, :do_list_providers, [server])
end
@doc """
Retrieve all configuration values from a remote server.
"""
@spec get_configs(node, module, map) :: [map]
def get_configs(node, server, params) do
:rpc.call(node, __MODULE__, :do_get_configs, [server, params])
end
@doc false
@spec do_list_servers :: [module]
def do_list_servers do
if function_exported?(ServerRegistry, :all_servers, 0) do
ServerRegistry.all_servers()
|> Enum.sort()
else
[]
end
end
@doc false
@spec do_list_config_keys(module) :: [atom]
def do_list_config_keys(server) do
apply(server, :__lamina__, [:config_keys])
end
@doc false
@spec do_list_providers(module) :: [{module, keyword}]
def do_list_providers(server) do
apply(server, :__lamina__, [:providers])
end
@doc false
@spec do_get_configs(module, map) :: {[map], non_neg_integer()}
def do_get_configs(server, params) do
sort_dir = if params.sort_dir == :asc, do: &<=/2, else: &>=/2
all_rows =
server
|> apply(:__lamina__, [:config_keys])
|> Enum.map(fn config_key ->
%{
name: config_key,
value: Server.get!(server, config_key)
}
end)
rows =
all_rows
|> maybe_filter_rows(params.search)
|> Enum.sort_by(&Map.get(&1, params.sort_by), sort_dir)
|> Enum.take(params.limit)
{rows, length(all_rows)}
end
defp maybe_filter_rows(rows, nil), do: rows
defp maybe_filter_rows(rows, search_term) do
Stream.filter(rows, fn row ->
row
|> Map.values()
|> Enum.any?(fn value ->
value
|> inspect()
|> String.downcase()
|> String.contains?(search_term)
end)
end)
end
end