%%%-------------------------------------------------------------------
%% @doc Cowboy handler for dashboard peer start/stop actions.
%%%-------------------------------------------------------------------
-module(vpn_peer_action_http).
-export([init/2]).
init(Req0, State) ->
case cowboy_req:method(Req0) of
<<"POST">> ->
PeerIdBin = cowboy_req:binding(id, Req0),
Action = maps:get(action, State),
run_action(Action, PeerIdBin),
redirect(Req0, State);
_Other ->
Req = cowboy_req:reply(
405,
#{<<"allow">> => <<"POST">>},
Req0),
{ok, Req, State}
end.
run_action(Action, PeerIdBin) ->
Result =
case find_peer_id(PeerIdBin) of
{ok, PeerId} ->
apply_action(Action, PeerId);
{error, not_found} ->
{error, not_found}
end,
log_result(Action, PeerIdBin, Result),
ok.
apply_action(start, PeerId) ->
vpn_manager:start_peer(PeerId);
apply_action(stop, PeerId) ->
vpn_manager:stop_peer(PeerId).
find_peer_id(PeerIdBin) ->
case [PeerId || PeerId <- vpn_manager:list_peers(),
peer_id_binary(PeerId) =:= PeerIdBin] of
[PeerId | _] ->
{ok, PeerId};
[] ->
{error, not_found}
end.
peer_id_binary(PeerId) when is_binary(PeerId) ->
PeerId;
peer_id_binary(PeerId) when is_atom(PeerId) ->
atom_to_binary(PeerId, utf8).
log_result(_Action, _PeerIdBin, ok) ->
ok;
log_result(_Action, _PeerIdBin, {ok, _Pid}) ->
ok;
log_result(Action, PeerIdBin, {error, Reason}) ->
logger:warning("vpn dashboard peer action failed action=~p peer=~s reason=~p",
[Action, PeerIdBin, Reason]).
redirect(Req0, State) ->
Req = cowboy_req:reply(
303,
#{<<"location">> => <<"/admin">>},
Req0),
{ok, Req, State}.