ha-handler/lib/ha_handler/ha_proxy.ex
2022-01-24 16:53:04 +01:00

62 lines
1.6 KiB
Elixir

defmodule HAHandler.HAProxy do
alias :procket, as: Socket
@haproxy_socket "/run/haproxy.sock"
def open_socket() do
pad = 8 * (Socket.unix_path_max() - byte_size(@haproxy_socket))
sockaddr =
Socket.sockaddr_common(1, byte_size(@haproxy_socket)) <> @haproxy_socket <> <<0::size(pad)>>
family = 1
{:ok, socket} = Socket.socket(family, 1, 0)
case Socket.connect(socket, sockaddr) do
:ok ->
{stdin, stdout} = {socket, socket}
port = Port.open({:fd, stdin, stdout}, [{:line, 10_000}, :binary])
Process.link(port)
{:ok, port}
{:error, err} ->
{:error, err}
end
end
defp read_from_socket(socket, acc \\ "") do
receive do
{_port, {:data, {:noeol, data}}} ->
read_from_socket(socket, acc <> data)
{_port, {:data, {:eol, data}}} ->
Poison.decode(acc <> data)
_ ->
{:error, :unexpected}
after 5000 ->
{:error, :timeout}
end
end
def get_stats() do
case open_socket() do
{:ok, socket} ->
send socket, {self(), {:command, "show stat json\n"}}
case read_from_socket(socket) do
{:ok, raw} ->
for entry <- raw do
attrs = entry
|> Enum.filter(fn m -> get_in(m, ["field", "name"]) == "pxname" end)
|> Enum.at(0)
%{type: attrs |> Map.get("objType"), name: get_in(attrs, ["value", "value"])}
end
{:error, err} ->
{:error, err}
end
{:error, err} -> {:error, err}
end
end
end