Minimal Web handler and initial HAProxy wiring

This commit is contained in:
Timothée Floure 2022-01-24 16:53:04 +01:00
parent 410c409f71
commit fe572d64d7
Signed by: tfloure
GPG Key ID: 4502C902C00A1E12
5 changed files with 104 additions and 4 deletions

View File

@ -8,8 +8,7 @@ defmodule HAHandler.Application do
@impl true
def start(_type, _args) do
children = [
# Starts a worker by calling: HAHandler.Worker.start_link(arg)
# {HAHandler.Worker, arg}
{Plug.Cowboy, scheme: :http, plug: HAHandler.Web, options: [port: 4000]}
]
# See https://hexdocs.pm/elixir/Supervisor.html

View File

@ -0,0 +1,62 @@
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

22
lib/ha_handler/web.ex Normal file
View File

@ -0,0 +1,22 @@
defmodule HAHandler.Web do
import Plug.Conn
alias HAHandler.HAProxy
def init(opts) do
opts
end
def call(conn, _opts) do
{:ok, hostname} = :inet.gethostname()
stats = HAProxy.get_stats()
reply = "OK #{hostname}"
<> "\nPROXY: "
<> inspect(stats)
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, reply)
end
end

View File

@ -22,8 +22,10 @@ defmodule HAHandler.MixProject do
# Run "mix help deps" to learn about dependencies.
defp deps do
[
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
{:plug, "~> 1.12"},
{:plug_cowboy, "~> 2.5"},
{:procket, "~> 0.9"},
{:poison, "~> 5.0"}
]
end
end

15
mix.lock Normal file
View File

@ -0,0 +1,15 @@
%{
"afunix": {:git, "https://github.com/tonyrog/afunix.git", "d7baab77d741d49bce08de2aeb28c5f192ab13d8", []},
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
"plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"},
"plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"},
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
"poison": {:hex, :poison, "5.0.0", "d2b54589ab4157bbb82ec2050757779bfed724463a544b6e20d79855a9e43b24", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "11dc6117c501b80c62a7594f941d043982a1bd05a1184280c0d9166eb4d8d3fc"},
"procket": {:hex, :procket, "0.9.5", "ce91c00cb3f4d627fb3827f46ce68e6a969ea265df1afb349c300a07be4bb16c", [:rebar3], [], "hexpm", "1288bba5eb6f08ea5df3dda9e051bdac8f4b1e50adcca5cf4d726e825ad81bed"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"sweet_xml": {:hex, :sweet_xml, "0.7.2", "4729f997286811fabdd8288f8474e0840a76573051062f066c4b597e76f14f9f", [:mix], [], "hexpm", "6894e68a120f454534d99045ea3325f7740ea71260bc315f82e29731d570a6e8"},
"telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},
}